aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/API/CMakeLists.txt2
-rw-r--r--source/API/Makefile18
-rw-r--r--source/API/SBAddress.cpp3
-rw-r--r--source/API/SBBlock.cpp8
-rw-r--r--source/API/SBBreakpoint.cpp66
-rw-r--r--source/API/SBBreakpointLocation.cpp42
-rw-r--r--source/API/SBBroadcaster.cpp6
-rw-r--r--source/API/SBCommandInterpreter.cpp10
-rw-r--r--source/API/SBCommandReturnObject.cpp18
-rw-r--r--source/API/SBDebugger.cpp18
-rw-r--r--source/API/SBExpressionOptions.cpp24
-rw-r--r--source/API/SBFileSpec.cpp6
-rw-r--r--source/API/SBFrame.cpp230
-rw-r--r--source/API/SBFunction.cpp4
-rw-r--r--source/API/SBHostOS.cpp16
-rw-r--r--source/API/SBInstruction.cpp180
-rw-r--r--source/API/SBInstructionList.cpp2
-rw-r--r--source/API/SBListener.cpp129
-rw-r--r--source/API/SBMemoryRegionInfo.cpp126
-rw-r--r--source/API/SBMemoryRegionInfoList.cpp162
-rw-r--r--source/API/SBModule.cpp3
-rw-r--r--source/API/SBProcess.cpp155
-rw-r--r--source/API/SBStringList.cpp10
-rw-r--r--source/API/SBSymbol.cpp5
-rw-r--r--source/API/SBTarget.cpp226
-rw-r--r--source/API/SBThread.cpp227
-rw-r--r--source/API/SBValue.cpp47
-rw-r--r--source/API/SBWatchpoint.cpp22
-rw-r--r--source/API/SystemInitializerFull.cpp96
-rw-r--r--source/API/liblldb.exports1
-rw-r--r--source/Breakpoint/Breakpoint.cpp4
-rw-r--r--source/Breakpoint/BreakpointList.cpp37
-rw-r--r--source/Breakpoint/BreakpointLocation.cpp87
-rw-r--r--source/Breakpoint/BreakpointLocationCollection.cpp10
-rw-r--r--source/Breakpoint/BreakpointLocationList.cpp45
-rw-r--r--source/Breakpoint/BreakpointResolver.cpp29
-rw-r--r--source/Breakpoint/BreakpointResolverAddress.cpp2
-rw-r--r--source/Breakpoint/BreakpointResolverFileLine.cpp4
-rw-r--r--source/Breakpoint/BreakpointResolverFileRegex.cpp38
-rw-r--r--source/Breakpoint/BreakpointResolverName.cpp94
-rw-r--r--source/Breakpoint/BreakpointSite.cpp40
-rw-r--r--source/Breakpoint/BreakpointSiteList.cpp28
-rw-r--r--source/Breakpoint/Makefile14
-rw-r--r--source/Breakpoint/WatchpointList.cpp33
-rw-r--r--source/Commands/CommandCompletions.cpp263
-rw-r--r--source/Commands/CommandObjectApropos.cpp51
-rw-r--r--source/Commands/CommandObjectArgs.cpp20
-rw-r--r--source/Commands/CommandObjectBreakpoint.cpp485
-rw-r--r--source/Commands/CommandObjectBreakpointCommand.cpp124
-rw-r--r--source/Commands/CommandObjectBugreport.cpp8
-rw-r--r--source/Commands/CommandObjectCommands.cpp755
-rw-r--r--source/Commands/CommandObjectDisassemble.cpp97
-rw-r--r--source/Commands/CommandObjectDisassemble.h7
-rw-r--r--source/Commands/CommandObjectExpression.cpp234
-rw-r--r--source/Commands/CommandObjectExpression.h17
-rw-r--r--source/Commands/CommandObjectFrame.cpp169
-rw-r--r--source/Commands/CommandObjectHelp.cpp108
-rw-r--r--source/Commands/CommandObjectHelp.h8
-rw-r--r--source/Commands/CommandObjectLanguage.cpp14
-rw-r--r--source/Commands/CommandObjectLanguage.h3
-rw-r--r--source/Commands/CommandObjectLog.cpp99
-rw-r--r--source/Commands/CommandObjectMemory.cpp336
-rw-r--r--source/Commands/CommandObjectMultiword.cpp108
-rw-r--r--source/Commands/CommandObjectPlatform.cpp562
-rw-r--r--source/Commands/CommandObjectPlugin.cpp53
-rw-r--r--source/Commands/CommandObjectProcess.cpp344
-rw-r--r--source/Commands/CommandObjectQuit.cpp4
-rw-r--r--source/Commands/CommandObjectRegister.cpp92
-rw-r--r--source/Commands/CommandObjectSettings.cpp306
-rw-r--r--source/Commands/CommandObjectSource.cpp132
-rw-r--r--source/Commands/CommandObjectSyntax.cpp27
-rw-r--r--source/Commands/CommandObjectTarget.cpp925
-rw-r--r--source/Commands/CommandObjectThread.cpp802
-rw-r--r--source/Commands/CommandObjectType.cpp793
-rw-r--r--source/Commands/CommandObjectVersion.cpp4
-rw-r--r--source/Commands/CommandObjectWatchpoint.cpp261
-rw-r--r--source/Commands/CommandObjectWatchpointCommand.cpp121
-rw-r--r--source/Commands/Makefile16
-rw-r--r--source/Core/Address.cpp159
-rw-r--r--source/Core/AddressRange.cpp2
-rw-r--r--source/Core/AddressResolverName.cpp80
-rw-r--r--source/Core/ArchSpec.cpp205
-rw-r--r--source/Core/Broadcaster.cpp389
-rw-r--r--source/Core/Communication.cpp139
-rw-r--r--source/Core/ConnectionSharedMemory.cpp39
-rw-r--r--source/Core/ConstString.cpp70
-rw-r--r--source/Core/CxaDemangle.cpp3
-rw-r--r--source/Core/DataBufferHeap.cpp22
-rw-r--r--source/Core/DataBufferMemoryMap.cpp66
-rw-r--r--source/Core/DataEncoder.cpp58
-rw-r--r--source/Core/DataExtractor.cpp230
-rw-r--r--source/Core/Debugger.cpp459
-rw-r--r--source/Core/Disassembler.cpp333
-rw-r--r--source/Core/DynamicLoader.cpp40
-rw-r--r--source/Core/EmulateInstruction.cpp108
-rw-r--r--source/Core/Error.cpp65
-rw-r--r--source/Core/Event.cpp104
-rw-r--r--source/Core/FastDemangle.cpp11
-rw-r--r--source/Core/FileSpecList.cpp42
-rw-r--r--source/Core/FormatEntity.cpp114
-rw-r--r--source/Core/IOHandler.cpp368
-rw-r--r--source/Core/Listener.cpp378
-rw-r--r--source/Core/Log.cpp55
-rw-r--r--source/Core/Logging.cpp37
-rw-r--r--source/Core/Makefile14
-rw-r--r--source/Core/Mangled.cpp23
-rw-r--r--source/Core/Module.cpp691
-rw-r--r--source/Core/ModuleList.cpp299
-rw-r--r--source/Core/Opcode.cpp20
-rw-r--r--source/Core/PluginManager.cpp806
-rw-r--r--source/Core/RegisterValue.cpp192
-rw-r--r--source/Core/RegularExpression.cpp33
-rw-r--r--source/Core/Scalar.cpp1152
-rw-r--r--source/Core/SearchFilter.cpp181
-rw-r--r--source/Core/Section.cpp145
-rw-r--r--source/Core/StreamCallback.cpp11
-rw-r--r--source/Core/Timer.cpp67
-rw-r--r--source/Core/UserSettingsController.cpp24
-rw-r--r--source/Core/Value.cpp15
-rw-r--r--source/Core/ValueObject.cpp71
-rw-r--r--source/Core/ValueObjectConstResult.cpp7
-rw-r--r--source/Core/ValueObjectConstResultCast.cpp5
-rw-r--r--source/Core/ValueObjectConstResultChild.cpp10
-rw-r--r--source/Core/ValueObjectConstResultImpl.cpp10
-rw-r--r--source/Core/ValueObjectDynamicValue.cpp16
-rw-r--r--source/Core/ValueObjectSyntheticFilter.cpp111
-rw-r--r--source/Core/ValueObjectVariable.cpp10
-rw-r--r--source/DataFormatters/DumpValueObjectOptions.cpp8
-rw-r--r--source/DataFormatters/FormatCache.cpp30
-rw-r--r--source/DataFormatters/FormatManager.cpp36
-rw-r--r--source/DataFormatters/FormattersHelpers.cpp172
-rw-r--r--source/DataFormatters/Makefile14
-rw-r--r--source/DataFormatters/StringPrinter.cpp2
-rw-r--r--source/DataFormatters/TypeCategory.cpp27
-rw-r--r--source/DataFormatters/TypeCategoryMap.cpp65
-rw-r--r--source/DataFormatters/TypeFormat.cpp4
-rw-r--r--source/DataFormatters/TypeSummary.cpp21
-rw-r--r--source/DataFormatters/TypeSynthetic.cpp9
-rw-r--r--source/DataFormatters/ValueObjectPrinter.cpp50
-rw-r--r--source/Expression/CMakeLists.txt1
-rw-r--r--source/Expression/DWARFExpression.cpp165
-rw-r--r--source/Expression/DiagnosticManager.cpp91
-rw-r--r--source/Expression/ExpressionSourceCode.cpp113
-rw-r--r--source/Expression/ExpressionVariable.cpp54
-rw-r--r--source/Expression/FunctionCaller.cpp89
-rw-r--r--source/Expression/IRDynamicChecks.cpp68
-rw-r--r--source/Expression/IRExecutionUnit.cpp655
-rw-r--r--source/Expression/IRInterpreter.cpp242
-rw-r--r--source/Expression/IRMemoryMap.cpp127
-rw-r--r--source/Expression/LLVMUserExpression.cpp90
-rw-r--r--source/Expression/Makefile14
-rw-r--r--source/Expression/Materializer.cpp516
-rw-r--r--source/Expression/REPL.cpp3
-rw-r--r--source/Expression/UserExpression.cpp132
-rw-r--r--source/Expression/UtilityFunction.cpp34
-rw-r--r--source/Host/Makefile65
-rw-r--r--source/Host/android/LibcGlue.cpp5
-rw-r--r--source/Host/common/Editline.cpp246
-rw-r--r--source/Host/common/File.cpp81
-rw-r--r--source/Host/common/FileSpec.cpp358
-rw-r--r--source/Host/common/Host.cpp71
-rw-r--r--source/Host/common/HostInfoBase.cpp34
-rw-r--r--source/Host/common/HostProcess.cpp4
-rw-r--r--source/Host/common/MonitoringProcessLauncher.cpp4
-rw-r--r--source/Host/common/NativeBreakpointList.cpp13
-rw-r--r--source/Host/common/NativeProcessProtocol.cpp56
-rw-r--r--source/Host/common/OptionParser.cpp6
-rw-r--r--source/Host/common/Socket.cpp2
-rw-r--r--source/Host/common/SocketAddress.cpp6
-rw-r--r--source/Host/common/SoftwareBreakpoint.cpp1
-rw-r--r--source/Host/common/TCPSocket.cpp3
-rw-r--r--source/Host/common/UDPSocket.cpp8
-rw-r--r--source/Host/linux/Host.cpp20
-rw-r--r--source/Host/linux/HostInfoLinux.cpp2
-rw-r--r--source/Host/macosx/Host.mm43
-rw-r--r--source/Host/macosx/HostInfoMacOSX.mm6
-rw-r--r--source/Host/macosx/ThisThread.cpp18
-rw-r--r--source/Host/netbsd/Makefile14
-rw-r--r--source/Host/posix/ConnectionFileDescriptorPosix.cpp57
-rw-r--r--source/Host/posix/DomainSocket.cpp2
-rw-r--r--source/Host/posix/FileSystem.cpp46
-rw-r--r--source/Host/posix/HostInfoPosix.cpp11
-rw-r--r--source/Host/posix/HostProcessPosix.cpp4
-rw-r--r--source/Host/posix/HostThreadPosix.cpp20
-rw-r--r--source/Host/windows/ConnectionGenericFileWindows.cpp11
-rw-r--r--source/Host/windows/FileSystem.cpp120
-rw-r--r--source/Host/windows/Host.cpp48
-rw-r--r--source/Host/windows/HostInfoWindows.cpp52
-rw-r--r--source/Host/windows/HostProcessWindows.cpp21
-rw-r--r--source/Host/windows/PipeWindows.cpp10
-rw-r--r--source/Host/windows/ProcessLauncherWindows.cpp49
-rw-r--r--source/Host/windows/Windows.cpp157
-rw-r--r--source/Initialization/Makefile14
-rw-r--r--source/Initialization/SystemInitializerCommon.cpp67
-rw-r--r--source/Initialization/SystemLifetimeManager.cpp9
-rw-r--r--source/Interpreter/Args.cpp100
-rw-r--r--source/Interpreter/CMakeLists.txt1
-rw-r--r--source/Interpreter/CommandAlias.cpp307
-rw-r--r--source/Interpreter/CommandHistory.cpp21
-rw-r--r--source/Interpreter/CommandInterpreter.cpp660
-rw-r--r--source/Interpreter/CommandObject.cpp265
-rw-r--r--source/Interpreter/CommandObjectScript.cpp9
-rw-r--r--source/Interpreter/Makefile51
-rw-r--r--source/Interpreter/OptionGroupValueObjectDisplay.cpp12
-rw-r--r--source/Interpreter/OptionValueArray.cpp1
-rw-r--r--source/Interpreter/OptionValueFileSpecLIst.cpp1
-rw-r--r--source/Interpreter/OptionValuePathMappings.cpp81
-rw-r--r--source/Interpreter/OptionValueProperties.cpp19
-rw-r--r--source/Interpreter/Options.cpp315
-rw-r--r--source/Makefile37
-rw-r--r--source/Plugins/ABI/CMakeLists.txt1
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp264
-rw-r--r--source/Plugins/ABI/MacOSX-arm/Makefile14
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp316
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/Makefile14
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp124
-rw-r--r--source/Plugins/ABI/MacOSX-i386/Makefile14
-rw-r--r--source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp472
-rw-r--r--source/Plugins/ABI/SysV-arm/ABISysV_arm.h3
-rw-r--r--source/Plugins/ABI/SysV-arm/Makefile14
-rw-r--r--source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp318
-rw-r--r--source/Plugins/ABI/SysV-arm64/Makefile14
-rw-r--r--source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp193
-rw-r--r--source/Plugins/ABI/SysV-hexagon/Makefile14
-rw-r--r--source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp49
-rw-r--r--source/Plugins/ABI/SysV-i386/Makefile14
-rw-r--r--source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp226
-rw-r--r--source/Plugins/ABI/SysV-mips/ABISysV_mips.h3
-rw-r--r--source/Plugins/ABI/SysV-mips/Makefile14
-rw-r--r--source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp212
-rw-r--r--source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h3
-rw-r--r--source/Plugins/ABI/SysV-mips64/Makefile14
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp142
-rw-r--r--source/Plugins/ABI/SysV-ppc/Makefile14
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp142
-rw-r--r--source/Plugins/ABI/SysV-ppc64/Makefile14
-rw-r--r--source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp807
-rw-r--r--source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h120
-rw-r--r--source/Plugins/ABI/SysV-s390x/CMakeLists.txt3
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp209
-rw-r--r--source/Plugins/ABI/SysV-x86_64/Makefile14
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp542
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h8
-rw-r--r--source/Plugins/Disassembler/llvm/Makefile14
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp105
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h12
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/Makefile14
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp36
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h10
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/Makefile14
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt1
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp1143
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h293
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp1018
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h226
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/Makefile14
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp15
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h2
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/Makefile14
-rw-r--r--source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp4
-rw-r--r--source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h1
-rw-r--r--source/Plugins/DynamicLoader/Static/Makefile14
-rw-r--r--source/Plugins/DynamicLoader/Windows-DYLD/Makefile14
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTDumper.cpp3
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp122
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h51
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp59
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangASTSource.h2
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h60
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp496
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h22
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h9
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp620
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h44
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp20
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h16
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp3
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp24
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h15
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp257
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.h42
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp48
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h8
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRForTarget.cpp711
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRForTarget.h168
-rw-r--r--source/Plugins/ExpressionParser/Clang/Makefile14
-rw-r--r--source/Plugins/ExpressionParser/Go/GoAST.h1
-rw-r--r--source/Plugins/ExpressionParser/Go/GoUserExpression.cpp29
-rw-r--r--source/Plugins/ExpressionParser/Go/GoUserExpression.h50
-rw-r--r--source/Plugins/ExpressionParser/Go/Makefile14
-rw-r--r--source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp81
-rw-r--r--source/Plugins/Instruction/ARM/EmulateInstructionARM.h4
-rw-r--r--source/Plugins/Instruction/ARM/EmulationStateARM.cpp116
-rw-r--r--source/Plugins/Instruction/ARM/EmulationStateARM.h10
-rw-r--r--source/Plugins/Instruction/ARM/Makefile14
-rw-r--r--source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp2
-rw-r--r--source/Plugins/Instruction/ARM64/Makefile14
-rw-r--r--source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp46
-rw-r--r--source/Plugins/Instruction/MIPS/Makefile14
-rw-r--r--source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp45
-rw-r--r--source/Plugins/Instruction/MIPS64/Makefile14
-rw-r--r--source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp33
-rw-r--r--source/Plugins/InstrumentationRuntime/AddressSanitizer/Makefile14
-rw-r--r--source/Plugins/InstrumentationRuntime/CMakeLists.txt1
-rw-r--r--source/Plugins/InstrumentationRuntime/ThreadSanitizer/CMakeLists.txt3
-rw-r--r--source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp887
-rw-r--r--source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h119
-rw-r--r--source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp99
-rw-r--r--source/Plugins/JITLoader/GDB/Makefile14
-rw-r--r--source/Plugins/Language/CMakeLists.txt1
-rw-r--r--source/Plugins/Language/CPlusPlus/BlockPointer.cpp225
-rw-r--r--source/Plugins/Language/CPlusPlus/BlockPointer.h27
-rw-r--r--source/Plugins/Language/CPlusPlus/CMakeLists.txt2
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp162
-rw-r--r--source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp22
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.cpp76
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp121
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxAtomic.h29
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp27
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxList.cpp46
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxMap.cpp60
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp31
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxVector.cpp30
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcpp.cpp191
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcpp.h7
-rw-r--r--source/Plugins/Language/CPlusPlus/Makefile14
-rw-r--r--source/Plugins/Language/Go/Makefile14
-rw-r--r--source/Plugins/Language/Java/CMakeLists.txt4
-rw-r--r--source/Plugins/Language/Java/JavaFormatterFunctions.cpp186
-rw-r--r--source/Plugins/Language/Java/JavaFormatterFunctions.h36
-rw-r--r--source/Plugins/Language/Java/JavaLanguage.cpp112
-rw-r--r--source/Plugins/Language/Java/JavaLanguage.h64
-rw-r--r--source/Plugins/Language/ObjC/CF.cpp60
-rw-r--r--source/Plugins/Language/ObjC/Cocoa.cpp164
-rw-r--r--source/Plugins/Language/ObjC/Cocoa.h14
-rw-r--r--source/Plugins/Language/ObjC/Makefile14
-rw-r--r--source/Plugins/Language/ObjC/NSArray.cpp262
-rw-r--r--source/Plugins/Language/ObjC/NSDictionary.cpp302
-rw-r--r--source/Plugins/Language/ObjC/NSError.cpp63
-rw-r--r--source/Plugins/Language/ObjC/NSException.cpp8
-rw-r--r--source/Plugins/Language/ObjC/NSIndexPath.cpp207
-rw-r--r--source/Plugins/Language/ObjC/NSSet.cpp150
-rw-r--r--source/Plugins/Language/ObjC/ObjCLanguage.cpp22
-rw-r--r--source/Plugins/Language/ObjC/ObjCLanguage.h3
-rw-r--r--source/Plugins/Language/ObjCPlusPlus/Makefile14
-rw-r--r--source/Plugins/LanguageRuntime/CMakeLists.txt1
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp374
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h29
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/Makefile14
-rw-r--r--source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp3
-rw-r--r--source/Plugins/LanguageRuntime/Go/Makefile14
-rw-r--r--source/Plugins/LanguageRuntime/Java/CMakeLists.txt3
-rw-r--r--source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp176
-rw-r--r--source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h90
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp10
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h5
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp50
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp31
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp1
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp576
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h44
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp58
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h6
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp9
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp19
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/Makefile14
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/Makefile14
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp2601
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h291
-rw-r--r--source/Plugins/Makefile67
-rw-r--r--source/Plugins/MemoryHistory/asan/Makefile14
-rw-r--r--source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp109
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/Makefile14
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp12
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h6
-rw-r--r--source/Plugins/ObjectContainer/Universal-Mach-O/Makefile14
-rw-r--r--source/Plugins/ObjectFile/ELF/ELFHeader.cpp3
-rw-r--r--source/Plugins/ObjectFile/ELF/Makefile14
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp458
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.h26
-rw-r--r--source/Plugins/ObjectFile/JIT/Makefile14
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp6
-rw-r--r--source/Plugins/ObjectFile/Mach-O/Makefile14
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp109
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h5
-rw-r--r--source/Plugins/ObjectFile/PECOFF/Makefile14
-rw-r--r--source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp35
-rw-r--r--source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h5
-rw-r--r--source/Plugins/OperatingSystem/Go/Makefile14
-rw-r--r--source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp19
-rw-r--r--source/Plugins/OperatingSystem/Python/Makefile14
-rw-r--r--source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp16
-rw-r--r--source/Plugins/Platform/Android/AdbClient.cpp414
-rw-r--r--source/Plugins/Platform/Android/AdbClient.h82
-rw-r--r--source/Plugins/Platform/Android/Makefile14
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.cpp57
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.h6
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp17
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h3
-rw-r--r--source/Plugins/Platform/FreeBSD/Makefile14
-rw-r--r--source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp77
-rw-r--r--source/Plugins/Platform/Kalimba/Makefile14
-rw-r--r--source/Plugins/Platform/Linux/Makefile14
-rw-r--r--source/Plugins/Platform/Linux/PlatformLinux.cpp99
-rw-r--r--source/Plugins/Platform/Linux/PlatformLinux.h4
-rw-r--r--source/Plugins/Platform/MacOSX/Makefile34
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp2
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp2
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp2
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwin.cpp57
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwin.h3
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp19
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp156
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp155
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp78
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp2
-rw-r--r--source/Plugins/Platform/Makefile36
-rw-r--r--source/Plugins/Platform/NetBSD/Makefile14
-rw-r--r--source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp28
-rw-r--r--source/Plugins/Platform/NetBSD/PlatformNetBSD.h4
-rw-r--r--source/Plugins/Platform/POSIX/Makefile14
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.cpp53
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.h7
-rw-r--r--source/Plugins/Platform/Windows/Makefile14
-rw-r--r--source/Plugins/Platform/Windows/PlatformWindows.cpp38
-rw-r--r--source/Plugins/Platform/Windows/PlatformWindows.h4
-rw-r--r--source/Plugins/Platform/gdb-server/Makefile14
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp22
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h3
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.cpp38
-rw-r--r--source/Plugins/Process/FreeBSD/Makefile17
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp28
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.h9
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp17
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.h8
-rw-r--r--source/Plugins/Process/Linux/CMakeLists.txt2
-rw-r--r--source/Plugins/Process/Linux/Makefile17
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.cpp693
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.h69
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp43
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h5
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp44
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h5
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp6
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp716
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h141
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.cpp143
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.h28
-rw-r--r--source/Plugins/Process/Linux/SingleStepCheck.cpp177
-rw-r--r--source/Plugins/Process/Linux/SingleStepCheck.h41
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp45
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h6
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/Makefile14
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp24
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h4
-rw-r--r--source/Plugins/Process/POSIX/Makefile32
-rw-r--r--source/Plugins/Process/Utility/CMakeLists.txt3
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.cpp40
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.h5
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.cpp6
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.h1
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.cpp63
-rw-r--r--source/Plugins/Process/Utility/Makefile14
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp2
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm.h9
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.cpp97
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp98
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_s390x.h42
-rw-r--r--source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp357
-rw-r--r--source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h35
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp265
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h103
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_s390x.h93
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_mips.h15
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_mips64.h11
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_s390x.h132
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.cpp2
-rw-r--r--source/Plugins/Process/Utility/lldb-s390x-register-enums.h94
-rw-r--r--source/Plugins/Process/Windows/Common/NtStructures.h32
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.cpp4
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.h2
-rw-r--r--source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp6
-rw-r--r--source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp59
-rw-r--r--source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h3
-rw-r--r--source/Plugins/Process/Windows/Live/DebuggerThread.cpp13
-rw-r--r--source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp116
-rw-r--r--source/Plugins/Process/Windows/Live/ProcessWindowsLive.h4
-rw-r--r--source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp638
-rw-r--r--source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h46
-rw-r--r--source/Plugins/Process/elf-core/CMakeLists.txt1
-rw-r--r--source/Plugins/Process/elf-core/Makefile14
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.cpp92
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.h14
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp115
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h65
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.cpp10
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.h2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp17
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp224
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h5
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h1
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp47
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h9
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp65
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h11
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp15
-rw-r--r--source/Plugins/Process/gdb-remote/Makefile14
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp474
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h23
-rw-r--r--source/Plugins/Process/mach-core/Makefile14
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.cpp183
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.h13
-rw-r--r--source/Plugins/ScriptInterpreter/None/Makefile14
-rw-r--r--source/Plugins/ScriptInterpreter/Python/Makefile14
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp138
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h37
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp205
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h5
-rw-r--r--source/Plugins/SymbolFile/CMakeLists.txt1
-rw-r--r--source/Plugins/SymbolFile/DWARF/CMakeLists.txt1
-rw-r--r--source/Plugins/SymbolFile/DWARF/DIERef.cpp55
-rw-r--r--source/Plugins/SymbolFile/DWARF/DIERef.h20
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParser.h12
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp733
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h62
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp42
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp555
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h90
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp80
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp75
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.h18
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp11
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h3
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp75
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h7
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp22
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h13
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h16
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp8
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.h1
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp15
-rw-r--r--source/Plugins/SymbolFile/DWARF/Makefile14
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp616
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h45
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp51
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h10
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp8
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h9
-rw-r--r--source/Plugins/SymbolFile/PDB/CMakeLists.txt7
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.cpp237
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.h58
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp733
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.h204
-rw-r--r--source/Plugins/SymbolFile/Symtab/Makefile14
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp3
-rw-r--r--source/Plugins/SymbolVendor/ELF/Makefile14
-rw-r--r--source/Plugins/SymbolVendor/MacOSX/Makefile14
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp73
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h8
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp77
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h8
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp75
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h8
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp75
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h8
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/Makefile14
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp50
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h6
-rw-r--r--source/Plugins/UnwindAssembly/InstEmulation/Makefile14
-rw-r--r--source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp128
-rw-r--r--source/Plugins/UnwindAssembly/x86/Makefile14
-rw-r--r--source/Symbol/ArmUnwindInfo.cpp2
-rw-r--r--source/Symbol/Block.cpp37
-rw-r--r--source/Symbol/CMakeLists.txt2
-rw-r--r--source/Symbol/ClangASTContext.cpp1360
-rw-r--r--source/Symbol/ClangASTImporter.cpp267
-rw-r--r--source/Symbol/ClangExternalASTSourceCommon.cpp6
-rw-r--r--source/Symbol/ClangUtil.cpp58
-rw-r--r--source/Symbol/CompactUnwindInfo.cpp520
-rw-r--r--source/Symbol/CompileUnit.cpp63
-rw-r--r--source/Symbol/CompilerDecl.cpp6
-rw-r--r--source/Symbol/CompilerDeclContext.cpp5
-rw-r--r--source/Symbol/CompilerType.cpp21
-rw-r--r--source/Symbol/DWARFCallFrameInfo.cpp52
-rw-r--r--source/Symbol/FuncUnwinders.cpp142
-rw-r--r--source/Symbol/Function.cpp44
-rw-r--r--source/Symbol/GoASTContext.cpp6
-rw-r--r--source/Symbol/JavaASTContext.cpp1561
-rw-r--r--source/Symbol/LineEntry.cpp16
-rw-r--r--source/Symbol/LineTable.cpp5
-rw-r--r--source/Symbol/Makefile14
-rw-r--r--source/Symbol/ObjectFile.cpp30
-rw-r--r--source/Symbol/Symbol.cpp7
-rw-r--r--source/Symbol/SymbolContext.cpp72
-rw-r--r--source/Symbol/SymbolFile.cpp2
-rw-r--r--source/Symbol/SymbolVendor.cpp70
-rw-r--r--source/Symbol/Symtab.cpp256
-rw-r--r--source/Symbol/Type.cpp8
-rw-r--r--source/Symbol/TypeSystem.cpp59
-rw-r--r--source/Symbol/UnwindPlan.cpp25
-rw-r--r--source/Symbol/UnwindTable.cpp28
-rw-r--r--source/Symbol/Variable.cpp37
-rw-r--r--source/Target/ABI.cpp52
-rw-r--r--source/Target/ExecutionContext.cpp63
-rw-r--r--source/Target/InstrumentationRuntime.cpp16
-rw-r--r--source/Target/JITLoader.cpp12
-rw-r--r--source/Target/JITLoaderList.cpp15
-rw-r--r--source/Target/Language.cpp24
-rw-r--r--source/Target/LanguageRuntime.cpp40
-rw-r--r--source/Target/Makefile14
-rw-r--r--source/Target/Memory.cpp46
-rw-r--r--source/Target/MemoryHistory.cpp13
-rw-r--r--source/Target/ObjCLanguageRuntime.cpp5
-rw-r--r--source/Target/OperatingSystem.cpp23
-rw-r--r--source/Target/PathMappingList.cpp62
-rw-r--r--source/Target/Platform.cpp336
-rw-r--r--source/Target/Process.cpp951
-rw-r--r--source/Target/ProcessInfo.cpp29
-rw-r--r--source/Target/ProcessLaunchInfo.cpp93
-rw-r--r--source/Target/Queue.cpp19
-rw-r--r--source/Target/QueueList.cpp18
-rw-r--r--source/Target/RegisterContext.cpp36
-rw-r--r--source/Target/SectionLoadHistory.cpp20
-rw-r--r--source/Target/SectionLoadList.cpp50
-rw-r--r--source/Target/StackFrame.cpp351
-rw-r--r--source/Target/StackFrameList.cpp157
-rw-r--r--source/Target/StackID.cpp16
-rw-r--r--source/Target/StopInfo.cpp29
-rw-r--r--source/Target/SystemRuntime.cpp20
-rw-r--r--source/Target/Target.cpp364
-rw-r--r--source/Target/TargetList.cpp36
-rw-r--r--source/Target/Thread.cpp86
-rw-r--r--source/Target/ThreadCollection.cpp28
-rw-r--r--source/Target/ThreadList.cpp102
-rw-r--r--source/Target/ThreadPlan.cpp34
-rw-r--r--source/Target/ThreadPlanCallUserExpression.cpp16
-rw-r--r--source/Target/ThreadPlanShouldStopHere.cpp41
-rw-r--r--source/Target/ThreadPlanStepInstruction.cpp3
-rw-r--r--source/Target/ThreadPlanStepOverRange.cpp6
-rw-r--r--source/Target/ThreadPlanStepRange.cpp12
-rw-r--r--source/Target/ThreadPlanStepThrough.cpp2
-rw-r--r--source/Target/UnixSignals.cpp60
-rw-r--r--source/Target/UnwindAssembly.cpp16
-rw-r--r--source/Utility/ConvertEnum.cpp2
-rw-r--r--source/Utility/JSON.cpp1
-rw-r--r--source/Utility/Makefile15
-rw-r--r--source/Utility/ModuleCache.cpp24
-rw-r--r--source/Utility/SharingPtr.cpp8
-rw-r--r--source/Utility/StringExtractor.cpp3
-rw-r--r--source/Utility/StringExtractorGDBRemote.cpp133
-rw-r--r--source/Utility/StringExtractorGDBRemote.h32
-rw-r--r--source/Utility/TaskPool.cpp5
653 files changed, 39813 insertions, 24790 deletions
diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt
index 06a26e17c929..2ed42cac062e 100644
--- a/source/API/CMakeLists.txt
+++ b/source/API/CMakeLists.txt
@@ -35,6 +35,8 @@ add_lldb_library(liblldb SHARED
SBLaunchInfo.cpp
SBLineEntry.cpp
SBListener.cpp
+ SBMemoryRegionInfo.cpp
+ SBMemoryRegionInfoList.cpp
SBModule.cpp
SBModuleSpec.cpp
SBPlatform.cpp
diff --git a/source/API/Makefile b/source/API/Makefile
deleted file mode 100644
index e35b2c37735e..000000000000
--- a/source/API/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-##===- source/API/Makefile ---------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LIBRARYNAME := lldbAPI
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
-
-ifeq ($(HOST_OS),MingW)
-CXXFLAGS += -DEXPORT_LIBLLDB
-endif
diff --git a/source/API/SBAddress.cpp b/source/API/SBAddress.cpp
index f95fcb8b3985..470ea5659f28 100644
--- a/source/API/SBAddress.cpp
+++ b/source/API/SBAddress.cpp
@@ -15,7 +15,6 @@
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/LineEntry.h"
#include "lldb/Target/Target.h"
@@ -125,7 +124,7 @@ SBAddress::GetLoadAddress (const SBTarget &target) const
{
if (m_opaque_ap->IsValid())
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
addr = m_opaque_ap->GetLoadAddress (target_sp.get());
}
}
diff --git a/source/API/SBBlock.cpp b/source/API/SBBlock.cpp
index fdbbbc045279..03ee7343c9f5 100644
--- a/source/API/SBBlock.cpp
+++ b/source/API/SBBlock.cpp
@@ -131,7 +131,11 @@ SBBlock::AppendVariables (bool can_create, bool get_parent_variables, lldb_priva
if (IsValid())
{
bool show_inline = true;
- m_opaque_ptr->AppendVariables (can_create, get_parent_variables, show_inline, var_list);
+ m_opaque_ptr->AppendVariables (can_create,
+ get_parent_variables,
+ show_inline,
+ [](Variable*) { return true; },
+ var_list);
}
}
@@ -290,6 +294,7 @@ SBBlock::GetVariables (lldb::SBFrame& frame,
{
case eValueTypeVariableGlobal:
case eValueTypeVariableStatic:
+ case eValueTypeVariableThreadLocal:
add_variable = statics;
break;
@@ -352,6 +357,7 @@ SBBlock::GetVariables (lldb::SBTarget& target,
{
case eValueTypeVariableGlobal:
case eValueTypeVariableStatic:
+ case eValueTypeVariableThreadLocal:
add_variable = statics;
break;
diff --git a/source/API/SBBreakpoint.cpp b/source/API/SBBreakpoint.cpp
index 1f58ddb7152a..ec3a3de4a788 100644
--- a/source/API/SBBreakpoint.cpp
+++ b/source/API/SBBreakpoint.cpp
@@ -149,7 +149,7 @@ SBBreakpoint::ClearAllBreakpointSites ()
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->ClearAllBreakpointSites ();
}
}
@@ -163,7 +163,7 @@ SBBreakpoint::FindLocationByAddress (addr_t vm_addr)
{
if (vm_addr != LLDB_INVALID_ADDRESS)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
Address address;
Target &target = m_opaque_sp->GetTarget();
if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address))
@@ -183,7 +183,7 @@ SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr)
if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
Address address;
Target &target = m_opaque_sp->GetTarget();
if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address))
@@ -203,7 +203,7 @@ SBBreakpoint::FindLocationByID (break_id_t bp_loc_id)
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id));
}
@@ -217,7 +217,7 @@ SBBreakpoint::GetLocationAtIndex (uint32_t index)
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index));
}
@@ -235,7 +235,7 @@ SBBreakpoint::SetEnabled (bool enable)
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->SetEnabled (enable);
}
}
@@ -245,7 +245,7 @@ SBBreakpoint::IsEnabled ()
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->IsEnabled();
}
else
@@ -263,7 +263,7 @@ SBBreakpoint::SetOneShot (bool one_shot)
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->SetOneShot (one_shot);
}
}
@@ -273,7 +273,7 @@ SBBreakpoint::IsOneShot () const
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->IsOneShot();
}
else
@@ -285,7 +285,7 @@ SBBreakpoint::IsInternal ()
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->IsInternal();
}
else
@@ -303,7 +303,7 @@ SBBreakpoint::SetIgnoreCount (uint32_t count)
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->SetIgnoreCount (count);
}
}
@@ -313,7 +313,7 @@ SBBreakpoint::SetCondition (const char *condition)
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->SetCondition (condition);
}
}
@@ -323,7 +323,7 @@ SBBreakpoint::GetCondition ()
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->GetConditionText ();
}
return nullptr;
@@ -335,7 +335,7 @@ SBBreakpoint::GetHitCount () const
uint32_t count = 0;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
count = m_opaque_sp->GetHitCount();
}
@@ -353,7 +353,7 @@ SBBreakpoint::GetIgnoreCount () const
uint32_t count = 0;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
count = m_opaque_sp->GetIgnoreCount();
}
@@ -370,7 +370,7 @@ SBBreakpoint::SetThreadID (tid_t tid)
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->SetThreadID (tid);
}
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -385,7 +385,7 @@ SBBreakpoint::GetThreadID ()
tid_t tid = LLDB_INVALID_THREAD_ID;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
tid = m_opaque_sp->GetThreadID();
}
@@ -405,7 +405,7 @@ SBBreakpoint::SetThreadIndex (uint32_t index)
static_cast<void*>(m_opaque_sp.get()), index);
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index);
}
}
@@ -416,7 +416,7 @@ SBBreakpoint::GetThreadIndex() const
uint32_t thread_idx = UINT32_MAX;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
if (thread_spec != nullptr)
thread_idx = thread_spec->GetIndex();
@@ -439,7 +439,7 @@ SBBreakpoint::SetThreadName (const char *thread_name)
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name);
}
}
@@ -450,7 +450,7 @@ SBBreakpoint::GetThreadName () const
const char *name = nullptr;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
if (thread_spec != nullptr)
name = thread_spec->GetName();
@@ -472,7 +472,7 @@ SBBreakpoint::SetQueueName (const char *queue_name)
static_cast<void*>(m_opaque_sp.get()), queue_name);
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name);
}
}
@@ -483,7 +483,7 @@ SBBreakpoint::GetQueueName () const
const char *name = nullptr;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
if (thread_spec)
name = thread_spec->GetQueueName();
@@ -502,7 +502,7 @@ SBBreakpoint::GetNumResolvedLocations() const
size_t num_resolved = 0;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
num_resolved = m_opaque_sp->GetNumResolvedLocations();
}
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -519,7 +519,7 @@ SBBreakpoint::GetNumLocations() const
size_t num_locs = 0;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
num_locs = m_opaque_sp->GetNumLocations();
}
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -535,7 +535,7 @@ SBBreakpoint::GetDescription (SBStream &s)
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
m_opaque_sp->GetResolverDescription (s.get());
m_opaque_sp->GetFilterDescription (s.get());
@@ -598,7 +598,7 @@ SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
}
@@ -616,7 +616,7 @@ SBBreakpoint::SetScriptCallbackFunction (const char *callback_function_name)
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallbackFunction (bp_options,
callback_function_name);
@@ -635,7 +635,7 @@ SBBreakpoint::SetScriptCallbackBody (const char *callback_body_text)
SBError sb_error;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
Error error = m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options,
callback_body_text);
@@ -659,7 +659,7 @@ SBBreakpoint::AddName (const char *new_name)
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
Error error; // Think I'm just going to swallow the error here, it's probably more annoying to have to provide it.
return m_opaque_sp->AddName(new_name, error);
}
@@ -679,7 +679,7 @@ SBBreakpoint::RemoveName (const char *name_to_remove)
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->RemoveName(name_to_remove);
}
}
@@ -696,7 +696,7 @@ SBBreakpoint::MatchesName (const char *name)
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->MatchesName(name);
}
@@ -714,7 +714,7 @@ SBBreakpoint::GetNames (SBStringList &names)
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
std::vector<std::string> names_vec;
m_opaque_sp->GetNames(names_vec);
for (std::string name : names_vec)
diff --git a/source/API/SBBreakpointLocation.cpp b/source/API/SBBreakpointLocation.cpp
index 4390e9ad737a..631a32bc9dda 100644
--- a/source/API/SBBreakpointLocation.cpp
+++ b/source/API/SBBreakpointLocation.cpp
@@ -92,7 +92,7 @@ SBBreakpointLocation::GetLoadAddress ()
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
ret_addr = m_opaque_sp->GetLoadAddress();
}
@@ -104,7 +104,7 @@ SBBreakpointLocation::SetEnabled (bool enabled)
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->SetEnabled (enabled);
}
}
@@ -114,7 +114,7 @@ SBBreakpointLocation::IsEnabled ()
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->IsEnabled();
}
else
@@ -126,7 +126,7 @@ SBBreakpointLocation::GetIgnoreCount ()
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->GetIgnoreCount();
}
else
@@ -138,7 +138,7 @@ SBBreakpointLocation::SetIgnoreCount (uint32_t n)
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->SetIgnoreCount (n);
}
}
@@ -148,7 +148,7 @@ SBBreakpointLocation::SetCondition (const char *condition)
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->SetCondition (condition);
}
}
@@ -158,7 +158,7 @@ SBBreakpointLocation::GetCondition ()
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->GetConditionText ();
}
return NULL;
@@ -176,7 +176,7 @@ SBBreakpointLocation::SetScriptCallbackFunction (const char *callback_function_n
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
BreakpointOptions *bp_options = m_opaque_sp->GetLocationOptions();
m_opaque_sp->GetBreakpoint().GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallbackFunction (bp_options,
callback_function_name);
@@ -195,7 +195,7 @@ SBBreakpointLocation::SetScriptCallbackBody (const char *callback_body_text)
SBError sb_error;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
BreakpointOptions *bp_options = m_opaque_sp->GetLocationOptions();
Error error = m_opaque_sp->GetBreakpoint().GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options,
callback_body_text);
@@ -212,7 +212,7 @@ SBBreakpointLocation::SetThreadID (tid_t thread_id)
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->SetThreadID (thread_id);
}
}
@@ -223,7 +223,7 @@ SBBreakpointLocation::GetThreadID ()
tid_t tid = LLDB_INVALID_THREAD_ID;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->GetThreadID();
}
return tid;
@@ -234,7 +234,7 @@ SBBreakpointLocation::SetThreadIndex (uint32_t index)
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->SetThreadIndex (index);
}
}
@@ -245,7 +245,7 @@ SBBreakpointLocation::GetThreadIndex() const
uint32_t thread_idx = UINT32_MAX;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->GetThreadIndex();
}
return thread_idx;
@@ -257,7 +257,7 @@ SBBreakpointLocation::SetThreadName (const char *thread_name)
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->SetThreadName (thread_name);
}
}
@@ -267,7 +267,7 @@ SBBreakpointLocation::GetThreadName () const
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->GetThreadName();
}
return NULL;
@@ -278,7 +278,7 @@ SBBreakpointLocation::SetQueueName (const char *queue_name)
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->SetQueueName (queue_name);
}
}
@@ -288,7 +288,7 @@ SBBreakpointLocation::GetQueueName () const
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->GetQueueName ();
}
return NULL;
@@ -299,7 +299,7 @@ SBBreakpointLocation::IsResolved ()
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->IsResolved();
}
return false;
@@ -319,7 +319,7 @@ SBBreakpointLocation::GetDescription (SBStream &description, DescriptionLevel le
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
m_opaque_sp->GetDescription (&strm, level);
strm.EOL();
}
@@ -334,7 +334,7 @@ SBBreakpointLocation::GetID ()
{
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
return m_opaque_sp->GetID ();
}
else
@@ -352,7 +352,7 @@ SBBreakpointLocation::GetBreakpoint ()
SBBreakpoint sb_bp;
if (m_opaque_sp)
{
- Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
*sb_bp = m_opaque_sp->GetBreakpoint ().shared_from_this();
}
diff --git a/source/API/SBBroadcaster.cpp b/source/API/SBBroadcaster.cpp
index 73eac5183f8a..4b751adc295f 100644
--- a/source/API/SBBroadcaster.cpp
+++ b/source/API/SBBroadcaster.cpp
@@ -117,14 +117,14 @@ SBBroadcaster::AddInitialEventsToListener (const SBListener &listener, uint32_t
static_cast<void*>(m_opaque_ptr),
static_cast<void*>(listener.get()), requested_events);
if (m_opaque_ptr)
- m_opaque_ptr->AddInitialEventsToListener (listener.get(), requested_events);
+ m_opaque_ptr->AddInitialEventsToListener (listener.m_opaque_sp, requested_events);
}
uint32_t
SBBroadcaster::AddListener (const SBListener &listener, uint32_t event_mask)
{
if (m_opaque_ptr)
- return m_opaque_ptr->AddListener (listener.get(), event_mask);
+ return m_opaque_ptr->AddListener (listener.m_opaque_sp, event_mask);
return 0;
}
@@ -148,7 +148,7 @@ bool
SBBroadcaster::RemoveListener (const SBListener &listener, uint32_t event_mask)
{
if (m_opaque_ptr)
- return m_opaque_ptr->RemoveListener (listener.get(), event_mask);
+ return m_opaque_ptr->RemoveListener (listener.m_opaque_sp, event_mask);
return false;
}
diff --git a/source/API/SBCommandInterpreter.cpp b/source/API/SBCommandInterpreter.cpp
index 21f431dac6a3..dfa1709a3491 100644
--- a/source/API/SBCommandInterpreter.cpp
+++ b/source/API/SBCommandInterpreter.cpp
@@ -398,7 +398,7 @@ SBCommandInterpreter::GetProcess ()
TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
if (target_sp)
{
- Mutex::Locker api_locker(target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
process_sp = target_sp->GetProcessSP();
sb_process.SetSP(process_sp);
}
@@ -483,9 +483,9 @@ SBCommandInterpreter::SourceInitFileInHomeDirectory (SBCommandReturnObject &resu
if (IsValid())
{
TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
- Mutex::Locker api_locker;
+ std::unique_lock<std::recursive_mutex> lock;
if (target_sp)
- api_locker.Lock(target_sp->GetAPIMutex());
+ lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
m_opaque_ptr->SourceInitFile (false, result.ref());
}
else
@@ -508,9 +508,9 @@ SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory (SBCommandReturnOb
if (IsValid())
{
TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
- Mutex::Locker api_locker;
+ std::unique_lock<std::recursive_mutex> lock;
if (target_sp)
- api_locker.Lock(target_sp->GetAPIMutex());
+ lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
m_opaque_ptr->SourceInitFile (true, result.ref());
}
else
diff --git a/source/API/SBCommandReturnObject.cpp b/source/API/SBCommandReturnObject.cpp
index a2ed4d6e8c26..a7bc31da8a89 100644
--- a/source/API/SBCommandReturnObject.cpp
+++ b/source/API/SBCommandReturnObject.cpp
@@ -258,15 +258,27 @@ SBCommandReturnObject::GetDescription (SBStream &description)
void
SBCommandReturnObject::SetImmediateOutputFile(FILE *fh)
{
- if (m_opaque_ap)
- m_opaque_ap->SetImmediateOutputFile(fh);
+ SetImmediateOutputFile(fh, false);
}
void
SBCommandReturnObject::SetImmediateErrorFile(FILE *fh)
{
+ SetImmediateErrorFile(fh, false);
+}
+
+void
+SBCommandReturnObject::SetImmediateOutputFile(FILE *fh, bool transfer_ownership)
+{
+ if (m_opaque_ap)
+ m_opaque_ap->SetImmediateOutputFile(fh, transfer_ownership);
+}
+
+void
+SBCommandReturnObject::SetImmediateErrorFile(FILE *fh, bool transfer_ownership)
+{
if (m_opaque_ap)
- m_opaque_ap->SetImmediateErrorFile(fh);
+ m_opaque_ap->SetImmediateErrorFile(fh, transfer_ownership);
}
void
diff --git a/source/API/SBDebugger.cpp b/source/API/SBDebugger.cpp
index 1645294b5a3f..3493ad507a71 100644
--- a/source/API/SBDebugger.cpp
+++ b/source/API/SBDebugger.cpp
@@ -191,8 +191,8 @@ SBDebugger::Create(bool source_init_files, lldb::LogOutputCallback callback, voi
// uses global collections and having two threads parsing the .lldbinit files can cause
// mayhem. So to get around this for now we need to use a mutex to prevent bad things
// from happening.
- static Mutex g_mutex(Mutex::eMutexTypeRecursive);
- Mutex::Locker locker(g_mutex);
+ static std::recursive_mutex g_mutex;
+ std::lock_guard<std::recursive_mutex> guard(g_mutex);
debugger.reset(Debugger::CreateInstance(callback, baton));
@@ -411,9 +411,9 @@ SBDebugger::HandleCommand (const char *command)
if (m_opaque_sp)
{
TargetSP target_sp (m_opaque_sp->GetSelectedTarget());
- Mutex::Locker api_locker;
+ std::unique_lock<std::recursive_mutex> lock;
if (target_sp)
- api_locker.Lock(target_sp->GetAPIMutex());
+ lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
SBCommandInterpreter sb_interpreter(GetCommandInterpreter ());
SBCommandReturnObject result;
@@ -432,8 +432,8 @@ SBDebugger::HandleCommand (const char *command)
if (process_sp)
{
EventSP event_sp;
- Listener &lldb_listener = m_opaque_sp->GetListener();
- while (lldb_listener.GetNextEventForBroadcaster (process_sp.get(), event_sp))
+ ListenerSP lldb_listener_sp = m_opaque_sp->GetListener();
+ while (lldb_listener_sp->GetNextEventForBroadcaster (process_sp.get(), event_sp))
{
SBEvent event(event_sp);
HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle());
@@ -450,7 +450,7 @@ SBDebugger::GetListener ()
SBListener sb_listener;
if (m_opaque_sp)
- sb_listener.reset(&m_opaque_sp->GetListener(), false);
+ sb_listener.reset(m_opaque_sp->GetListener());
if (log)
log->Printf ("SBDebugger(%p)::GetListener () => SBListener(%p)",
@@ -474,8 +474,8 @@ SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event,
char stdio_buffer[1024];
size_t len;
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
-
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+
if (event_type & (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged))
{
// Drain stdout when we stop just in case we have any bytes
diff --git a/source/API/SBExpressionOptions.cpp b/source/API/SBExpressionOptions.cpp
index 43b7d03064f5..328a96ef6b53 100644
--- a/source/API/SBExpressionOptions.cpp
+++ b/source/API/SBExpressionOptions.cpp
@@ -197,6 +197,30 @@ SBExpressionOptions::SetPrefix (const char *prefix)
return m_opaque_ap->SetPrefix(prefix);
}
+bool
+SBExpressionOptions::GetAutoApplyFixIts ()
+{
+ return m_opaque_ap->GetAutoApplyFixIts ();
+}
+
+void
+SBExpressionOptions::SetAutoApplyFixIts (bool b)
+{
+ return m_opaque_ap->SetAutoApplyFixIts (b);
+}
+
+bool
+SBExpressionOptions::GetTopLevel ()
+{
+ return m_opaque_ap->GetExecutionPolicy() == eExecutionPolicyTopLevel;
+}
+
+void
+SBExpressionOptions::SetTopLevel (bool b)
+{
+ m_opaque_ap->SetExecutionPolicy(b ? eExecutionPolicyTopLevel : m_opaque_ap->default_execution_policy);
+}
+
EvaluateExpressionOptions *
SBExpressionOptions::get() const
{
diff --git a/source/API/SBFileSpec.cpp b/source/API/SBFileSpec.cpp
index dd7435de1b5b..23bc5bc8eb65 100644
--- a/source/API/SBFileSpec.cpp
+++ b/source/API/SBFileSpec.cpp
@@ -211,3 +211,9 @@ SBFileSpec::GetDescription (SBStream &description) const
strm.PutCString (path);
return true;
}
+
+void
+SBFileSpec::AppendPathComponent (const char *fn)
+{
+ m_opaque_ap->AppendPathComponent (fn);
+}
diff --git a/source/API/SBFrame.cpp b/source/API/SBFrame.cpp
index 02a215beb07d..38bbfb8675ff 100644
--- a/source/API/SBFrame.cpp
+++ b/source/API/SBFrame.cpp
@@ -10,6 +10,7 @@
// C Includes
// C++ Includes
#include <algorithm>
+#include <set>
#include <string>
// Other libraries and framework includes
@@ -104,7 +105,20 @@ SBFrame::SetFrameSP (const StackFrameSP &lldb_object_sp)
bool
SBFrame::IsValid() const
{
- return GetFrameSP().get() != nullptr;
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
+ Target *target = exe_ctx.GetTargetPtr();
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
+ {
+ Process::StopLocker stop_locker;
+ if (stop_locker.TryLock(&process->GetRunLock()))
+ return GetFrameSP().get() != nullptr;
+ }
+
+ // Without a target & process we can't have a valid stack frame.
+ return false;
}
SBSymbolContext
@@ -112,8 +126,8 @@ SBFrame::GetSymbolContext (uint32_t resolve_scope) const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBSymbolContext sb_sym_ctx;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -155,8 +169,8 @@ SBFrame::GetModule () const
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBModule sb_module;
ModuleSP module_sp;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -198,8 +212,8 @@ SBFrame::GetCompileUnit () const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBCompileUnit sb_comp_unit;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -239,8 +253,8 @@ SBFrame::GetFunction () const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBFunction sb_function;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -280,8 +294,8 @@ SBFrame::GetSymbol () const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBSymbol sb_symbol;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -320,8 +334,8 @@ SBFrame::GetBlock () const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBBlock sb_block;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -360,8 +374,8 @@ SBBlock
SBFrame::GetFrameBlock () const
{
SBBlock sb_block;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -401,8 +415,8 @@ SBFrame::GetLineEntry () const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBLineEntry sb_line_entry;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -441,7 +455,9 @@ SBFrame::GetFrameID () const
{
uint32_t frame_idx = UINT32_MAX;
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
StackFrame *frame = exe_ctx.GetFramePtr();
if (frame)
frame_idx = frame->GetFrameIndex ();
@@ -456,7 +472,9 @@ SBFrame::GetFrameID () const
lldb::addr_t
SBFrame::GetCFA () const
{
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
StackFrame *frame = exe_ctx.GetFramePtr();
if (frame)
return frame->GetStackID().GetCallFrameAddress();
@@ -468,8 +486,8 @@ SBFrame::GetPC () const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
addr_t addr = LLDB_INVALID_ADDRESS;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -509,8 +527,8 @@ SBFrame::SetPC (addr_t new_pc)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
bool ret_val = false;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -550,8 +568,8 @@ SBFrame::GetSP () const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
addr_t addr = LLDB_INVALID_ADDRESS;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -590,8 +608,8 @@ SBFrame::GetFP () const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
addr_t addr = LLDB_INVALID_ADDRESS;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -630,8 +648,8 @@ SBFrame::GetPCAddress () const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBAddress sb_addr;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
@@ -675,7 +693,9 @@ lldb::SBValue
SBFrame::GetValueForVariablePath (const char *var_path)
{
SBValue sb_value;
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
StackFrame *frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
if (frame && target)
@@ -690,7 +710,6 @@ lldb::SBValue
SBFrame::GetValueForVariablePath (const char *var_path, DynamicValueType use_dynamic)
{
SBValue sb_value;
- Mutex::Locker api_locker;
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (var_path == nullptr || var_path[0] == '\0')
{
@@ -698,8 +717,9 @@ SBFrame::GetValueForVariablePath (const char *var_path, DynamicValueType use_dyn
log->Printf ("SBFrame::GetValueForVariablePath called with empty variable path.");
return sb_value;
}
-
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -740,7 +760,9 @@ SBValue
SBFrame::FindVariable (const char *name)
{
SBValue value;
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
StackFrame *frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
if (frame && target)
@@ -766,8 +788,8 @@ SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic)
}
ValueObjectSP value_sp;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -789,9 +811,10 @@ SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic)
const bool get_parent_variables = true;
const bool stop_if_block_is_inlined_function = true;
- if (sc.block->AppendVariables (can_create,
+ if (sc.block->AppendVariables (can_create,
get_parent_variables,
stop_if_block_is_inlined_function,
+ [frame](Variable* v) { return v->IsInScope(frame); },
&variable_list))
{
var_sp = variable_list.FindVariable (ConstString(name));
@@ -829,7 +852,9 @@ SBValue
SBFrame::FindValue (const char *name, ValueType value_type)
{
SBValue value;
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
StackFrame *frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
if (frame && target)
@@ -854,8 +879,8 @@ SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueTy
}
ValueObjectSP value_sp;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -876,32 +901,31 @@ SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueTy
case eValueTypeVariableStatic: // static variable
case eValueTypeVariableArgument: // function argument variables
case eValueTypeVariableLocal: // function local variables
+ case eValueTypeVariableThreadLocal: // thread local variables
+ {
+ SymbolContext sc(frame->GetSymbolContext(eSymbolContextBlock));
+
+ const bool can_create = true;
+ const bool get_parent_variables = true;
+ const bool stop_if_block_is_inlined_function = true;
+
+ if (sc.block)
+ sc.block->AppendVariables(can_create, get_parent_variables, stop_if_block_is_inlined_function,
+ [frame](Variable *v) { return v->IsInScope(frame); }, &variable_list);
+ if (value_type == eValueTypeVariableGlobal)
{
- SymbolContext sc(frame->GetSymbolContext(eSymbolContextBlock));
-
- const bool can_create = true;
- const bool get_parent_variables = true;
- const bool stop_if_block_is_inlined_function = true;
-
- if (sc.block)
- sc.block->AppendVariables(can_create,
- get_parent_variables,
- stop_if_block_is_inlined_function,
- &variable_list);
- if (value_type == eValueTypeVariableGlobal)
- {
- const bool get_file_globals = true;
- VariableList *frame_vars = frame->GetVariableList(get_file_globals);
- if (frame_vars)
- frame_vars->AppendVariablesIfUnique(variable_list);
- }
- ConstString const_name(name);
- VariableSP variable_sp(variable_list.FindVariable(const_name, value_type));
- if (variable_sp)
- {
- value_sp = frame->GetValueObjectForFrameVariable(variable_sp, eNoDynamicValues);
- sb_value.SetSP(value_sp, use_dynamic);
- }
+ const bool get_file_globals = true;
+ VariableList *frame_vars = frame->GetVariableList(get_file_globals);
+ if (frame_vars)
+ frame_vars->AppendVariablesIfUnique(variable_list);
+ }
+ ConstString const_name(name);
+ VariableSP variable_sp(variable_list.FindVariable(const_name, value_type));
+ if (variable_sp)
+ {
+ value_sp = frame->GetValueObjectForFrameVariable(variable_sp, eNoDynamicValues);
+ sb_value.SetSP(value_sp, use_dynamic);
+ }
}
break;
@@ -1011,7 +1035,9 @@ SBFrame::GetThread () const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
ThreadSP thread_sp (exe_ctx.GetThreadSP());
SBThread sb_thread (thread_sp);
@@ -1032,8 +1058,8 @@ SBFrame::Disassemble () const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
const char *disassembly = nullptr;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -1075,7 +1101,9 @@ SBFrame::GetVariables (bool arguments,
bool in_scope_only)
{
SBValueList value_list;
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
StackFrame *frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
if (frame && target)
@@ -1103,7 +1131,9 @@ SBFrame::GetVariables (bool arguments,
bool in_scope_only,
lldb::DynamicValueType use_dynamic)
{
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
Target *target = exe_ctx.GetTargetPtr();
const bool include_runtime_support_values = target ? target->GetDisplayRuntimeSupportValues() : false;
SBVariablesOptions options;
@@ -1122,8 +1152,8 @@ SBFrame::GetVariables (const lldb::SBVariablesOptions& options)
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBValueList value_list;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -1140,7 +1170,8 @@ SBFrame::GetVariables (const lldb::SBVariablesOptions& options)
arguments, locals,
statics, in_scope_only,
include_runtime_support_values, use_dynamic);
-
+
+ std::set<VariableSP> variable_set;
Process *process = exe_ctx.GetProcessPtr();
if (target && process)
{
@@ -1168,6 +1199,7 @@ SBFrame::GetVariables (const lldb::SBVariablesOptions& options)
{
case eValueTypeVariableGlobal:
case eValueTypeVariableStatic:
+ case eValueTypeVariableThreadLocal:
add_variable = statics;
break;
@@ -1184,6 +1216,12 @@ SBFrame::GetVariables (const lldb::SBVariablesOptions& options)
}
if (add_variable)
{
+ // Only add variables once so we don't end up with duplicates
+ if (variable_set.find(variable_sp) == variable_set.end())
+ variable_set.insert(variable_sp);
+ else
+ continue;
+
if (in_scope_only && !variable_sp->IsInScope(frame))
continue;
@@ -1230,8 +1268,8 @@ SBFrame::GetRegisters ()
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBValueList value_list;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -1282,8 +1320,8 @@ SBFrame::FindRegister (const char *name)
SBValue result;
ValueObjectSP value_sp;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
@@ -1341,8 +1379,8 @@ SBFrame::GetDescription (SBStream &description)
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Stream &strm = description.ref();
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrame *frame;
Target *target = exe_ctx.GetTargetPtr();
@@ -1380,7 +1418,9 @@ SBValue
SBFrame::EvaluateExpression (const char *expr)
{
SBValue result;
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
StackFrame *frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
if (frame && target)
@@ -1389,6 +1429,7 @@ SBFrame::EvaluateExpression (const char *expr)
lldb::DynamicValueType fetch_dynamic_value = frame->CalculateTarget()->GetPreferDynamicValue();
options.SetFetchDynamicValue (fetch_dynamic_value);
options.SetUnwindOnError (true);
+ options.SetIgnoreBreakpoints (true);
if (target->GetLanguage() != eLanguageTypeUnknown)
options.SetLanguage(target->GetLanguage());
else
@@ -1404,7 +1445,10 @@ SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dyna
SBExpressionOptions options;
options.SetFetchDynamicValue (fetch_dynamic_value);
options.SetUnwindOnError (true);
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ options.SetIgnoreBreakpoints (true);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
StackFrame *frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
if (target && target->GetLanguage() != eLanguageTypeUnknown)
@@ -1418,9 +1462,12 @@ SBValue
SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dynamic_value, bool unwind_on_error)
{
SBExpressionOptions options;
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
options.SetFetchDynamicValue (fetch_dynamic_value);
options.SetUnwindOnError (unwind_on_error);
+ options.SetIgnoreBreakpoints (true);
StackFrame *frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
if (target && target->GetLanguage() != eLanguageTypeUnknown)
@@ -1435,7 +1482,9 @@ SBFrame::EvaluateExpression (const char *expr, const SBExpressionOptions &option
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+#ifndef LLDB_DISABLE_PYTHON
Log *expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+#endif
ExpressionResults exe_results = eExpressionSetupError;
SBValue expr_result;
@@ -1449,8 +1498,8 @@ SBFrame::EvaluateExpression (const char *expr, const SBExpressionOptions &option
ValueObjectSP expr_value_sp;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (log)
log->Printf ("SBFrame()::EvaluateExpression (expr=\"%s\")...", expr);
@@ -1521,7 +1570,9 @@ bool
SBFrame::IsInlined() const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
Process *process = exe_ctx.GetProcessPtr();
@@ -1565,7 +1616,9 @@ SBFrame::GetFunctionName() const
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
const char *name = nullptr;
- ExecutionContext exe_ctx(m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
Process *process = exe_ctx.GetProcessPtr();
@@ -1621,7 +1674,10 @@ SBFrame::GetDisplayFunctionName()
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
const char *name = nullptr;
- ExecutionContext exe_ctx(m_opaque_sp.get());
+
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
Process *process = exe_ctx.GetProcessPtr();
diff --git a/source/API/SBFunction.cpp b/source/API/SBFunction.cpp
index 2d03d53fd9f7..b5983d763be1 100644
--- a/source/API/SBFunction.cpp
+++ b/source/API/SBFunction.cpp
@@ -156,12 +156,12 @@ SBFunction::GetInstructions (SBTarget target, const char *flavor)
SBInstructionList sb_instructions;
if (m_opaque_ptr)
{
- Mutex::Locker api_locker;
ExecutionContext exe_ctx;
TargetSP target_sp (target.GetSP());
+ std::unique_lock<std::recursive_mutex> lock;
if (target_sp)
{
- api_locker.Lock (target_sp->GetAPIMutex());
+ lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
target_sp->CalculateExecutionContext (exe_ctx);
exe_ctx.SetProcessSP(target_sp->GetProcessSP());
}
diff --git a/source/API/SBHostOS.cpp b/source/API/SBHostOS.cpp
index 008ca4d9672e..6c172997bdc8 100644
--- a/source/API/SBHostOS.cpp
+++ b/source/API/SBHostOS.cpp
@@ -17,6 +17,9 @@
#include "lldb/Host/HostThread.h"
#include "lldb/Host/ThreadLauncher.h"
+#include "llvm/Support/Path.h"
+#include "llvm/ADT/SmallString.h"
+
using namespace lldb;
using namespace lldb_private;
@@ -53,6 +56,19 @@ SBHostOS::GetLLDBPath (lldb::PathType path_type)
return sb_fspec;
}
+SBFileSpec
+SBHostOS::GetUserHomeDirectory ()
+{
+ SBFileSpec sb_fspec;
+
+ llvm::SmallString<64> home_dir_path;
+ llvm::sys::path::home_directory (home_dir_path);
+ FileSpec homedir (home_dir_path.c_str(), true);
+
+ sb_fspec.SetFileSpec (homedir);
+ return sb_fspec;
+}
+
lldb::thread_t
SBHostOS::ThreadCreate
(
diff --git a/source/API/SBInstruction.cpp b/source/API/SBInstruction.cpp
index a17f3f8dbd5d..ccf561edb90f 100644
--- a/source/API/SBInstruction.cpp
+++ b/source/API/SBInstruction.cpp
@@ -26,15 +26,63 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
+//----------------------------------------------------------------------
+// We recently fixed a leak in one of the Instruction subclasses where
+// the instruction will only hold a weak reference to the disassembler
+// to avoid a cycle that was keeping both objects alive (leak) and we
+// need the InstructionImpl class to make sure our public API behaves
+// as users would expect. Calls in our public API allow clients to do
+// things like:
+//
+// 1 lldb::SBInstruction inst;
+// 2 inst = target.ReadInstructions(pc, 1).GetInstructionAtIndex(0)
+// 3 if (inst.DoesBranch())
+// 4 ...
+//
+// There was a temporary lldb::DisassemblerSP object created in the
+// SBInstructionList that was returned by lldb.target.ReadInstructions()
+// that will go away after line 2 but the "inst" object should be able
+// to still answer questions about itself. So we make sure that any
+// SBInstruction objects that are given out have a strong reference to
+// the disassembler and the instruction so that the object can live and
+// successfully respond to all queries.
+//----------------------------------------------------------------------
+class InstructionImpl
+{
+public:
+ InstructionImpl (const lldb::DisassemblerSP &disasm_sp, const lldb::InstructionSP& inst_sp) :
+ m_disasm_sp(disasm_sp),
+ m_inst_sp(inst_sp)
+ {
+ }
+
+ lldb::InstructionSP
+ GetSP() const
+ {
+ return m_inst_sp;
+ }
+
+ bool
+ IsValid() const
+ {
+ return (bool)m_inst_sp;
+ }
+
+protected:
+ lldb::DisassemblerSP m_disasm_sp; // Can be empty/invalid
+ lldb::InstructionSP m_inst_sp;
+};
+
using namespace lldb;
using namespace lldb_private;
-SBInstruction::SBInstruction ()
+SBInstruction::SBInstruction() :
+ m_opaque_sp()
{
}
-SBInstruction::SBInstruction (const lldb::InstructionSP& inst_sp) :
- m_opaque_sp (inst_sp)
+SBInstruction::SBInstruction(const lldb::DisassemblerSP &disasm_sp, const lldb::InstructionSP& inst_sp) :
+ m_opaque_sp(new InstructionImpl(disasm_sp, inst_sp))
{
}
@@ -58,33 +106,36 @@ SBInstruction::~SBInstruction ()
bool
SBInstruction::IsValid()
{
- return (m_opaque_sp.get() != NULL);
+ return m_opaque_sp && m_opaque_sp->IsValid();
}
SBAddress
SBInstruction::GetAddress()
{
SBAddress sb_addr;
- if (m_opaque_sp && m_opaque_sp->GetAddress().IsValid())
- sb_addr.SetAddress(&m_opaque_sp->GetAddress());
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp && inst_sp->GetAddress().IsValid())
+ sb_addr.SetAddress(&inst_sp->GetAddress());
return sb_addr;
}
const char *
SBInstruction::GetMnemonic(SBTarget target)
{
- if (m_opaque_sp)
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
{
- Mutex::Locker api_locker;
ExecutionContext exe_ctx;
TargetSP target_sp (target.GetSP());
+ std::unique_lock<std::recursive_mutex> lock;
if (target_sp)
{
- api_locker.Lock (target_sp->GetAPIMutex());
+ lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
+
target_sp->CalculateExecutionContext (exe_ctx);
exe_ctx.SetProcessSP(target_sp->GetProcessSP());
}
- return m_opaque_sp->GetMnemonic(&exe_ctx);
+ return inst_sp->GetMnemonic(&exe_ctx);
}
return NULL;
}
@@ -92,18 +143,20 @@ SBInstruction::GetMnemonic(SBTarget target)
const char *
SBInstruction::GetOperands(SBTarget target)
{
- if (m_opaque_sp)
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
{
- Mutex::Locker api_locker;
ExecutionContext exe_ctx;
TargetSP target_sp (target.GetSP());
+ std::unique_lock<std::recursive_mutex> lock;
if (target_sp)
{
- api_locker.Lock (target_sp->GetAPIMutex());
+ lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
+
target_sp->CalculateExecutionContext (exe_ctx);
exe_ctx.SetProcessSP(target_sp->GetProcessSP());
}
- return m_opaque_sp->GetOperands(&exe_ctx);
+ return inst_sp->GetOperands(&exe_ctx);
}
return NULL;
}
@@ -111,18 +164,20 @@ SBInstruction::GetOperands(SBTarget target)
const char *
SBInstruction::GetComment(SBTarget target)
{
- if (m_opaque_sp)
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
{
- Mutex::Locker api_locker;
ExecutionContext exe_ctx;
TargetSP target_sp (target.GetSP());
+ std::unique_lock<std::recursive_mutex> lock;
if (target_sp)
{
- api_locker.Lock (target_sp->GetAPIMutex());
+ lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
+
target_sp->CalculateExecutionContext (exe_ctx);
exe_ctx.SetProcessSP(target_sp->GetProcessSP());
}
- return m_opaque_sp->GetComment(&exe_ctx);
+ return inst_sp->GetComment(&exe_ctx);
}
return NULL;
}
@@ -130,8 +185,9 @@ SBInstruction::GetComment(SBTarget target)
size_t
SBInstruction::GetByteSize ()
{
- if (m_opaque_sp)
- return m_opaque_sp->GetOpcode().GetByteSize();
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
+ return inst_sp->GetOpcode().GetByteSize();
return 0;
}
@@ -139,10 +195,11 @@ SBData
SBInstruction::GetData (SBTarget target)
{
lldb::SBData sb_data;
- if (m_opaque_sp)
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
{
DataExtractorSP data_extractor_sp (new DataExtractor());
- if (m_opaque_sp->GetData (*data_extractor_sp))
+ if (inst_sp->GetData (*data_extractor_sp))
{
sb_data.SetOpaque (data_extractor_sp);
}
@@ -155,32 +212,44 @@ SBInstruction::GetData (SBTarget target)
bool
SBInstruction::DoesBranch ()
{
- if (m_opaque_sp)
- return m_opaque_sp->DoesBranch ();
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
+ return inst_sp->DoesBranch ();
return false;
}
bool
SBInstruction::HasDelaySlot ()
{
- if (m_opaque_sp)
- return m_opaque_sp->HasDelaySlot ();
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
+ return inst_sp->HasDelaySlot ();
return false;
}
+lldb::InstructionSP
+SBInstruction::GetOpaque ()
+{
+ if (m_opaque_sp)
+ return m_opaque_sp->GetSP();
+ else
+ return lldb::InstructionSP();
+}
+
void
-SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp)
+SBInstruction::SetOpaque (const lldb::DisassemblerSP &disasm_sp, const lldb::InstructionSP& inst_sp)
{
- m_opaque_sp = inst_sp;
+ m_opaque_sp.reset(new InstructionImpl(disasm_sp, inst_sp));
}
bool
SBInstruction::GetDescription (lldb::SBStream &s)
{
- if (m_opaque_sp)
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
{
SymbolContext sc;
- const Address &addr = m_opaque_sp->GetAddress();
+ const Address &addr = inst_sp->GetAddress();
ModuleSP module_sp (addr.GetModule());
if (module_sp)
module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
@@ -188,7 +257,7 @@ SBInstruction::GetDescription (lldb::SBStream &s)
// didn't have a stream already created, one will get created...
FormatEntity::Entry format;
FormatEntity::Parse("${addr}: ", format);
- m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, &sc, NULL, &format, 0);
+ inst_sp->Dump (&s.ref(), 0, true, false, NULL, &sc, NULL, &format, 0);
return true;
}
return false;
@@ -200,24 +269,26 @@ SBInstruction::Print (FILE *out)
if (out == NULL)
return;
- if (m_opaque_sp)
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
{
SymbolContext sc;
- const Address &addr = m_opaque_sp->GetAddress();
+ const Address &addr = inst_sp->GetAddress();
ModuleSP module_sp (addr.GetModule());
if (module_sp)
module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
StreamFile out_stream (out, false);
FormatEntity::Entry format;
FormatEntity::Parse("${addr}: ", format);
- m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, &sc, NULL, &format, 0);
+ inst_sp->Dump (&out_stream, 0, true, false, NULL, &sc, NULL, &format, 0);
}
}
bool
SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options)
{
- if (m_opaque_sp)
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
{
lldb::StackFrameSP frame_sp (frame.GetFrameSP());
@@ -228,13 +299,13 @@ SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options
lldb_private::Target *target = exe_ctx.GetTargetPtr();
lldb_private::ArchSpec arch = target->GetArchitecture();
- return m_opaque_sp->Emulate (arch,
- evaluate_options,
- (void *) frame_sp.get(),
- &lldb_private::EmulateInstruction::ReadMemoryFrame,
- &lldb_private::EmulateInstruction::WriteMemoryFrame,
- &lldb_private::EmulateInstruction::ReadRegisterFrame,
- &lldb_private::EmulateInstruction::WriteRegisterFrame);
+ return inst_sp->Emulate(arch,
+ evaluate_options,
+ (void *) frame_sp.get(),
+ &lldb_private::EmulateInstruction::ReadMemoryFrame,
+ &lldb_private::EmulateInstruction::WriteMemoryFrame,
+ &lldb_private::EmulateInstruction::ReadRegisterFrame,
+ &lldb_private::EmulateInstruction::WriteRegisterFrame);
}
}
return false;
@@ -243,29 +314,32 @@ SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options
bool
SBInstruction::DumpEmulation (const char *triple)
{
- if (m_opaque_sp && triple)
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp && triple)
{
lldb_private::ArchSpec arch (triple, NULL);
-
- return m_opaque_sp->DumpEmulation (arch);
-
+ return inst_sp->DumpEmulation (arch);
}
return false;
}
bool
-SBInstruction::TestEmulation (lldb::SBStream &output_stream, const char *test_file)
+SBInstruction::TestEmulation (lldb::SBStream &output_stream, const char *test_file)
{
- if (!m_opaque_sp.get())
- m_opaque_sp.reset (new PseudoInstruction());
-
- return m_opaque_sp->TestEmulation (output_stream.get(), test_file);
+ if (!m_opaque_sp)
+ SetOpaque(lldb::DisassemblerSP(), lldb::InstructionSP(new PseudoInstruction()));
+
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
+ return inst_sp->TestEmulation (output_stream.get(), test_file);
+ return false;
}
lldb::AddressClass
SBInstruction::GetAddressClass ()
{
- if (m_opaque_sp.get())
- return m_opaque_sp->GetAddressClass();
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
+ return inst_sp->GetAddressClass();
return eAddressClassInvalid;
}
diff --git a/source/API/SBInstructionList.cpp b/source/API/SBInstructionList.cpp
index 34b0e05079f8..9be38b483ebb 100644
--- a/source/API/SBInstructionList.cpp
+++ b/source/API/SBInstructionList.cpp
@@ -61,7 +61,7 @@ SBInstructionList::GetInstructionAtIndex (uint32_t idx)
{
SBInstruction inst;
if (m_opaque_sp && idx < m_opaque_sp->GetInstructionList().GetSize())
- inst.SetOpaque (m_opaque_sp->GetInstructionList().GetInstructionAtIndex (idx));
+ inst.SetOpaque (m_opaque_sp, m_opaque_sp->GetInstructionList().GetInstructionAtIndex (idx));
return inst;
}
diff --git a/source/API/SBListener.cpp b/source/API/SBListener.cpp
index 643c82d70f78..8e63de0b7698 100644
--- a/source/API/SBListener.cpp
+++ b/source/API/SBListener.cpp
@@ -26,27 +26,25 @@ using namespace lldb_private;
SBListener::SBListener () :
m_opaque_sp (),
- m_opaque_ptr (NULL)
+ m_unused_ptr (NULL)
{
}
SBListener::SBListener (const char *name) :
- m_opaque_sp (new Listener (name)),
- m_opaque_ptr (NULL)
+ m_opaque_sp (Listener::MakeListener(name)),
+ m_unused_ptr (nullptr)
{
- m_opaque_ptr = m_opaque_sp.get();
-
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
log->Printf ("SBListener::SBListener (name=\"%s\") => SBListener(%p)",
- name, static_cast<void*>(m_opaque_ptr));
+ name, static_cast<void*>(m_opaque_sp.get()));
}
SBListener::SBListener (const SBListener &rhs) :
m_opaque_sp (rhs.m_opaque_sp),
- m_opaque_ptr (rhs.m_opaque_ptr)
+ m_unused_ptr (nullptr)
{
}
@@ -56,20 +54,14 @@ SBListener::operator = (const lldb::SBListener &rhs)
if (this != &rhs)
{
m_opaque_sp = rhs.m_opaque_sp;
- m_opaque_ptr = rhs.m_opaque_ptr;
+ m_unused_ptr = nullptr;
}
return *this;
}
-SBListener::SBListener (Listener &listener) :
- m_opaque_sp (),
- m_opaque_ptr (&listener)
-{
-}
-
SBListener::SBListener (const lldb::ListenerSP &listener_sp) :
m_opaque_sp (listener_sp),
- m_opaque_ptr (listener_sp.get())
+ m_unused_ptr (nullptr)
{
}
@@ -80,7 +72,7 @@ SBListener::~SBListener ()
bool
SBListener::IsValid() const
{
- return m_opaque_ptr != NULL;
+ return m_opaque_sp != nullptr;
}
void
@@ -88,14 +80,14 @@ SBListener::AddEvent (const SBEvent &event)
{
EventSP &event_sp = event.GetSP ();
if (event_sp)
- m_opaque_ptr->AddEvent (event_sp);
+ m_opaque_sp->AddEvent (event_sp);
}
void
SBListener::Clear ()
{
- if (m_opaque_ptr)
- m_opaque_ptr->Clear ();
+ if (m_opaque_sp)
+ m_opaque_sp->Clear ();
}
uint32_t
@@ -103,13 +95,13 @@ SBListener::StartListeningForEventClass (SBDebugger &debugger,
const char *broadcaster_class,
uint32_t event_mask)
{
- if (m_opaque_ptr)
+ if (m_opaque_sp)
{
Debugger *lldb_debugger = debugger.get();
if (!lldb_debugger)
return 0;
BroadcastEventSpec event_spec (ConstString (broadcaster_class), event_mask);
- return m_opaque_ptr->StartListeningForEventSpec (*lldb_debugger, event_spec);
+ return m_opaque_sp->StartListeningForEventSpec (lldb_debugger->GetBroadcasterManager(), event_spec);
}
else
return 0;
@@ -120,13 +112,13 @@ SBListener::StopListeningForEventClass (SBDebugger &debugger,
const char *broadcaster_class,
uint32_t event_mask)
{
- if (m_opaque_ptr)
+ if (m_opaque_sp)
{
Debugger *lldb_debugger = debugger.get();
if (!lldb_debugger)
return false;
BroadcastEventSpec event_spec (ConstString (broadcaster_class), event_mask);
- return m_opaque_ptr->StopListeningForEventSpec (*lldb_debugger, event_spec);
+ return m_opaque_sp->StopListeningForEventSpec (lldb_debugger->GetBroadcasterManager(), event_spec);
}
else
return false;
@@ -136,9 +128,9 @@ uint32_t
SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask)
{
uint32_t acquired_event_mask = 0;
- if (m_opaque_ptr && broadcaster.IsValid())
+ if (m_opaque_sp && broadcaster.IsValid())
{
- acquired_event_mask = m_opaque_ptr->StartListeningForEvents (broadcaster.get(), event_mask);
+ acquired_event_mask = m_opaque_sp->StartListeningForEvents (broadcaster.get(), event_mask);
}
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
@@ -153,7 +145,7 @@ SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t
const bool got_requested_names = lldb_broadcaster->GetEventNames (sstr_requested, event_mask, false);
const bool got_acquired_names = lldb_broadcaster->GetEventNames (sstr_acquired, acquired_event_mask, false);
log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p): %s, event_mask=0x%8.8x%s%s%s) => 0x%8.8x%s%s%s",
- static_cast<void*>(m_opaque_ptr),
+ static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(lldb_broadcaster),
lldb_broadcaster->GetBroadcasterName().GetCString(),
event_mask,
@@ -168,7 +160,7 @@ SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t
else
{
log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p), event_mask=0x%8.8x) => 0x%8.8x",
- static_cast<void*>(m_opaque_ptr),
+ static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(lldb_broadcaster), event_mask,
acquired_event_mask);
}
@@ -180,9 +172,9 @@ SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t
bool
SBListener::StopListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask)
{
- if (m_opaque_ptr && broadcaster.IsValid())
+ if (m_opaque_sp && broadcaster.IsValid())
{
- return m_opaque_ptr->StopListeningForEvents (broadcaster.get(), event_mask);
+ return m_opaque_sp->StopListeningForEvents (broadcaster.get(), event_mask);
}
return false;
}
@@ -196,19 +188,19 @@ SBListener::WaitForEvent (uint32_t timeout_secs, SBEvent &event)
if (timeout_secs == UINT32_MAX)
{
log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p))...",
- static_cast<void*>(m_opaque_ptr),
+ static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(event.get()));
}
else
{
log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p))...",
- static_cast<void*>(m_opaque_ptr), timeout_secs,
+ static_cast<void*>(m_opaque_sp.get()), timeout_secs,
static_cast<void*>(event.get()));
}
}
bool success = false;
- if (m_opaque_ptr)
+ if (m_opaque_sp)
{
TimeValue time_value;
if (timeout_secs != UINT32_MAX)
@@ -218,7 +210,7 @@ SBListener::WaitForEvent (uint32_t timeout_secs, SBEvent &event)
time_value.OffsetWithSeconds (timeout_secs);
}
EventSP event_sp;
- if (m_opaque_ptr->WaitForEvent (time_value.IsValid() ? &time_value : NULL, event_sp))
+ if (m_opaque_sp->WaitForEvent (time_value.IsValid() ? &time_value : NULL, event_sp))
{
event.reset (event_sp);
success = true;
@@ -230,13 +222,13 @@ SBListener::WaitForEvent (uint32_t timeout_secs, SBEvent &event)
if (timeout_secs == UINT32_MAX)
{
log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p)) => %i",
- static_cast<void*>(m_opaque_ptr),
+ static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(event.get()), success);
}
else
{
log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p)) => %i",
- static_cast<void*>(m_opaque_ptr), timeout_secs,
+ static_cast<void*>(m_opaque_sp.get()), timeout_secs,
static_cast<void*>(event.get()), success);
}
}
@@ -253,7 +245,7 @@ SBListener::WaitForEventForBroadcaster
SBEvent &event
)
{
- if (m_opaque_ptr && broadcaster.IsValid())
+ if (m_opaque_sp && broadcaster.IsValid())
{
TimeValue time_value;
if (num_seconds != UINT32_MAX)
@@ -262,7 +254,7 @@ SBListener::WaitForEventForBroadcaster
time_value.OffsetWithSeconds (num_seconds);
}
EventSP event_sp;
- if (m_opaque_ptr->WaitForEventForBroadcaster (time_value.IsValid() ? &time_value : NULL,
+ if (m_opaque_sp->WaitForEventForBroadcaster (time_value.IsValid() ? &time_value : NULL,
broadcaster.get(),
event_sp))
{
@@ -284,7 +276,7 @@ SBListener::WaitForEventForBroadcasterWithType
SBEvent &event
)
{
- if (m_opaque_ptr && broadcaster.IsValid())
+ if (m_opaque_sp && broadcaster.IsValid())
{
TimeValue time_value;
if (num_seconds != UINT32_MAX)
@@ -293,7 +285,7 @@ SBListener::WaitForEventForBroadcasterWithType
time_value.OffsetWithSeconds (num_seconds);
}
EventSP event_sp;
- if (m_opaque_ptr->WaitForEventForBroadcasterWithType (time_value.IsValid() ? &time_value : NULL,
+ if (m_opaque_sp->WaitForEventForBroadcasterWithType (time_value.IsValid() ? &time_value : NULL,
broadcaster.get(),
event_type_mask,
event_sp))
@@ -309,9 +301,9 @@ SBListener::WaitForEventForBroadcasterWithType
bool
SBListener::PeekAtNextEvent (SBEvent &event)
{
- if (m_opaque_ptr)
+ if (m_opaque_sp)
{
- event.reset (m_opaque_ptr->PeekAtNextEvent ());
+ event.reset (m_opaque_sp->PeekAtNextEvent ());
return event.IsValid();
}
event.reset (NULL);
@@ -321,9 +313,9 @@ SBListener::PeekAtNextEvent (SBEvent &event)
bool
SBListener::PeekAtNextEventForBroadcaster (const SBBroadcaster &broadcaster, SBEvent &event)
{
- if (m_opaque_ptr && broadcaster.IsValid())
+ if (m_opaque_sp && broadcaster.IsValid())
{
- event.reset (m_opaque_ptr->PeekAtNextEventForBroadcaster (broadcaster.get()));
+ event.reset (m_opaque_sp->PeekAtNextEventForBroadcaster (broadcaster.get()));
return event.IsValid();
}
event.reset (NULL);
@@ -334,9 +326,9 @@ bool
SBListener::PeekAtNextEventForBroadcasterWithType (const SBBroadcaster &broadcaster, uint32_t event_type_mask,
SBEvent &event)
{
- if (m_opaque_ptr && broadcaster.IsValid())
+ if (m_opaque_sp && broadcaster.IsValid())
{
- event.reset(m_opaque_ptr->PeekAtNextEventForBroadcasterWithType (broadcaster.get(), event_type_mask));
+ event.reset(m_opaque_sp->PeekAtNextEventForBroadcasterWithType (broadcaster.get(), event_type_mask));
return event.IsValid();
}
event.reset (NULL);
@@ -346,10 +338,10 @@ SBListener::PeekAtNextEventForBroadcasterWithType (const SBBroadcaster &broadcas
bool
SBListener::GetNextEvent (SBEvent &event)
{
- if (m_opaque_ptr)
+ if (m_opaque_sp)
{
EventSP event_sp;
- if (m_opaque_ptr->GetNextEvent (event_sp))
+ if (m_opaque_sp->GetNextEvent (event_sp))
{
event.reset (event_sp);
return true;
@@ -362,10 +354,10 @@ SBListener::GetNextEvent (SBEvent &event)
bool
SBListener::GetNextEventForBroadcaster (const SBBroadcaster &broadcaster, SBEvent &event)
{
- if (m_opaque_ptr && broadcaster.IsValid())
+ if (m_opaque_sp && broadcaster.IsValid())
{
EventSP event_sp;
- if (m_opaque_ptr->GetNextEventForBroadcaster (broadcaster.get(), event_sp))
+ if (m_opaque_sp->GetNextEventForBroadcaster (broadcaster.get(), event_sp))
{
event.reset (event_sp);
return true;
@@ -383,10 +375,10 @@ SBListener::GetNextEventForBroadcasterWithType
SBEvent &event
)
{
- if (m_opaque_ptr && broadcaster.IsValid())
+ if (m_opaque_sp && broadcaster.IsValid())
{
EventSP event_sp;
- if (m_opaque_ptr->GetNextEventForBroadcasterWithType (broadcaster.get(),
+ if (m_opaque_sp->GetNextEventForBroadcasterWithType (broadcaster.get(),
event_type_mask,
event_sp))
{
@@ -401,49 +393,28 @@ SBListener::GetNextEventForBroadcasterWithType
bool
SBListener::HandleBroadcastEvent (const SBEvent &event)
{
- if (m_opaque_ptr)
- return m_opaque_ptr->HandleBroadcastEvent (event.GetSP());
+ if (m_opaque_sp)
+ return m_opaque_sp->HandleBroadcastEvent (event.GetSP());
return false;
}
Listener *
SBListener::operator->() const
{
- return m_opaque_ptr;
+ return m_opaque_sp.get();
}
Listener *
SBListener::get() const
{
- return m_opaque_ptr;
+ return m_opaque_sp.get();
}
void
-SBListener::reset(Listener *listener, bool owns)
-{
- if (owns)
- m_opaque_sp.reset (listener);
- else
- m_opaque_sp.reset ();
- m_opaque_ptr = listener;
-}
-
-Listener &
-SBListener::ref() const
-{
- return *m_opaque_ptr;
-}
-
-Listener &
-SBListener::operator *()
-{
- return *m_opaque_ptr;
-}
-
-const Listener &
-SBListener::operator *() const
+SBListener::reset(ListenerSP listener_sp)
{
- return *m_opaque_ptr;
+ m_opaque_sp = listener_sp;
+ m_unused_ptr = nullptr;
}
diff --git a/source/API/SBMemoryRegionInfo.cpp b/source/API/SBMemoryRegionInfo.cpp
new file mode 100644
index 000000000000..53b180787af9
--- /dev/null
+++ b/source/API/SBMemoryRegionInfo.cpp
@@ -0,0 +1,126 @@
+//===-- SBMemoryRegionInfo.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBMemoryRegionInfo.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+SBMemoryRegionInfo::SBMemoryRegionInfo () :
+ m_opaque_ap (new MemoryRegionInfo())
+{
+}
+
+SBMemoryRegionInfo::SBMemoryRegionInfo (const MemoryRegionInfo *lldb_object_ptr) :
+ m_opaque_ap (new MemoryRegionInfo())
+{
+ if (lldb_object_ptr)
+ ref() = *lldb_object_ptr;
+}
+
+SBMemoryRegionInfo::SBMemoryRegionInfo(const SBMemoryRegionInfo &rhs) :
+ m_opaque_ap (new MemoryRegionInfo())
+{
+ ref() = rhs.ref();
+}
+
+const SBMemoryRegionInfo &
+SBMemoryRegionInfo::operator = (const SBMemoryRegionInfo &rhs)
+{
+ if (this != &rhs)
+ {
+ ref() = rhs.ref();
+ }
+ return *this;
+}
+
+SBMemoryRegionInfo::~SBMemoryRegionInfo ()
+{
+}
+
+void
+SBMemoryRegionInfo::Clear()
+{
+ m_opaque_ap->Clear();
+}
+
+bool
+SBMemoryRegionInfo::operator == (const SBMemoryRegionInfo &rhs) const
+{
+ return ref() == rhs.ref();
+}
+
+bool
+SBMemoryRegionInfo::operator != (const SBMemoryRegionInfo &rhs) const
+{
+ return ref() != rhs.ref();
+}
+
+MemoryRegionInfo &
+SBMemoryRegionInfo::ref()
+{
+ return *m_opaque_ap;
+}
+
+const MemoryRegionInfo &
+SBMemoryRegionInfo::ref() const
+{
+ return *m_opaque_ap;
+}
+
+lldb::addr_t
+SBMemoryRegionInfo::GetRegionBase () {
+ return m_opaque_ap->GetRange().GetRangeBase();
+}
+
+lldb::addr_t
+SBMemoryRegionInfo::GetRegionEnd () {
+ return m_opaque_ap->GetRange().GetRangeEnd();
+}
+
+bool
+SBMemoryRegionInfo::IsReadable () {
+ return m_opaque_ap->GetReadable() == MemoryRegionInfo::eYes;
+}
+
+bool
+SBMemoryRegionInfo::IsWritable () {
+ return m_opaque_ap->GetWritable() == MemoryRegionInfo::eYes;
+}
+
+bool
+SBMemoryRegionInfo::IsExecutable () {
+ return m_opaque_ap->GetExecutable() == MemoryRegionInfo::eYes;
+}
+
+bool
+SBMemoryRegionInfo::IsMapped () {
+ return m_opaque_ap->GetMapped() == MemoryRegionInfo::eYes;
+}
+
+bool
+SBMemoryRegionInfo::GetDescription (SBStream &description)
+{
+ Stream &strm = description.ref();
+ const addr_t load_addr = m_opaque_ap->GetRange().base;
+
+ strm.Printf ("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 " ", load_addr, load_addr + m_opaque_ap->GetRange().size);
+ strm.Printf (m_opaque_ap->GetReadable() ? "R" : "-");
+ strm.Printf (m_opaque_ap->GetWritable() ? "W" : "-");
+ strm.Printf (m_opaque_ap->GetExecutable() ? "X" : "-");
+ strm.Printf ("]");
+
+ return true;
+}
diff --git a/source/API/SBMemoryRegionInfoList.cpp b/source/API/SBMemoryRegionInfoList.cpp
new file mode 100644
index 000000000000..b2e974785a5c
--- /dev/null
+++ b/source/API/SBMemoryRegionInfoList.cpp
@@ -0,0 +1,162 @@
+//===-- SBMemoryRegionInfoList.cpp ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBMemoryRegionInfo.h"
+#include "lldb/API/SBMemoryRegionInfoList.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+
+#include <vector>
+
+using namespace lldb;
+using namespace lldb_private;
+
+class MemoryRegionInfoListImpl
+{
+public:
+ MemoryRegionInfoListImpl () :
+ m_regions()
+ {
+ }
+
+ MemoryRegionInfoListImpl (const MemoryRegionInfoListImpl& rhs) :
+ m_regions(rhs.m_regions)
+ {
+ }
+
+ MemoryRegionInfoListImpl&
+ operator = (const MemoryRegionInfoListImpl& rhs)
+ {
+ if (this == &rhs)
+ return *this;
+ m_regions = rhs.m_regions;
+ return *this;
+ }
+
+ uint32_t
+ GetSize ()
+ {
+ return m_regions.size();
+ }
+
+ void
+ Append (const lldb::SBMemoryRegionInfo& sb_region)
+ {
+ m_regions.push_back(sb_region);
+ }
+
+ void
+ Append (const MemoryRegionInfoListImpl& list)
+ {
+ for (auto val : list.m_regions)
+ Append (val);
+ }
+
+ void
+ Clear ()
+ {
+ m_regions.clear();
+ }
+
+ bool
+ GetMemoryRegionInfoAtIndex (uint32_t index, SBMemoryRegionInfo &region_info)
+ {
+ if (index >= GetSize())
+ return false;
+ region_info = m_regions[index];
+ return true;
+ }
+
+private:
+ std::vector<lldb::SBMemoryRegionInfo> m_regions;
+};
+
+SBMemoryRegionInfoList::SBMemoryRegionInfoList () :
+ m_opaque_ap (new MemoryRegionInfoListImpl())
+{
+}
+
+SBMemoryRegionInfoList::SBMemoryRegionInfoList (const SBMemoryRegionInfoList& rhs) :
+ m_opaque_ap (new MemoryRegionInfoListImpl(*rhs.m_opaque_ap))
+{
+}
+
+SBMemoryRegionInfoList::~SBMemoryRegionInfoList ()
+{
+}
+
+const SBMemoryRegionInfoList &
+SBMemoryRegionInfoList::operator = (const SBMemoryRegionInfoList &rhs)
+{
+ if (this != &rhs)
+ {
+ *m_opaque_ap = *rhs.m_opaque_ap;
+ }
+ return *this;
+}
+
+uint32_t
+SBMemoryRegionInfoList::GetSize() const
+{
+ return m_opaque_ap->GetSize();
+}
+
+
+bool
+SBMemoryRegionInfoList::GetMemoryRegionAtIndex (uint32_t idx, SBMemoryRegionInfo &region_info)
+{
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+ bool result = m_opaque_ap->GetMemoryRegionInfoAtIndex(idx, region_info);
+
+ if (log)
+ {
+ SBStream sstr;
+ region_info.GetDescription (sstr);
+ log->Printf ("SBMemoryRegionInfoList::GetMemoryRegionAtIndex (this.ap=%p, idx=%d) => SBMemoryRegionInfo (this.ap=%p, '%s')",
+ static_cast<void*>(m_opaque_ap.get()), idx,
+ static_cast<void*>(region_info.m_opaque_ap.get()), sstr.GetData());
+ }
+
+ return result;
+}
+
+void
+SBMemoryRegionInfoList::Clear()
+{
+
+ m_opaque_ap->Clear();
+}
+
+void
+SBMemoryRegionInfoList::Append(SBMemoryRegionInfo &sb_region)
+{
+ m_opaque_ap->Append(sb_region);
+}
+
+void
+SBMemoryRegionInfoList::Append(SBMemoryRegionInfoList &sb_region_list)
+{
+ m_opaque_ap->Append(*sb_region_list);
+}
+
+const MemoryRegionInfoListImpl *
+SBMemoryRegionInfoList::operator->() const
+{
+ return m_opaque_ap.get();
+}
+
+const MemoryRegionInfoListImpl&
+SBMemoryRegionInfoList::operator*() const
+{
+ assert (m_opaque_ap.get());
+ return *m_opaque_ap.get();
+}
+
diff --git a/source/API/SBModule.cpp b/source/API/SBModule.cpp
index a810940f301f..bf015f7f2e58 100644
--- a/source/API/SBModule.cpp
+++ b/source/API/SBModule.cpp
@@ -21,6 +21,7 @@
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Symtab.h"
#include "lldb/Symbol/TypeSystem.h"
@@ -555,10 +556,12 @@ SBModule::FindTypes (const char *type)
TypeList type_list;
const bool exact_match = false;
ConstString name(type);
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
const uint32_t num_matches = module_sp->FindTypes (sc,
name,
exact_match,
UINT32_MAX,
+ searched_symbol_files,
type_list);
if (num_matches > 0)
diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp
index eea5fdca2b38..50211bfde329 100644
--- a/source/API/SBProcess.cpp
+++ b/source/API/SBProcess.cpp
@@ -23,6 +23,7 @@
#include "lldb/Core/State.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SystemRuntime.h"
@@ -36,6 +37,8 @@
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBMemoryRegionInfo.h"
+#include "lldb/API/SBMemoryRegionInfoList.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBThreadCollection.h"
#include "lldb/API/SBStream.h"
@@ -163,7 +166,7 @@ SBProcess::RemoteLaunch (char const **argv,
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
if (process_sp->GetState() == eStateConnected)
{
if (stop_at_entry)
@@ -209,7 +212,7 @@ SBProcess::RemoteAttachToProcessWithID (lldb::pid_t pid, lldb::SBError& error)
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
if (process_sp->GetState() == eStateConnected)
{
ProcessAttachInfo attach_info;
@@ -251,7 +254,7 @@ SBProcess::GetNumThreads ()
Process::StopLocker stop_locker;
const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
num_threads = process_sp->GetThreadList().GetSize(can_update);
}
@@ -272,7 +275,7 @@ SBProcess::GetSelectedThread () const
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
thread_sp = process_sp->GetThreadList().GetSelectedThread();
sb_thread.SetThread (thread_sp);
}
@@ -295,7 +298,7 @@ SBProcess::CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context)
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
thread_sp = process_sp->CreateOSPluginThread(tid, context);
sb_thread.SetThread (thread_sp);
}
@@ -465,7 +468,7 @@ SBProcess::SetSelectedThread (const SBThread &thread)
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
return process_sp->GetThreadList().SetSelectedThreadByID (thread.GetThreadID());
}
return false;
@@ -480,7 +483,7 @@ SBProcess::SetSelectedThreadByID (lldb::tid_t tid)
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
ret_val = process_sp->GetThreadList().SetSelectedThreadByID (tid);
}
@@ -501,7 +504,7 @@ SBProcess::SetSelectedThreadByIndexID (uint32_t index_id)
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
ret_val = process_sp->GetThreadList().SetSelectedThreadByIndexID (index_id);
}
@@ -525,7 +528,7 @@ SBProcess::GetThreadAtIndex (size_t index)
{
Process::StopLocker stop_locker;
const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
thread_sp = process_sp->GetThreadList().GetThreadAtIndex(index, can_update);
sb_thread.SetThread (thread_sp);
}
@@ -549,9 +552,11 @@ SBProcess::GetNumQueues ()
if (process_sp)
{
Process::StopLocker stop_locker;
-
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
- num_queues = process_sp->GetQueueList().GetSize();
+ if (stop_locker.TryLock(&process_sp->GetRunLock()))
+ {
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
+ num_queues = process_sp->GetQueueList().GetSize();
+ }
}
if (log)
@@ -572,9 +577,12 @@ SBProcess::GetQueueAtIndex (size_t index)
if (process_sp)
{
Process::StopLocker stop_locker;
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
- queue_sp = process_sp->GetQueueList().GetQueueAtIndex(index);
- sb_queue.SetQueue (queue_sp);
+ if (stop_locker.TryLock(&process_sp->GetRunLock()))
+ {
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
+ queue_sp = process_sp->GetQueueList().GetQueueAtIndex(index);
+ sb_queue.SetQueue (queue_sp);
+ }
}
if (log)
@@ -593,7 +601,7 @@ SBProcess::GetStopID(bool include_expression_stops)
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
if (include_expression_stops)
return process_sp->GetStopID();
else
@@ -612,7 +620,7 @@ SBProcess::GetStopEventForStopID(uint32_t stop_id)
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
event_sp = process_sp->GetStopEventForStopID(stop_id);
sb_event.reset(event_sp);
}
@@ -634,7 +642,7 @@ SBProcess::GetState ()
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
ret_val = process_sp->GetState();
}
@@ -655,7 +663,7 @@ SBProcess::GetExitStatus ()
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
exit_status = process_sp->GetExitStatus ();
}
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -674,7 +682,7 @@ SBProcess::GetExitDescription ()
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
exit_desc = process_sp->GetExitDescription ();
}
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -760,7 +768,7 @@ SBProcess::Continue ()
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
if (process_sp->GetTarget().GetDebugger().GetAsyncExecution ())
sb_error.ref() = process_sp->Resume ();
@@ -790,7 +798,7 @@ SBProcess::Destroy ()
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
sb_error.SetError(process_sp->Destroy(false));
}
else
@@ -817,7 +825,7 @@ SBProcess::Stop ()
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
sb_error.SetError (process_sp->Halt());
}
else
@@ -843,7 +851,7 @@ SBProcess::Kill ()
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
sb_error.SetError (process_sp->Destroy(true));
}
else
@@ -877,7 +885,7 @@ SBProcess::Detach (bool keep_stopped)
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
sb_error.SetError (process_sp->Detach(keep_stopped));
}
else
@@ -893,7 +901,7 @@ SBProcess::Signal (int signo)
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
sb_error.SetError (process_sp->Signal (signo));
}
else
@@ -939,7 +947,7 @@ SBProcess::GetThreadByID (tid_t tid)
{
Process::StopLocker stop_locker;
const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
thread_sp = process_sp->GetThreadList().FindThreadByID (tid, can_update);
sb_thread.SetThread (thread_sp);
}
@@ -963,7 +971,7 @@ SBProcess::GetThreadByIndexID (uint32_t index_id)
{
Process::StopLocker stop_locker;
const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
thread_sp = process_sp->GetThreadList().FindThreadByIndexID (index_id, can_update);
sb_thread.SetThread (thread_sp);
}
@@ -1080,7 +1088,7 @@ SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process_sp->GetRunLock()))
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
bytes_read = process_sp->ReadMemory (addr, dst, dst_len, sb_error.ref());
}
else
@@ -1120,7 +1128,7 @@ SBProcess::ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBE
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process_sp->GetRunLock()))
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
bytes_read = process_sp->ReadCStringFromMemory (addr, (char *)buf, size, sb_error.ref());
}
else
@@ -1149,7 +1157,7 @@ SBProcess::ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBErro
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process_sp->GetRunLock()))
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
value = process_sp->ReadUnsignedIntegerFromMemory (addr, byte_size, 0, sb_error.ref());
}
else
@@ -1178,7 +1186,7 @@ SBProcess::ReadPointerFromMemory (addr_t addr, lldb::SBError &sb_error)
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process_sp->GetRunLock()))
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
ptr = process_sp->ReadPointerFromMemory (addr, sb_error.ref());
}
else
@@ -1218,7 +1226,7 @@ SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &s
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process_sp->GetRunLock()))
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
bytes_written = process_sp->WriteMemory (addr, src, src_len, sb_error.ref());
}
else
@@ -1282,7 +1290,7 @@ SBProcess::GetNumSupportedHardwareWatchpoints (lldb::SBError &sb_error) const
ProcessSP process_sp(GetSP());
if (process_sp)
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
sb_error.SetError(process_sp->GetWatchpointSupportInfo (num));
if (log)
log->Printf ("SBProcess(%p)::GetNumSupportedHardwareWatchpoints () => %u",
@@ -1312,7 +1320,7 @@ SBProcess::LoadImage (const lldb::SBFileSpec &sb_local_image_spec,
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process_sp->GetRunLock()))
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
return platform_sp->LoadImage (process_sp.get(),
*sb_local_image_spec,
@@ -1341,7 +1349,7 @@ SBProcess::UnloadImage (uint32_t image_token)
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process_sp->GetRunLock()))
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
sb_error.SetError (platform_sp->UnloadImage (process_sp.get(), image_token));
}
@@ -1369,7 +1377,7 @@ SBProcess::SendEventData (const char *event_data)
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process_sp->GetRunLock()))
{
- Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
sb_error.SetError (process_sp->SendEventData (event_data));
}
else
@@ -1459,7 +1467,7 @@ SBProcess::SaveCore(const char *file_name)
return error;
}
- Mutex::Locker api_locker(process_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
if (process_sp->GetState() != eStateStopped)
{
@@ -1471,3 +1479,74 @@ SBProcess::SaveCore(const char *file_name)
error.ref() = PluginManager::SaveCore(process_sp, core_file);
return error;
}
+
+lldb::SBError
+SBProcess::GetMemoryRegionInfo (lldb::addr_t load_addr, SBMemoryRegionInfo &sb_region_info)
+{
+ lldb::SBError sb_error;
+ ProcessSP process_sp(GetSP());
+ MemoryRegionInfoSP region_info_sp = std::make_shared<lldb_private::MemoryRegionInfo>();
+ if (process_sp)
+ {
+ Process::StopLocker stop_locker;
+ if (stop_locker.TryLock(&process_sp->GetRunLock()))
+ {
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
+ sb_error.ref() = process_sp->GetMemoryRegionInfo(load_addr, *region_info_sp);
+ if( sb_error.Success() ) {
+ sb_region_info.ref() = *region_info_sp;
+ }
+ }
+ else
+ {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ log->Printf ("SBProcess(%p)::GetMemoryRegionInfo() => error: process is running",
+ static_cast<void*>(process_sp.get()));
+ sb_error.SetErrorString("process is running");
+ }
+ }
+ else
+ {
+ sb_error.SetErrorString ("SBProcess is invalid");
+ }
+ return sb_error;
+}
+
+lldb::SBMemoryRegionInfoList
+SBProcess::GetMemoryRegions()
+{
+ lldb::SBError sb_error;
+ lldb::SBMemoryRegionInfoList sb_region_list;
+ ProcessSP process_sp(GetSP());
+ if (process_sp)
+ {
+ Process::StopLocker stop_locker;
+ if (stop_locker.TryLock(&process_sp->GetRunLock()))
+ {
+ std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
+ std::vector<MemoryRegionInfoSP> region_list;
+ sb_error.ref() = process_sp->GetMemoryRegions(region_list);
+ if( sb_error.Success() ) {
+ std::vector<MemoryRegionInfoSP>::iterator end = region_list.end();
+ for( std::vector<MemoryRegionInfoSP>::iterator it = region_list.begin(); it != end; it++ ) {
+ SBMemoryRegionInfo sb_region_info(it->get());
+ sb_region_list.Append(sb_region_info);
+ }
+ }
+ }
+ else
+ {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ log->Printf ("SBProcess(%p)::GetMemoryRegionInfo() => error: process is running",
+ static_cast<void*>(process_sp.get()));
+ sb_error.SetErrorString("process is running");
+ }
+ }
+ else
+ {
+ sb_error.SetErrorString ("SBProcess is invalid");
+ }
+ return sb_region_list;
+}
diff --git a/source/API/SBStringList.cpp b/source/API/SBStringList.cpp
index 129d2f4c11f0..f469bc4336fc 100644
--- a/source/API/SBStringList.cpp
+++ b/source/API/SBStringList.cpp
@@ -126,6 +126,16 @@ SBStringList::GetStringAtIndex (size_t idx)
return NULL;
}
+const char *
+SBStringList::GetStringAtIndex (size_t idx) const
+{
+ if (IsValid())
+ {
+ return m_opaque_ap->GetStringAtIndex (idx);
+ }
+ return NULL;
+}
+
void
SBStringList::Clear ()
{
diff --git a/source/API/SBSymbol.cpp b/source/API/SBSymbol.cpp
index 22d1e546b5ee..0dbed1238b8c 100644
--- a/source/API/SBSymbol.cpp
+++ b/source/API/SBSymbol.cpp
@@ -141,12 +141,13 @@ SBSymbol::GetInstructions (SBTarget target, const char *flavor_string)
SBInstructionList sb_instructions;
if (m_opaque_ptr)
{
- Mutex::Locker api_locker;
ExecutionContext exe_ctx;
TargetSP target_sp (target.GetSP());
+ std::unique_lock<std::recursive_mutex> lock;
if (target_sp)
{
- api_locker.Lock (target_sp->GetAPIMutex());
+ lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
+
target_sp->CalculateExecutionContext (exe_ctx);
}
if (m_opaque_ptr->ValueIsAddress())
diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp
index c7595c3c39fb..6a5301b06053 100644
--- a/source/API/SBTarget.cpp
+++ b/source/API/SBTarget.cpp
@@ -22,6 +22,7 @@
#include "lldb/API/SBSourceManager.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStringList.h"
#include "lldb/API/SBSymbolContextList.h"
#include "lldb/Breakpoint/BreakpointID.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
@@ -49,6 +50,7 @@
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
@@ -75,7 +77,7 @@ namespace {
Error
AttachToProcess (ProcessAttachInfo &attach_info, Target &target)
{
- Mutex::Locker api_locker (target.GetAPIMutex ());
+ std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
auto process_sp = target.GetProcessSP ();
if (process_sp)
@@ -265,7 +267,7 @@ SBTarget::Install()
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
sb_error.ref() = target_sp->Install(NULL);
}
return sb_error;
@@ -305,7 +307,7 @@ SBTarget::Launch
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
if (stop_at_entry)
launch_flags |= eLaunchFlagStopAtEntry;
@@ -372,9 +374,8 @@ SBTarget::Launch
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
if (log)
- log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)",
- static_cast<void*>(target_sp.get()),
- static_cast<void*>(sb_process.GetSP().get()));
+ log->Printf("SBTarget(%p)::Launch (...) => SBProcess(%p), SBError(%s)", static_cast<void *>(target_sp.get()),
+ static_cast<void *>(sb_process.GetSP().get()), error.GetCString());
return sb_process;
}
@@ -393,7 +394,7 @@ SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error)
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
StateType state = eStateInvalid;
{
ProcessSP process_sp = target_sp->GetProcessSP();
@@ -621,9 +622,9 @@ SBTarget::ConnectRemote
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
if (listener.IsValid())
- process_sp = target_sp->CreateProcess (listener.ref(), plugin_name, NULL);
+ process_sp = target_sp->CreateProcess (listener.m_opaque_sp, plugin_name, NULL);
else
process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), plugin_name, NULL);
@@ -705,7 +706,7 @@ SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr)
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
if (target_sp->ResolveLoadAddress (vm_addr, addr))
return sb_addr;
}
@@ -724,7 +725,7 @@ SBTarget::ResolveFileAddress (lldb::addr_t file_addr)
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
if (target_sp->ResolveFileAddress (file_addr, addr))
return sb_addr;
}
@@ -741,7 +742,7 @@ SBTarget::ResolvePastLoadAddress (uint32_t stop_id, lldb::addr_t vm_addr)
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
if (target_sp->ResolveLoadAddress (vm_addr, addr))
return sb_addr;
}
@@ -777,7 +778,7 @@ SBTarget::ReadMemory (const SBAddress addr,
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
bytes_read = target_sp->ReadMemory(addr.ref(), false, buf, size, sb_error.ref());
}
else
@@ -799,20 +800,36 @@ SBBreakpoint
SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec,
uint32_t line)
{
+ return BreakpointCreateByLocation(sb_file_spec, line, 0);
+}
+
+SBBreakpoint
+SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec,
+ uint32_t line,
+ lldb::addr_t offset)
+{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBBreakpoint sb_bp;
TargetSP target_sp(GetSP());
if (target_sp && line != 0)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
const LazyBool check_inlines = eLazyBoolCalculate;
const LazyBool skip_prologue = eLazyBoolCalculate;
const bool internal = false;
const bool hardware = false;
const LazyBool move_to_nearest_code = eLazyBoolCalculate;
- *sb_bp = target_sp->CreateBreakpoint (NULL, *sb_file_spec, line, check_inlines, skip_prologue, internal, hardware, move_to_nearest_code);
+ *sb_bp = target_sp->CreateBreakpoint (NULL,
+ *sb_file_spec,
+ line,
+ offset,
+ check_inlines,
+ skip_prologue,
+ internal,
+ hardware,
+ move_to_nearest_code);
}
if (log)
@@ -839,20 +856,21 @@ SBTarget::BreakpointCreateByName (const char *symbol_name,
TargetSP target_sp(GetSP());
if (target_sp.get())
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
const bool internal = false;
const bool hardware = false;
const LazyBool skip_prologue = eLazyBoolCalculate;
+ const lldb::addr_t offset = 0;
if (module_name && module_name[0])
{
FileSpecList module_spec_list;
module_spec_list.Append (FileSpec (module_name, false));
- *sb_bp = target_sp->CreateBreakpoint (&module_spec_list, NULL, symbol_name, eFunctionNameTypeAuto, eLanguageTypeUnknown, skip_prologue, internal, hardware);
+ *sb_bp = target_sp->CreateBreakpoint (&module_spec_list, NULL, symbol_name, eFunctionNameTypeAuto, eLanguageTypeUnknown, offset, skip_prologue, internal, hardware);
}
else
{
- *sb_bp = target_sp->CreateBreakpoint (NULL, NULL, symbol_name, eFunctionNameTypeAuto, eLanguageTypeUnknown, skip_prologue, internal, hardware);
+ *sb_bp = target_sp->CreateBreakpoint (NULL, NULL, symbol_name, eFunctionNameTypeAuto, eLanguageTypeUnknown, offset, skip_prologue, internal, hardware);
}
}
@@ -898,12 +916,13 @@ SBTarget::BreakpointCreateByName (const char *symbol_name,
const bool internal = false;
const bool hardware = false;
const LazyBool skip_prologue = eLazyBoolCalculate;
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
*sb_bp = target_sp->CreateBreakpoint (module_list.get(),
comp_unit_list.get(),
symbol_name,
name_type_mask,
symbol_language,
+ 0,
skip_prologue,
internal,
hardware);
@@ -935,13 +954,25 @@ SBTarget::BreakpointCreateByNames (const char *symbol_names[],
const SBFileSpecList &module_list,
const SBFileSpecList &comp_unit_list)
{
+ return BreakpointCreateByNames(symbol_names, num_names, name_type_mask, eLanguageTypeUnknown, 0, module_list, comp_unit_list);
+}
+
+lldb::SBBreakpoint
+SBTarget::BreakpointCreateByNames (const char *symbol_names[],
+ uint32_t num_names,
+ uint32_t name_type_mask,
+ LanguageType symbol_language,
+ lldb::addr_t offset,
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &comp_unit_list)
+{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBBreakpoint sb_bp;
TargetSP target_sp(GetSP());
if (target_sp && num_names > 0)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
const bool internal = false;
const bool hardware = false;
const LazyBool skip_prologue = eLazyBoolCalculate;
@@ -949,8 +980,9 @@ SBTarget::BreakpointCreateByNames (const char *symbol_names[],
comp_unit_list.get(),
symbol_names,
num_names,
- name_type_mask,
+ name_type_mask,
symbol_language,
+ offset,
skip_prologue,
internal,
hardware);
@@ -1013,7 +1045,7 @@ SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex,
TargetSP target_sp(GetSP());
if (target_sp && symbol_name_regex && symbol_name_regex[0])
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
RegularExpression regexp(symbol_name_regex);
const bool internal = false;
const bool hardware = false;
@@ -1039,7 +1071,7 @@ SBTarget::BreakpointCreateByAddress (addr_t address)
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
const bool hardware = false;
*sb_bp = target_sp->CreateBreakpoint (address, false, hardware);
}
@@ -1070,7 +1102,7 @@ SBTarget::BreakpointCreateBySBAddress (SBAddress &sb_address)
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
const bool hardware = false;
*sb_bp = target_sp->CreateBreakpoint (sb_address.ref(), false, hardware);
}
@@ -1093,42 +1125,21 @@ SBTarget::BreakpointCreateBySourceRegex (const char *source_regex,
const lldb::SBFileSpec &source_file,
const char *module_name)
{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-
- SBBreakpoint sb_bp;
- TargetSP target_sp(GetSP());
- if (target_sp && source_regex && source_regex[0])
- {
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
- RegularExpression regexp(source_regex);
- FileSpecList source_file_spec_list;
- const bool hardware = false;
- const LazyBool move_to_nearest_code = eLazyBoolCalculate;
- source_file_spec_list.Append (source_file.ref());
+ SBFileSpecList module_spec_list;
if (module_name && module_name[0])
{
- FileSpecList module_spec_list;
module_spec_list.Append (FileSpec (module_name, false));
-
- *sb_bp = target_sp->CreateSourceRegexBreakpoint (&module_spec_list, &source_file_spec_list, regexp, false, hardware, move_to_nearest_code);
}
- else
+
+ SBFileSpecList source_file_list;
+ if (source_file.IsValid())
{
- *sb_bp = target_sp->CreateSourceRegexBreakpoint (NULL, &source_file_spec_list, regexp, false, hardware, move_to_nearest_code);
+ source_file_list.Append(source_file);
}
- }
-
- if (log)
- {
- char path[PATH_MAX];
- source_file->GetPath (path, sizeof(path));
- log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\", file=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)",
- static_cast<void*>(target_sp.get()), source_regex, path,
- module_name, static_cast<void*>(sb_bp.get()));
- }
+
+ return BreakpointCreateBySourceRegex (source_regex, module_spec_list, source_file_list);
- return sb_bp;
}
lldb::SBBreakpoint
@@ -1136,17 +1147,38 @@ SBTarget::BreakpointCreateBySourceRegex (const char *source_regex,
const SBFileSpecList &module_list,
const lldb::SBFileSpecList &source_file_list)
{
+ return BreakpointCreateBySourceRegex(source_regex, module_list, source_file_list, SBStringList());
+}
+
+lldb::SBBreakpoint
+SBTarget::BreakpointCreateBySourceRegex (const char *source_regex,
+ const SBFileSpecList &module_list,
+ const lldb::SBFileSpecList &source_file_list,
+ const SBStringList &func_names)
+{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBBreakpoint sb_bp;
TargetSP target_sp(GetSP());
if (target_sp && source_regex && source_regex[0])
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
const bool hardware = false;
const LazyBool move_to_nearest_code = eLazyBoolCalculate;
RegularExpression regexp(source_regex);
- *sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(), source_file_list.get(), regexp, false, hardware, move_to_nearest_code);
+ std::unordered_set<std::string> func_names_set;
+ for (size_t i = 0; i < func_names.GetSize(); i++)
+ {
+ func_names_set.insert(func_names.GetStringAtIndex(i));
+ }
+
+ *sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(),
+ source_file_list.get(),
+ func_names_set,
+ regexp,
+ false,
+ hardware,
+ move_to_nearest_code);
}
if (log)
@@ -1168,7 +1200,7 @@ SBTarget::BreakpointCreateForException (lldb::LanguageType language,
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
const bool hardware = false;
*sb_bp = target_sp->CreateExceptionBreakpoint (language, catch_bp, throw_bp, hardware);
}
@@ -1217,7 +1249,7 @@ SBTarget::BreakpointDelete (break_id_t bp_id)
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
result = target_sp->RemoveBreakpointByID (bp_id);
}
@@ -1238,7 +1270,7 @@ SBTarget::FindBreakpointByID (break_id_t bp_id)
TargetSP target_sp(GetSP());
if (target_sp && bp_id != LLDB_INVALID_BREAK_ID)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
*sb_breakpoint = target_sp->GetBreakpointByID (bp_id);
}
@@ -1257,7 +1289,7 @@ SBTarget::EnableAllBreakpoints ()
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
target_sp->EnableAllBreakpoints ();
return true;
}
@@ -1270,7 +1302,7 @@ SBTarget::DisableAllBreakpoints ()
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
target_sp->DisableAllBreakpoints ();
return true;
}
@@ -1283,7 +1315,7 @@ SBTarget::DeleteAllBreakpoints ()
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
target_sp->RemoveAllBreakpoints ();
return true;
}
@@ -1324,9 +1356,9 @@ SBTarget::DeleteWatchpoint (watch_id_t wp_id)
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
- Mutex::Locker locker;
- target_sp->GetWatchpointList().GetListMutex(locker);
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+ std::unique_lock<std::recursive_mutex> lock;
+ target_sp->GetWatchpointList().GetListMutex(lock);
result = target_sp->RemoveWatchpointByID (wp_id);
}
@@ -1348,9 +1380,9 @@ SBTarget::FindWatchpointByID (lldb::watch_id_t wp_id)
TargetSP target_sp(GetSP());
if (target_sp && wp_id != LLDB_INVALID_WATCH_ID)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
- Mutex::Locker locker;
- target_sp->GetWatchpointList().GetListMutex(locker);
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+ std::unique_lock<std::recursive_mutex> lock;
+ target_sp->GetWatchpointList().GetListMutex(lock);
watchpoint_sp = target_sp->GetWatchpointList().FindByID(wp_id);
sb_watchpoint.SetSP (watchpoint_sp);
}
@@ -1374,7 +1406,7 @@ SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, S
TargetSP target_sp(GetSP());
if (target_sp && (read || write) && addr != LLDB_INVALID_ADDRESS && size > 0)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
uint32_t watch_type = 0;
if (read)
watch_type |= LLDB_WATCH_TYPE_READ;
@@ -1410,9 +1442,9 @@ SBTarget::EnableAllWatchpoints ()
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
- Mutex::Locker locker;
- target_sp->GetWatchpointList().GetListMutex(locker);
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+ std::unique_lock<std::recursive_mutex> lock;
+ target_sp->GetWatchpointList().GetListMutex(lock);
target_sp->EnableAllWatchpoints ();
return true;
}
@@ -1425,9 +1457,9 @@ SBTarget::DisableAllWatchpoints ()
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
- Mutex::Locker locker;
- target_sp->GetWatchpointList().GetListMutex(locker);
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+ std::unique_lock<std::recursive_mutex> lock;
+ target_sp->GetWatchpointList().GetListMutex(lock);
target_sp->DisableAllWatchpoints ();
return true;
}
@@ -1519,9 +1551,9 @@ SBTarget::DeleteAllWatchpoints ()
TargetSP target_sp(GetSP());
if (target_sp)
{
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
- Mutex::Locker locker;
- target_sp->GetWatchpointList().GetListMutex(locker);
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+ std::unique_lock<std::recursive_mutex> lock;
+ target_sp->GetWatchpointList().GetListMutex(lock);
target_sp->RemoveAllWatchpoints ();
return true;
}
@@ -1894,11 +1926,12 @@ SBTarget::FindTypes (const char* typename_cstr)
bool exact_match = false;
SymbolContext sc;
TypeList type_list;
-
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
uint32_t num_matches = images.FindTypes (sc,
const_typename,
exact_match,
UINT32_MAX,
+ searched_symbol_files,
type_list);
if (num_matches > 0)
@@ -2171,6 +2204,13 @@ SBTarget::SetSectionLoadAddress (lldb::SBSection section,
ProcessSP process_sp (target_sp->GetProcessSP());
if (target_sp->SetSectionLoadAddress (section_sp, section_base_addr))
{
+ ModuleSP module_sp(section_sp->GetModule());
+ if (module_sp)
+ {
+ ModuleList module_list;
+ module_list.Append(module_sp);
+ target_sp->ModulesDidLoad (module_list);
+ }
// Flush info in the process (stack frames, etc)
if (process_sp)
process_sp->Flush();
@@ -2200,12 +2240,27 @@ SBTarget::ClearSectionLoadAddress (lldb::SBSection section)
}
else
{
- ProcessSP process_sp (target_sp->GetProcessSP());
- if (target_sp->SetSectionUnloaded (section.GetSP()))
+ SectionSP section_sp (section.GetSP());
+ if (section_sp)
+ {
+ ProcessSP process_sp (target_sp->GetProcessSP());
+ if (target_sp->SetSectionUnloaded(section_sp))
+ {
+ ModuleSP module_sp(section_sp->GetModule());
+ if (module_sp)
+ {
+ ModuleList module_list;
+ module_list.Append(module_sp);
+ target_sp->ModulesDidUnload(module_list, false);
+ }
+ // Flush info in the process (stack frames, etc)
+ if (process_sp)
+ process_sp->Flush();
+ }
+ }
+ else
{
- // Flush info in the process (stack frames, etc)
- if (process_sp)
- process_sp->Flush();
+ sb_error.SetErrorStringWithFormat ("invalid section");
}
}
}
@@ -2287,6 +2342,9 @@ SBTarget::ClearModuleLoadAddress (lldb::SBModule module)
}
if (changed)
{
+ ModuleList module_list;
+ module_list.Append(module_sp);
+ target_sp->ModulesDidUnload(module_list, false);
// Flush info in the process (stack frames, etc)
ProcessSP process_sp (target_sp->GetProcessSP());
if (process_sp)
@@ -2356,7 +2414,9 @@ lldb::SBValue
SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &options)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+#if !defined(LLDB_DISABLE_PYTHON)
Log * expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+#endif
SBValue expr_result;
ExpressionResults exe_results = eExpressionSetupError;
ValueObjectSP expr_value_sp;
@@ -2371,7 +2431,7 @@ SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &optio
return expr_result;
}
- Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
ExecutionContext exe_ctx (m_opaque_sp.get());
if (log)
diff --git a/source/API/SBThread.cpp b/source/API/SBThread.cpp
index 2f3887ebce3a..47cf80ef29ce 100644
--- a/source/API/SBThread.cpp
+++ b/source/API/SBThread.cpp
@@ -35,12 +35,12 @@
#include "lldb/Target/ThreadPlanStepRange.h"
#include "lldb/Target/ThreadPlanStepInRange.h"
-
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBThreadCollection.h"
#include "lldb/API/SBThreadPlan.h"
#include "lldb/API/SBValue.h"
@@ -96,8 +96,8 @@ SBThread::GetQueue () const
{
SBQueue sb_queue;
QueueSP queue_sp;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (exe_ctx.HasThreadScope())
@@ -130,7 +130,19 @@ SBThread::GetQueue () const
bool
SBThread::IsValid() const
{
- return m_opaque_sp->GetThreadSP().get() != NULL;
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
+ Target *target = exe_ctx.GetTargetPtr();
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
+ {
+ Process::StopLocker stop_locker;
+ if (stop_locker.TryLock(&process->GetRunLock()))
+ return m_opaque_sp->GetThreadSP().get() != NULL;
+ }
+ // Without a valid target & process, this thread can't be valid.
+ return false;
}
void
@@ -146,8 +158,8 @@ SBThread::GetStopReason()
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
StopReason reason = eStopReasonInvalid;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope())
{
@@ -175,8 +187,8 @@ SBThread::GetStopReason()
size_t
SBThread::GetStopReasonDataCount ()
{
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope())
{
@@ -235,8 +247,8 @@ SBThread::GetStopReasonDataCount ()
uint64_t
SBThread::GetStopReasonDataAtIndex (uint32_t idx)
{
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope())
{
@@ -313,7 +325,9 @@ SBThread::GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream)
{
Stream &strm = stream.ref();
- ExecutionContext exe_ctx (m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
if (! exe_ctx.HasThreadScope())
return false;
@@ -328,13 +342,39 @@ SBThread::GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream)
return true;
}
+SBThreadCollection
+SBThread::GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type)
+{
+ ThreadCollectionSP threads;
+ threads.reset(new ThreadCollection());
+
+ // We currently only support ThreadSanitizer.
+ if (type != eInstrumentationRuntimeTypeThreadSanitizer)
+ return threads;
+
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
+ if (! exe_ctx.HasThreadScope())
+ return threads;
+
+ ProcessSP process_sp = exe_ctx.GetProcessSP();
+
+ StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
+ StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
+ if (! info)
+ return threads;
+
+ return process_sp->GetInstrumentationRuntime(type)->GetBacktracesFromExtendedStopInfo(info);
+}
+
size_t
SBThread::GetStopDescription (char *dst, size_t dst_len)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope())
{
@@ -465,8 +505,8 @@ SBThread::GetStopReturnValue ()
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
ValueObjectSP return_valobj_sp;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope())
{
@@ -526,8 +566,8 @@ SBThread::GetName () const
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
const char *name = NULL;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope())
{
@@ -556,8 +596,8 @@ const char *
SBThread::GetQueueName () const
{
const char *name = NULL;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (exe_ctx.HasThreadScope())
@@ -587,8 +627,8 @@ lldb::queue_id_t
SBThread::GetQueueID () const
{
queue_id_t id = LLDB_INVALID_QUEUE_ID;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (exe_ctx.HasThreadScope())
@@ -618,8 +658,8 @@ SBThread::GetInfoItemByPathAsString (const char *path, SBStream &strm)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
bool success = false;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope())
{
@@ -724,9 +764,8 @@ SBThread::StepOver (lldb::RunMode stop_other_threads)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
-
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (log)
log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')",
@@ -774,10 +813,17 @@ SBThread::StepInto (lldb::RunMode stop_other_threads)
void
SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
{
+ SBError error;
+ StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
+}
+
+void
+SBThread::StepInto (const char *target_name, uint32_t end_line, SBError &error, lldb::RunMode stop_other_threads)
+{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (log)
log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
@@ -795,11 +841,20 @@ SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
if (frame_sp && frame_sp->HasDebugInformation ())
{
+ SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
+ AddressRange range;
+ if (end_line == LLDB_INVALID_LINE_NUMBER)
+ range = sc.line_entry.range;
+ else
+ {
+ if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
+ return;
+ }
+
const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate;
const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate;
- SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
- sc.line_entry,
+ range,
sc,
target_name,
stop_other_threads,
@@ -813,8 +868,7 @@ SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
stop_other_threads);
}
- // This returns an error, we should use it!
- ResumeNewPlan (exe_ctx, new_plan_sp.get());
+ error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
}
}
@@ -823,8 +877,8 @@ SBThread::StepOut ()
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (log)
log->Printf ("SBThread(%p)::StepOut ()",
@@ -857,8 +911,8 @@ SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (!sb_frame.IsValid())
{
@@ -910,10 +964,8 @@ SBThread::StepInstruction (bool step_over)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
-
-
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (log)
log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)",
@@ -934,9 +986,8 @@ SBThread::RunToAddress (lldb::addr_t addr)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
-
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (log)
log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
@@ -969,8 +1020,8 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
char path[PATH_MAX];
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
StackFrameSP frame_sp (sb_frame.GetFrameSP());
@@ -1113,8 +1164,8 @@ SBThread::StepUsingScriptedThreadPlan (const char *script_class_name)
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBError sb_error;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (log)
{
@@ -1153,8 +1204,8 @@ SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBError sb_error;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (log)
log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)",
@@ -1181,9 +1232,8 @@ SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
-
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (log)
log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)",
@@ -1199,12 +1249,39 @@ SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
return sb_error;
}
+SBError
+SBThread::UnwindInnermostExpression()
+{
+ SBError sb_error;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
+ if (log)
+ log->Printf ("SBThread(%p)::UnwindExpressionEvaluation",
+ static_cast<void*>(exe_ctx.GetThreadPtr()));
+
+ if (exe_ctx.HasThreadScope())
+ {
+ Thread *thread = exe_ctx.GetThreadPtr();
+ sb_error.SetError (thread->UnwindInnermostExpression());
+ if (sb_error.Success())
+ thread->SetSelectedFrameByIndex(0, false);
+ }
+
+ return sb_error;
+
+}
bool
SBThread::Suspend()
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- ExecutionContext exe_ctx (m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
bool result = false;
if (exe_ctx.HasThreadScope())
{
@@ -1231,7 +1308,9 @@ bool
SBThread::Resume ()
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- ExecutionContext exe_ctx (m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
bool result = false;
if (exe_ctx.HasThreadScope())
{
@@ -1258,7 +1337,9 @@ SBThread::Resume ()
bool
SBThread::IsSuspended()
{
- ExecutionContext exe_ctx (m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
if (exe_ctx.HasThreadScope())
return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
return false;
@@ -1267,7 +1348,9 @@ SBThread::IsSuspended()
bool
SBThread::IsStopped()
{
- ExecutionContext exe_ctx (m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
if (exe_ctx.HasThreadScope())
return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
return false;
@@ -1277,7 +1360,9 @@ SBProcess
SBThread::GetProcess ()
{
SBProcess sb_process;
- ExecutionContext exe_ctx (m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
if (exe_ctx.HasThreadScope())
{
// Have to go up to the target so we can get a shared pointer to our process...
@@ -1304,8 +1389,8 @@ SBThread::GetNumFrames ()
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
uint32_t num_frames = 0;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope())
{
@@ -1336,8 +1421,8 @@ SBThread::GetFrameAtIndex (uint32_t idx)
SBFrame sb_frame;
StackFrameSP frame_sp;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope())
{
@@ -1375,8 +1460,8 @@ SBThread::GetSelectedFrame ()
SBFrame sb_frame;
StackFrameSP frame_sp;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope())
{
@@ -1414,8 +1499,8 @@ SBThread::SetSelectedFrame (uint32_t idx)
SBFrame sb_frame;
StackFrameSP frame_sp;
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
if (exe_ctx.HasThreadScope())
{
@@ -1486,7 +1571,9 @@ SBThread::GetStatus (SBStream &status) const
{
Stream &strm = status.ref();
- ExecutionContext exe_ctx (m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
if (exe_ctx.HasThreadScope())
{
exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
@@ -1502,7 +1589,9 @@ SBThread::GetDescription (SBStream &description) const
{
Stream &strm = description.ref();
- ExecutionContext exe_ctx (m_opaque_sp.get());
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
if (exe_ctx.HasThreadScope())
{
exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, LLDB_INVALID_THREAD_ID);
@@ -1518,8 +1607,8 @@ SBThread
SBThread::GetExtendedBacktraceThread (const char *type)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- Mutex::Locker api_locker;
- ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
SBThread sb_origin_thread;
if (exe_ctx.HasThreadScope())
diff --git a/source/API/SBValue.cpp b/source/API/SBValue.cpp
index a8584c5d38c9..4fdcb0d5ecbf 100644
--- a/source/API/SBValue.cpp
+++ b/source/API/SBValue.cpp
@@ -127,7 +127,7 @@ public:
}
lldb::ValueObjectSP
- GetSP (Process::StopLocker &stop_locker, Mutex::Locker &api_locker, Error &error)
+ GetSP(Process::StopLocker &stop_locker, std::unique_lock<std::recursive_mutex> &lock, Error &error)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (!m_valobj_sp)
@@ -139,11 +139,11 @@ public:
lldb::ValueObjectSP value_sp = m_valobj_sp;
Target *target = value_sp->GetTargetSP().get();
- if (target)
- api_locker.Lock(target->GetAPIMutex());
- else
+ if (!target)
return ValueObjectSP();
+ lock = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex());
+
ProcessSP process_sp(value_sp->GetProcessSP());
if (process_sp && !stop_locker.TryLock (&process_sp->GetRunLock()))
{
@@ -255,13 +255,13 @@ public:
ValueLocker ()
{
}
-
+
ValueObjectSP
GetLockedSP(ValueImpl &in_value)
{
- return in_value.GetSP(m_stop_locker, m_api_locker, m_lock_error);
+ return in_value.GetSP(m_stop_locker, m_lock, m_lock_error);
}
-
+
Error &
GetError()
{
@@ -270,9 +270,8 @@ public:
private:
Process::StopLocker m_stop_locker;
- Mutex::Locker m_api_locker;
+ std::unique_lock<std::recursive_mutex> m_lock;
Error m_lock_error;
-
};
SBValue::SBValue () :
@@ -529,6 +528,10 @@ SBValue::GetValueType ()
log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult",
static_cast<void*>(value_sp.get()));
break;
+ case eValueTypeVariableThreadLocal:
+ log->Printf("SBValue(%p)::GetValueType () => eValueTypeVariableThreadLocal",
+ static_cast<void *>(value_sp.get()));
+ break;
}
}
return result;
@@ -923,16 +926,17 @@ SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType s
}
lldb::SBValue
-SBValue::CreateValueFromData (const char* name, SBData data, SBType type)
+SBValue::CreateValueFromData (const char* name, SBData data, SBType sb_type)
{
lldb::SBValue sb_value;
lldb::ValueObjectSP new_value_sp;
ValueLocker locker;
lldb::ValueObjectSP value_sp(GetSP(locker));
- if (value_sp)
+ lldb::TypeImplSP type_impl_sp (sb_type.GetSP());
+ if (value_sp && type_impl_sp)
{
ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
- new_value_sp = ValueObject::CreateValueObjectFromData(name, **data, exe_ctx, type.GetSP()->GetCompilerType(true));
+ new_value_sp = ValueObject::CreateValueObjectFromData(name, **data, exe_ctx, type_impl_sp->GetCompilerType(true));
new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
}
sb_value.SetSP(new_value_sp);
@@ -1141,6 +1145,25 @@ SBValue::IsSynthetic ()
return false;
}
+bool
+SBValue::IsSyntheticChildrenGenerated ()
+{
+ ValueLocker locker;
+ lldb::ValueObjectSP value_sp(GetSP(locker));
+ if (value_sp)
+ return value_sp->IsSyntheticChildrenGenerated();
+ return false;
+}
+
+void
+SBValue::SetSyntheticChildrenGenerated (bool is)
+{
+ ValueLocker locker;
+ lldb::ValueObjectSP value_sp(GetSP(locker));
+ if (value_sp)
+ return value_sp->SetSyntheticChildrenGenerated(is);
+}
+
lldb::SBValue
SBValue::GetValueForExpressionPath(const char* expr_path)
{
diff --git a/source/API/SBWatchpoint.cpp b/source/API/SBWatchpoint.cpp
index 1a1a970aaa87..c33d5686b9c9 100644
--- a/source/API/SBWatchpoint.cpp
+++ b/source/API/SBWatchpoint.cpp
@@ -115,7 +115,7 @@ SBWatchpoint::GetHardwareIndex ()
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
- Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(watchpoint_sp->GetTarget().GetAPIMutex());
hw_index = watchpoint_sp->GetHardwareIndex();
}
@@ -130,7 +130,7 @@ SBWatchpoint::GetWatchAddress ()
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
- Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(watchpoint_sp->GetTarget().GetAPIMutex());
ret_addr = watchpoint_sp->GetLoadAddress();
}
@@ -145,7 +145,7 @@ SBWatchpoint::GetWatchSize ()
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
- Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(watchpoint_sp->GetTarget().GetAPIMutex());
watch_size = watchpoint_sp->GetByteSize();
}
@@ -158,7 +158,7 @@ SBWatchpoint::SetEnabled (bool enabled)
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
- Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(watchpoint_sp->GetTarget().GetAPIMutex());
watchpoint_sp->GetTarget().DisableWatchpointByID(watchpoint_sp->GetID());
}
}
@@ -169,7 +169,7 @@ SBWatchpoint::IsEnabled ()
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
- Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(watchpoint_sp->GetTarget().GetAPIMutex());
return watchpoint_sp->IsEnabled();
}
else
@@ -183,7 +183,7 @@ SBWatchpoint::GetHitCount ()
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
- Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(watchpoint_sp->GetTarget().GetAPIMutex());
count = watchpoint_sp->GetHitCount();
}
@@ -201,7 +201,7 @@ SBWatchpoint::GetIgnoreCount ()
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
- Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(watchpoint_sp->GetTarget().GetAPIMutex());
return watchpoint_sp->GetIgnoreCount();
}
else
@@ -214,7 +214,7 @@ SBWatchpoint::SetIgnoreCount (uint32_t n)
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
- Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(watchpoint_sp->GetTarget().GetAPIMutex());
watchpoint_sp->SetIgnoreCount (n);
}
}
@@ -225,7 +225,7 @@ SBWatchpoint::GetCondition ()
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
- Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(watchpoint_sp->GetTarget().GetAPIMutex());
return watchpoint_sp->GetConditionText ();
}
return NULL;
@@ -237,7 +237,7 @@ SBWatchpoint::SetCondition (const char *condition)
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
- Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(watchpoint_sp->GetTarget().GetAPIMutex());
watchpoint_sp->SetCondition (condition);
}
}
@@ -250,7 +250,7 @@ SBWatchpoint::GetDescription (SBStream &description, DescriptionLevel level)
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
- Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(watchpoint_sp->GetTarget().GetAPIMutex());
watchpoint_sp->GetDescription (&strm, level);
strm.EOL();
}
diff --git a/source/API/SystemInitializerFull.cpp b/source/API/SystemInitializerFull.cpp
index cbc01a6cff9a..038f96cafba0 100644
--- a/source/API/SystemInitializerFull.cpp
+++ b/source/API/SystemInitializerFull.cpp
@@ -26,54 +26,76 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/GoASTContext.h"
+#include "lldb/Symbol/JavaASTContext.h"
-#include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h"
#include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h"
#include "Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h"
+#include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h"
#include "Plugins/ABI/SysV-arm/ABISysV_arm.h"
#include "Plugins/ABI/SysV-arm64/ABISysV_arm64.h"
#include "Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h"
#include "Plugins/ABI/SysV-i386/ABISysV_i386.h"
-#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
-#include "Plugins/ABI/SysV-ppc/ABISysV_ppc.h"
-#include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h"
#include "Plugins/ABI/SysV-mips/ABISysV_mips.h"
#include "Plugins/ABI/SysV-mips64/ABISysV_mips64.h"
+#include "Plugins/ABI/SysV-ppc/ABISysV_ppc.h"
+#include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h"
+#include "Plugins/ABI/SysV-s390x/ABISysV_s390x.h"
+#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
+#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
+#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
+#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
#include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h"
#include "Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h"
+#include "Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h"
#include "Plugins/JITLoader/GDB/JITLoaderGDB.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/Go/GoLanguage.h"
+#include "Plugins/Language/Java/JavaLanguage.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h"
#include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h"
+#include "Plugins/LanguageRuntime/Go/GoLanguageRuntime.h"
+#include "Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h"
-#include "Plugins/LanguageRuntime/Go/GoLanguageRuntime.h"
#include "Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h"
#include "Plugins/MemoryHistory/asan/MemoryHistoryASan.h"
+#include "Plugins/OperatingSystem/Go/OperatingSystemGo.h"
+#include "Plugins/OperatingSystem/Python/OperatingSystemPython.h"
+#include "Plugins/Platform/Android/PlatformAndroid.h"
+#include "Plugins/Platform/FreeBSD/PlatformFreeBSD.h"
+#include "Plugins/Platform/Kalimba/PlatformKalimba.h"
+#include "Plugins/Platform/Linux/PlatformLinux.h"
+#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
+#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
+#include "Plugins/Platform/NetBSD/PlatformNetBSD.h"
+#include "Plugins/Platform/Windows/PlatformWindows.h"
#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h"
+#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
#include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h"
#include "Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h"
-#include "Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h"
#include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h"
+#include "Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h"
#if defined(__APPLE__)
-#include "Plugins/Process/mach-core/ProcessMachCore.h"
-#include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h"
-#include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
+#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
#include "Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h"
#include "Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h"
+#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
#include "Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h"
#include "Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h"
+#include "Plugins/Platform/MacOSX/PlatformiOSSimulator.h"
+#include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h"
+#include "Plugins/Process/mach-core/ProcessMachCore.h"
+#include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
#endif
#if defined(__FreeBSD__)
@@ -255,6 +277,11 @@ SystemInitializerFull::Initialize()
SystemInitializerCommon::Initialize();
ScriptInterpreterNone::Initialize();
+#ifndef LLDB_DISABLE_PYTHON
+ OperatingSystemPython::Initialize();
+#endif
+ OperatingSystemGo::Initialize();
+
#if !defined(LLDB_DISABLE_PYTHON)
InitializeSWIG();
@@ -264,6 +291,19 @@ SystemInitializerFull::Initialize()
ScriptInterpreterPython::Initialize();
#endif
+ platform_freebsd::PlatformFreeBSD::Initialize();
+ platform_linux::PlatformLinux::Initialize();
+ platform_netbsd::PlatformNetBSD::Initialize();
+ PlatformWindows::Initialize();
+ PlatformKalimba::Initialize();
+ platform_android::PlatformAndroid::Initialize();
+ PlatformRemoteiOS::Initialize();
+ PlatformMacOSX::Initialize();
+#if defined(__APPLE__)
+ PlatformiOSSimulator::Initialize();
+ PlatformDarwinKernel::Initialize();
+#endif
+
// Initialize LLVM and Clang
llvm::InitializeAllTargets();
llvm::InitializeAllAsmPrinters();
@@ -272,6 +312,7 @@ SystemInitializerFull::Initialize()
ClangASTContext::Initialize();
GoASTContext::Initialize();
+ JavaASTContext::Initialize();
ABIMacOSX_i386::Initialize();
ABIMacOSX_arm::Initialize();
@@ -285,6 +326,7 @@ SystemInitializerFull::Initialize()
ABISysV_ppc64::Initialize();
ABISysV_mips::Initialize();
ABISysV_mips64::Initialize();
+ ABISysV_s390x::Initialize();
DisassemblerLLVMC::Initialize();
JITLoaderGDB::Initialize();
@@ -294,9 +336,11 @@ SystemInitializerFull::Initialize()
#endif
MemoryHistoryASan::Initialize();
AddressSanitizerRuntime::Initialize();
+ ThreadSanitizerRuntime::Initialize();
SymbolVendorELF::Initialize();
SymbolFileDWARF::Initialize();
+ SymbolFilePDB::Initialize();
SymbolFileSymtab::Initialize();
UnwindAssemblyInstEmulation::Initialize();
UnwindAssembly_x86::Initialize();
@@ -308,9 +352,11 @@ SystemInitializerFull::Initialize()
SystemRuntimeMacOSX::Initialize();
RenderScriptRuntime::Initialize();
GoLanguageRuntime::Initialize();
+ JavaLanguageRuntime::Initialize();
CPlusPlusLanguage::Initialize();
GoLanguage::Initialize();
+ JavaLanguage::Initialize();
ObjCLanguage::Initialize();
ObjCPlusPlusLanguage::Initialize();
@@ -328,6 +374,7 @@ SystemInitializerFull::Initialize()
PlatformAppleWatchSimulator::Initialize();
PlatformRemoteAppleTV::Initialize();
PlatformRemoteAppleWatch::Initialize();
+ DynamicLoaderDarwinKernel::Initialize();
#endif
//----------------------------------------------------------------------
// Platform agnostic plugins
@@ -335,7 +382,10 @@ SystemInitializerFull::Initialize()
platform_gdb_server::PlatformRemoteGDBServer::Initialize();
process_gdb_remote::ProcessGDBRemote::Initialize();
+ DynamicLoaderMacOSXDYLD::Initialize();
+ DynamicLoaderPOSIXDYLD::Initialize();
DynamicLoaderStatic::Initialize();
+ DynamicLoaderWindowsDYLD::Initialize();
// Scan for any system or user LLDB plug-ins
PluginManager::Initialize();
@@ -391,6 +441,7 @@ SystemInitializerFull::Terminate()
ClangASTContext::Terminate();
GoASTContext::Terminate();
+ JavaASTContext::Terminate();
ABIMacOSX_i386::Terminate();
ABIMacOSX_arm::Terminate();
@@ -404,6 +455,7 @@ SystemInitializerFull::Terminate()
ABISysV_ppc64::Terminate();
ABISysV_mips::Terminate();
ABISysV_mips64::Terminate();
+ ABISysV_s390x::Terminate();
DisassemblerLLVMC::Terminate();
JITLoaderGDB::Terminate();
@@ -413,8 +465,10 @@ SystemInitializerFull::Terminate()
#endif
MemoryHistoryASan::Terminate();
AddressSanitizerRuntime::Terminate();
+ ThreadSanitizerRuntime::Terminate();
SymbolVendorELF::Terminate();
SymbolFileDWARF::Terminate();
+ SymbolFilePDB::Terminate();
SymbolFileSymtab::Terminate();
UnwindAssembly_x86::Terminate();
UnwindAssemblyInstEmulation::Terminate();
@@ -425,13 +479,16 @@ SystemInitializerFull::Terminate()
AppleObjCRuntimeV1::Terminate();
SystemRuntimeMacOSX::Terminate();
RenderScriptRuntime::Terminate();
+ JavaLanguageRuntime::Terminate();
CPlusPlusLanguage::Terminate();
GoLanguage::Terminate();
+ JavaLanguage::Terminate();
ObjCLanguage::Terminate();
ObjCPlusPlusLanguage::Terminate();
#if defined(__APPLE__)
+ DynamicLoaderDarwinKernel::Terminate();
ProcessMachCore::Terminate();
ProcessKDP::Terminate();
SymbolVendorMacOSX::Terminate();
@@ -448,7 +505,28 @@ SystemInitializerFull::Terminate()
platform_gdb_server::PlatformRemoteGDBServer::Terminate();
process_gdb_remote::ProcessGDBRemote::Terminate();
+ DynamicLoaderMacOSXDYLD::Terminate();
+ DynamicLoaderPOSIXDYLD::Terminate();
DynamicLoaderStatic::Terminate();
+ DynamicLoaderWindowsDYLD::Terminate();
+
+#ifndef LLDB_DISABLE_PYTHON
+ OperatingSystemPython::Terminate();
+#endif
+ OperatingSystemGo::Terminate();
+
+ platform_freebsd::PlatformFreeBSD::Terminate();
+ platform_linux::PlatformLinux::Terminate();
+ platform_netbsd::PlatformNetBSD::Terminate();
+ PlatformWindows::Terminate();
+ PlatformKalimba::Terminate();
+ platform_android::PlatformAndroid::Terminate();
+ PlatformMacOSX::Terminate();
+ PlatformRemoteiOS::Terminate();
+#if defined(__APPLE__)
+ PlatformiOSSimulator::Terminate();
+ PlatformDarwinKernel::Terminate();
+#endif
// Now shutdown the common parts, in reverse order.
SystemInitializerCommon::Terminate();
diff --git a/source/API/liblldb.exports b/source/API/liblldb.exports
index fd234d11c40c..3ceb562c7ed1 100644
--- a/source/API/liblldb.exports
+++ b/source/API/liblldb.exports
@@ -1,3 +1,4 @@
_ZN4lldb*
_ZNK4lldb*
init_lld*
+PyInit__lldb*
diff --git a/source/Breakpoint/Breakpoint.cpp b/source/Breakpoint/Breakpoint.cpp
index 54f67b90220a..224f266fe111 100644
--- a/source/Breakpoint/Breakpoint.cpp
+++ b/source/Breakpoint/Breakpoint.cpp
@@ -410,8 +410,8 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_loca
if (log)
log->Printf ("Breakpoint::ModulesChanged: num_modules: %zu load: %i delete_locations: %i\n",
module_list.GetSize(), load, delete_locations);
-
- Mutex::Locker modules_mutex(module_list.GetMutex());
+
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
if (load)
{
// The logic for handling new modules is:
diff --git a/source/Breakpoint/BreakpointList.cpp b/source/Breakpoint/BreakpointList.cpp
index 650737761547..9877c2d1246c 100644
--- a/source/Breakpoint/BreakpointList.cpp
+++ b/source/Breakpoint/BreakpointList.cpp
@@ -18,11 +18,8 @@
using namespace lldb;
using namespace lldb_private;
-BreakpointList::BreakpointList (bool is_internal) :
- m_mutex (Mutex::eMutexTypeRecursive),
- m_breakpoints(),
- m_next_break_id (0),
- m_is_internal (is_internal)
+BreakpointList::BreakpointList(bool is_internal)
+ : m_mutex(), m_breakpoints(), m_next_break_id(0), m_is_internal(is_internal)
{
}
@@ -34,7 +31,7 @@ BreakpointList::~BreakpointList()
break_id_t
BreakpointList::Add (BreakpointSP &bp_sp, bool notify)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Internal breakpoint IDs are negative, normal ones are positive
bp_sp->SetID (m_is_internal ? --m_next_break_id : ++m_next_break_id);
@@ -51,7 +48,7 @@ BreakpointList::Add (BreakpointSP &bp_sp, bool notify)
bool
BreakpointList::Remove (break_id_t break_id, bool notify)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
bp_collection::iterator pos = GetBreakpointIDIterator(break_id); // Predicate
if (pos != m_breakpoints.end())
{
@@ -71,7 +68,7 @@ BreakpointList::Remove (break_id_t break_id, bool notify)
void
BreakpointList::RemoveInvalidLocations (const ArchSpec &arch)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
for (const auto &bp_sp : m_breakpoints)
bp_sp->RemoveInvalidLocations(arch);
}
@@ -80,7 +77,7 @@ BreakpointList::RemoveInvalidLocations (const ArchSpec &arch)
void
BreakpointList::SetEnabledAll (bool enabled)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
for (const auto &bp_sp : m_breakpoints)
bp_sp->SetEnabled (enabled);
}
@@ -89,7 +86,7 @@ BreakpointList::SetEnabledAll (bool enabled)
void
BreakpointList::RemoveAll (bool notify)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
ClearAllBreakpointSites ();
if (notify)
@@ -142,7 +139,7 @@ BreakpointList::GetBreakpointIDConstIterator (break_id_t break_id) const
BreakpointSP
BreakpointList::FindBreakpointByID (break_id_t break_id)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
BreakpointSP stop_sp;
bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
if (pos != m_breakpoints.end())
@@ -154,7 +151,7 @@ BreakpointList::FindBreakpointByID (break_id_t break_id)
const BreakpointSP
BreakpointList::FindBreakpointByID (break_id_t break_id) const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
BreakpointSP stop_sp;
bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
if (pos != m_breakpoints.end())
@@ -166,7 +163,7 @@ BreakpointList::FindBreakpointByID (break_id_t break_id) const
void
BreakpointList::Dump (Stream *s) const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
s->Printf("%p: ", static_cast<const void*>(this));
s->Indent();
s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size());
@@ -180,7 +177,7 @@ BreakpointList::Dump (Stream *s) const
BreakpointSP
BreakpointList::GetBreakpointAtIndex (size_t i)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
BreakpointSP stop_sp;
bp_collection::iterator end = m_breakpoints.end();
bp_collection::iterator pos;
@@ -196,7 +193,7 @@ BreakpointList::GetBreakpointAtIndex (size_t i)
const BreakpointSP
BreakpointList::GetBreakpointAtIndex (size_t i) const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
BreakpointSP stop_sp;
bp_collection::const_iterator end = m_breakpoints.end();
bp_collection::const_iterator pos;
@@ -212,7 +209,7 @@ BreakpointList::GetBreakpointAtIndex (size_t i) const
void
BreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added, bool delete_locations)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
for (const auto &bp_sp : m_breakpoints)
bp_sp->ModulesChanged (module_list, added, delete_locations);
@@ -221,7 +218,7 @@ BreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added, bool del
void
BreakpointList::UpdateBreakpointsWhenModuleIsReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
for (const auto &bp_sp : m_breakpoints)
bp_sp->ModuleReplaced (old_module_sp, new_module_sp);
@@ -230,14 +227,14 @@ BreakpointList::UpdateBreakpointsWhenModuleIsReplaced (ModuleSP old_module_sp, M
void
BreakpointList::ClearAllBreakpointSites ()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
for (const auto &bp_sp : m_breakpoints)
bp_sp->ClearAllBreakpointSites ();
}
void
-BreakpointList::GetListMutex (Mutex::Locker &locker)
+BreakpointList::GetListMutex(std::unique_lock<std::recursive_mutex> &lock)
{
- return locker.Lock (m_mutex);
+ lock = std::unique_lock<std::recursive_mutex>(m_mutex);
}
diff --git a/source/Breakpoint/BreakpointLocation.cpp b/source/Breakpoint/BreakpointLocation.cpp
index 5ff91102aadd..5baf4721e826 100644
--- a/source/Breakpoint/BreakpointLocation.cpp
+++ b/source/Breakpoint/BreakpointLocation.cpp
@@ -19,6 +19,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -32,36 +33,29 @@
using namespace lldb;
using namespace lldb_private;
-BreakpointLocation::BreakpointLocation
-(
- break_id_t loc_id,
- Breakpoint &owner,
- const Address &addr,
- lldb::tid_t tid,
- bool hardware,
- bool check_for_resolver
-) :
- StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
- m_being_created(true),
- m_should_resolve_indirect_functions (false),
- m_is_reexported (false),
- m_is_indirect (false),
- m_address (addr),
- m_owner (owner),
- m_options_ap (),
- m_bp_site_sp (),
- m_condition_mutex ()
+BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner, const Address &addr, lldb::tid_t tid,
+ bool hardware, bool check_for_resolver)
+ : StoppointLocation(loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
+ m_being_created(true),
+ m_should_resolve_indirect_functions(false),
+ m_is_reexported(false),
+ m_is_indirect(false),
+ m_address(addr),
+ m_owner(owner),
+ m_options_ap(),
+ m_bp_site_sp(),
+ m_condition_mutex()
{
if (check_for_resolver)
{
Symbol *symbol = m_address.CalculateSymbolContextSymbol();
if (symbol && symbol->IsIndirect())
{
- SetShouldResolveIndirectFunctions (true);
+ SetShouldResolveIndirectFunctions(true);
}
}
-
- SetThreadID (tid);
+
+ SetThreadID(tid);
m_being_created = false;
}
@@ -266,9 +260,9 @@ bool
BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
-
- Mutex::Locker evaluation_locker(m_condition_mutex);
-
+
+ std::lock_guard<std::mutex> guard(m_condition_mutex);
+
size_t condition_hash;
const char *condition_text = GetConditionText(&condition_hash);
@@ -277,10 +271,10 @@ BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
m_user_expression_sp.reset();
return false;
}
-
- if (condition_hash != m_condition_hash ||
- !m_user_expression_sp ||
- !m_user_expression_sp->MatchesContext(exe_ctx))
+
+ DiagnosticManager diagnostics;
+
+ if (condition_hash != m_condition_hash || !m_user_expression_sp || !m_user_expression_sp->MatchesContext(exe_ctx))
{
LanguageType language = eLanguageTypeUnknown;
// See if we can figure out the language from the frame, otherwise use the default language:
@@ -303,20 +297,14 @@ BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
return true;
}
- StreamString errors;
-
- if (!m_user_expression_sp->Parse(errors,
- exe_ctx,
- eExecutionPolicyOnlyWhenNeeded,
- true,
- false))
+ if (!m_user_expression_sp->Parse(diagnostics, exe_ctx, eExecutionPolicyOnlyWhenNeeded, true, false))
{
error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
- errors.GetData());
+ diagnostics.GetString().c_str());
m_user_expression_sp.reset();
return false;
}
-
+
m_condition_hash = condition_hash;
}
@@ -329,20 +317,17 @@ BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
options.SetUnwindOnError(true);
options.SetIgnoreBreakpoints(true);
options.SetTryAllThreads(true);
-
+ options.SetResultIsInternal(true); // Don't generate a user variable for condition expressions.
+
Error expr_error;
-
- StreamString execution_errors;
-
+
+ diagnostics.Clear();
+
ExpressionVariableSP result_variable_sp;
-
+
ExpressionResults result_code =
- m_user_expression_sp->Execute(execution_errors,
- exe_ctx,
- options,
- m_user_expression_sp,
- result_variable_sp);
-
+ m_user_expression_sp->Execute(diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp);
+
bool ret;
if (result_code == eExpressionCompleted)
@@ -382,9 +367,9 @@ BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
else
{
ret = false;
- error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
+ error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", diagnostics.GetString().c_str());
}
-
+
return ret;
}
diff --git a/source/Breakpoint/BreakpointLocationCollection.cpp b/source/Breakpoint/BreakpointLocationCollection.cpp
index 5b6e746f911d..52698b2f15bb 100644
--- a/source/Breakpoint/BreakpointLocationCollection.cpp
+++ b/source/Breakpoint/BreakpointLocationCollection.cpp
@@ -26,7 +26,8 @@ using namespace lldb_private;
// BreakpointLocationCollection constructor
//----------------------------------------------------------------------
BreakpointLocationCollection::BreakpointLocationCollection() :
- m_break_loc_collection()
+ m_break_loc_collection(),
+ m_collection_mutex()
{
}
@@ -40,6 +41,7 @@ BreakpointLocationCollection::~BreakpointLocationCollection()
void
BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc)
{
+ std::lock_guard<std::mutex> guard(m_collection_mutex);
BreakpointLocationSP old_bp_loc = FindByIDPair (bp_loc->GetBreakpoint().GetID(), bp_loc->GetID());
if (!old_bp_loc.get())
m_break_loc_collection.push_back(bp_loc);
@@ -48,6 +50,7 @@ BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc)
bool
BreakpointLocationCollection::Remove (lldb::break_id_t bp_id, lldb::break_id_t bp_loc_id)
{
+ std::lock_guard<std::mutex> guard(m_collection_mutex);
collection::iterator pos = GetIDPairIterator(bp_id, bp_loc_id); // Predicate
if (pos != m_break_loc_collection.end())
{
@@ -117,6 +120,7 @@ BreakpointLocationCollection::FindByIDPair (lldb::break_id_t break_id, lldb::bre
BreakpointLocationSP
BreakpointLocationCollection::GetByIndex (size_t i)
{
+ std::lock_guard<std::mutex> guard(m_collection_mutex);
BreakpointLocationSP stop_sp;
if (i < m_break_loc_collection.size())
stop_sp = m_break_loc_collection[i];
@@ -127,6 +131,7 @@ BreakpointLocationCollection::GetByIndex (size_t i)
const BreakpointLocationSP
BreakpointLocationCollection::GetByIndex (size_t i) const
{
+ std::lock_guard<std::mutex> guard(m_collection_mutex);
BreakpointLocationSP stop_sp;
if (i < m_break_loc_collection.size())
stop_sp = m_break_loc_collection[i];
@@ -156,6 +161,7 @@ BreakpointLocationCollection::ShouldStop (StoppointCallbackContext *context)
bool
BreakpointLocationCollection::ValidForThisThread (Thread *thread)
{
+ std::lock_guard<std::mutex> guard(m_collection_mutex);
collection::iterator pos,
begin = m_break_loc_collection.begin(),
end = m_break_loc_collection.end();
@@ -171,6 +177,7 @@ BreakpointLocationCollection::ValidForThisThread (Thread *thread)
bool
BreakpointLocationCollection::IsInternal () const
{
+ std::lock_guard<std::mutex> guard(m_collection_mutex);
collection::const_iterator pos,
begin = m_break_loc_collection.begin(),
end = m_break_loc_collection.end();
@@ -191,6 +198,7 @@ BreakpointLocationCollection::IsInternal () const
void
BreakpointLocationCollection::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
+ std::lock_guard<std::mutex> guard(m_collection_mutex);
collection::iterator pos,
begin = m_break_loc_collection.begin(),
end = m_break_loc_collection.end();
diff --git a/source/Breakpoint/BreakpointLocationList.cpp b/source/Breakpoint/BreakpointLocationList.cpp
index d57cfa68fb80..5e56299bfe78 100644
--- a/source/Breakpoint/BreakpointLocationList.cpp
+++ b/source/Breakpoint/BreakpointLocationList.cpp
@@ -24,13 +24,8 @@
using namespace lldb;
using namespace lldb_private;
-BreakpointLocationList::BreakpointLocationList(Breakpoint &owner) :
- m_owner (owner),
- m_locations(),
- m_address_to_location (),
- m_mutex (Mutex::eMutexTypeRecursive),
- m_next_id (0),
- m_new_location_recorder (nullptr)
+BreakpointLocationList::BreakpointLocationList(Breakpoint &owner)
+ : m_owner(owner), m_locations(), m_address_to_location(), m_mutex(), m_next_id(0), m_new_location_recorder(nullptr)
{
}
@@ -39,7 +34,7 @@ BreakpointLocationList::~BreakpointLocationList() = default;
BreakpointLocationSP
BreakpointLocationList::Create (const Address &addr, bool resolve_indirect_symbols)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// The location ID is just the size of the location list + 1
lldb::break_id_t bp_loc_id = ++m_next_id;
BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, m_owner, addr, LLDB_INVALID_THREAD_ID, m_owner.IsHardware(), resolve_indirect_symbols));
@@ -84,7 +79,7 @@ Compare (BreakpointLocationSP lhs, lldb::break_id_t val)
BreakpointLocationSP
BreakpointLocationList::FindByID (lldb::break_id_t break_id) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::const_iterator end = m_locations.end();
collection::const_iterator pos = std::lower_bound(m_locations.begin(), end, break_id, Compare);
if (pos != end && (*pos)->GetID() == break_id)
@@ -97,7 +92,7 @@ size_t
BreakpointLocationList::FindInModule (Module *module,
BreakpointLocationCollection& bp_loc_list)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const size_t orig_size = bp_loc_list.GetSize();
collection::iterator pos, end = m_locations.end();
@@ -116,7 +111,7 @@ BreakpointLocationList::FindInModule (Module *module,
const BreakpointLocationSP
BreakpointLocationList::FindByAddress (const Address &addr) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
BreakpointLocationSP bp_loc_sp;
if (!m_locations.empty())
{
@@ -150,7 +145,7 @@ BreakpointLocationList::Dump (Stream *s) const
{
s->Printf("%p: ", static_cast<const void*>(this));
//s->Indent();
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
s->Printf("BreakpointLocationList with %" PRIu64 " BreakpointLocations:\n", (uint64_t)m_locations.size());
s->IndentMore();
collection::const_iterator pos, end = m_locations.end();
@@ -162,7 +157,7 @@ BreakpointLocationList::Dump (Stream *s) const
BreakpointLocationSP
BreakpointLocationList::GetByIndex (size_t i)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
BreakpointLocationSP bp_loc_sp;
if (i < m_locations.size())
bp_loc_sp = m_locations[i];
@@ -173,7 +168,7 @@ BreakpointLocationList::GetByIndex (size_t i)
const BreakpointLocationSP
BreakpointLocationList::GetByIndex (size_t i) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
BreakpointLocationSP bp_loc_sp;
if (i < m_locations.size())
bp_loc_sp = m_locations[i];
@@ -184,7 +179,7 @@ BreakpointLocationList::GetByIndex (size_t i) const
void
BreakpointLocationList::ClearAllBreakpointSites ()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
(*pos)->ClearBreakpointSite();
@@ -193,7 +188,7 @@ BreakpointLocationList::ClearAllBreakpointSites ()
void
BreakpointLocationList::ResolveAllBreakpointSites ()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
@@ -207,7 +202,7 @@ uint32_t
BreakpointLocationList::GetHitCount () const
{
uint32_t hit_count = 0;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::const_iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
hit_count += (*pos)->GetHitCount();
@@ -217,7 +212,7 @@ BreakpointLocationList::GetHitCount () const
size_t
BreakpointLocationList::GetNumResolvedLocations() const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
size_t resolve_count = 0;
collection::const_iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
@@ -231,7 +226,7 @@ BreakpointLocationList::GetNumResolvedLocations() const
void
BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
@@ -244,7 +239,7 @@ BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level)
BreakpointLocationSP
BreakpointLocationList::AddLocation (const Address &addr, bool resolve_indirect_symbols, bool *new_location)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (new_location)
*new_location = false;
@@ -285,8 +280,8 @@ BreakpointLocationList::RemoveLocation (const lldb::BreakpointLocationSP &bp_loc
{
if (bp_loc_sp)
{
- Mutex::Locker locker (m_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
m_address_to_location.erase (bp_loc_sp->GetAddress());
collection::iterator pos, end = m_locations.end();
@@ -305,7 +300,7 @@ BreakpointLocationList::RemoveLocation (const lldb::BreakpointLocationSP &bp_loc
void
BreakpointLocationList::RemoveInvalidLocations (const ArchSpec &arch)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
size_t idx = 0;
// Don't cache m_location.size() as it will change since we might
// remove locations from our vector...
@@ -341,7 +336,7 @@ BreakpointLocationList::RemoveInvalidLocations (const ArchSpec &arch)
void
BreakpointLocationList::StartRecordingNewLocations (BreakpointLocationCollection &new_locations)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
assert(m_new_location_recorder == nullptr);
m_new_location_recorder = &new_locations;
}
@@ -349,7 +344,7 @@ BreakpointLocationList::StartRecordingNewLocations (BreakpointLocationCollection
void
BreakpointLocationList::StopRecordingNewLocations ()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_new_location_recorder = nullptr;
}
diff --git a/source/Breakpoint/BreakpointResolver.cpp b/source/Breakpoint/BreakpointResolver.cpp
index f02eadf86a7c..e757b388550f 100644
--- a/source/Breakpoint/BreakpointResolver.cpp
+++ b/source/Breakpoint/BreakpointResolver.cpp
@@ -32,8 +32,9 @@ using namespace lldb;
//----------------------------------------------------------------------
// BreakpointResolver:
//----------------------------------------------------------------------
-BreakpointResolver::BreakpointResolver (Breakpoint *bkpt, const unsigned char resolverTy) :
+BreakpointResolver::BreakpointResolver (Breakpoint *bkpt, const unsigned char resolverTy, lldb::addr_t offset) :
m_breakpoint (bkpt),
+ m_offset(offset),
SubclassID (resolverTy)
{
}
@@ -74,6 +75,7 @@ BreakpointResolver::SetSCMatchesByLine (SearchFilter &filter, SymbolContextList
bool first_entry = true;
FileSpec match_file_spec;
+ FileSpec match_original_file_spec;
uint32_t closest_line_number = UINT32_MAX;
// Pull out the first entry, and all the others that match its file spec, and stuff them in the tmp list.
@@ -85,11 +87,13 @@ BreakpointResolver::SetSCMatchesByLine (SearchFilter &filter, SymbolContextList
if (first_entry)
{
match_file_spec = sc.line_entry.file;
+ match_original_file_spec = sc.line_entry.original_file;
matches = true;
first_entry = false;
}
else
- matches = (sc.line_entry.file == match_file_spec);
+ matches = ((sc.line_entry.file == match_file_spec) ||
+ (sc.line_entry.original_file == match_original_file_spec));
if (matches)
{
@@ -176,7 +180,7 @@ BreakpointResolver::SetSCMatchesByLine (SearchFilter &filter, SymbolContextList
}
}
- BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(line_start));
+ BreakpointLocationSP bp_loc_sp (AddLocation(line_start));
if (log && bp_loc_sp && !m_breakpoint->IsInternal())
{
StreamString s;
@@ -202,3 +206,22 @@ BreakpointResolver::SetSCMatchesByLine (SearchFilter &filter, SymbolContextList
}
}
}
+
+BreakpointLocationSP
+BreakpointResolver::AddLocation(Address loc_addr, bool *new_location)
+{
+ loc_addr.Slide(m_offset);
+ return m_breakpoint->AddLocation(loc_addr, new_location);
+}
+
+
+void
+BreakpointResolver::SetOffset (lldb::addr_t offset)
+{
+ // There may already be an offset, so we are actually adjusting location addresses by the difference.
+ // lldb::addr_t slide = offset - m_offset;
+ // FIXME: We should go fix up all the already set locations for the new slide.
+
+ m_offset = offset;
+}
+
diff --git a/source/Breakpoint/BreakpointResolverAddress.cpp b/source/Breakpoint/BreakpointResolverAddress.cpp
index 8a0469a07e46..14942014d80a 100644
--- a/source/Breakpoint/BreakpointResolverAddress.cpp
+++ b/source/Breakpoint/BreakpointResolverAddress.cpp
@@ -121,8 +121,8 @@ BreakpointResolverAddress::SearchCallback
}
}
- BreakpointLocationSP bp_loc_sp(m_breakpoint->AddLocation(m_addr));
m_resolved_addr = m_addr.GetLoadAddress(&m_breakpoint->GetTarget());
+ BreakpointLocationSP bp_loc_sp(AddLocation(m_addr));
if (bp_loc_sp && !m_breakpoint->IsInternal())
{
StreamString s;
diff --git a/source/Breakpoint/BreakpointResolverFileLine.cpp b/source/Breakpoint/BreakpointResolverFileLine.cpp
index 408998ec83ab..e1fb87a9d872 100644
--- a/source/Breakpoint/BreakpointResolverFileLine.cpp
+++ b/source/Breakpoint/BreakpointResolverFileLine.cpp
@@ -31,11 +31,12 @@ BreakpointResolverFileLine::BreakpointResolverFileLine
Breakpoint *bkpt,
const FileSpec &file_spec,
uint32_t line_no,
+ lldb::addr_t offset,
bool check_inlines,
bool skip_prologue,
bool exact_match
) :
- BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver),
+ BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver, offset),
m_file_spec (file_spec),
m_line_number (line_no),
m_inlines (check_inlines),
@@ -117,6 +118,7 @@ BreakpointResolverFileLine::CopyForBreakpoint (Breakpoint &breakpoint)
lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileLine(&breakpoint,
m_file_spec,
m_line_number,
+ m_offset,
m_inlines,
m_skip_prologue,
m_exact_match));
diff --git a/source/Breakpoint/BreakpointResolverFileRegex.cpp b/source/Breakpoint/BreakpointResolverFileRegex.cpp
index e7bce0524c57..ae7f58acb91e 100644
--- a/source/Breakpoint/BreakpointResolverFileRegex.cpp
+++ b/source/Breakpoint/BreakpointResolverFileRegex.cpp
@@ -30,11 +30,13 @@ BreakpointResolverFileRegex::BreakpointResolverFileRegex
(
Breakpoint *bkpt,
RegularExpression &regex,
+ const std::unordered_set<std::string> &func_names,
bool exact_match
) :
BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver),
m_regex (regex),
- m_exact_match (exact_match)
+ m_exact_match (exact_match),
+ m_function_names(func_names)
{
}
@@ -68,6 +70,32 @@ BreakpointResolverFileRegex::SearchCallback
const bool search_inlines = false;
cu->ResolveSymbolContext (cu_file_spec, line_matches[i], search_inlines, m_exact_match, eSymbolContextEverything, sc_list);
+ // Find all the function names:
+ if (!m_function_names.empty())
+ {
+ std::vector<size_t> sc_to_remove;
+ for (size_t i = 0; i < sc_list.GetSize(); i++)
+ {
+ SymbolContext sc_ctx;
+ sc_list.GetContextAtIndex(i, sc_ctx);
+ std::string name(sc_ctx.GetFunctionName(Mangled::NamePreference::ePreferDemangledWithoutArguments).AsCString());
+ if (!m_function_names.count(name))
+ {
+ sc_to_remove.push_back(i);
+ }
+ }
+
+ if (!sc_to_remove.empty())
+ {
+ std::vector<size_t>::reverse_iterator iter;
+ std::vector<size_t>::reverse_iterator rend = sc_to_remove.rend();
+ for (iter = sc_to_remove.rbegin(); iter != rend; iter++)
+ {
+ sc_list.RemoveContextAtIndex(*iter);
+ }
+ }
+ }
+
const bool skip_prologue = true;
BreakpointResolver::SetSCMatchesByLine (filter, sc_list, skip_prologue, m_regex.GetText());
@@ -98,7 +126,13 @@ BreakpointResolverFileRegex::Dump (Stream *s) const
lldb::BreakpointResolverSP
BreakpointResolverFileRegex::CopyForBreakpoint (Breakpoint &breakpoint)
{
- lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex(&breakpoint, m_regex, m_exact_match));
+ lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex(&breakpoint, m_regex, m_function_names, m_exact_match));
return ret_sp;
}
+void
+BreakpointResolverFileRegex::AddFunctionName(const char *func_name)
+{
+ m_function_names.insert(func_name);
+}
+
diff --git a/source/Breakpoint/BreakpointResolverName.cpp b/source/Breakpoint/BreakpointResolverName.cpp
index 9ae3fe5256d4..dfa09c2342f9 100644
--- a/source/Breakpoint/BreakpointResolverName.cpp
+++ b/source/Breakpoint/BreakpointResolverName.cpp
@@ -22,6 +22,7 @@
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
using namespace lldb;
using namespace lldb_private;
@@ -31,8 +32,9 @@ BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
uint32_t name_type_mask,
LanguageType language,
Breakpoint::MatchType type,
+ lldb::addr_t offset,
bool skip_prologue) :
- BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
+ BreakpointResolver (bkpt, BreakpointResolver::NameResolver, offset),
m_class_name (),
m_regex (),
m_match_type (type),
@@ -60,8 +62,9 @@ BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
size_t num_names,
uint32_t name_type_mask,
LanguageType language,
+ lldb::addr_t offset,
bool skip_prologue) :
- BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
+ BreakpointResolver (bkpt, BreakpointResolver::NameResolver, offset),
m_match_type (Breakpoint::Exact),
m_language (language),
m_skip_prologue (skip_prologue)
@@ -76,8 +79,9 @@ BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
std::vector<std::string> names,
uint32_t name_type_mask,
LanguageType language,
+ lldb::addr_t offset,
bool skip_prologue) :
- BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
+ BreakpointResolver (bkpt, BreakpointResolver::NameResolver, offset),
m_match_type (Breakpoint::Exact),
m_language (language),
m_skip_prologue (skip_prologue)
@@ -91,8 +95,9 @@ BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
RegularExpression &func_regex,
lldb::LanguageType language,
+ lldb::addr_t offset,
bool skip_prologue) :
- BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
+ BreakpointResolver (bkpt, BreakpointResolver::NameResolver, offset),
m_class_name (nullptr),
m_regex (func_regex),
m_match_type (Breakpoint::Regexp),
@@ -101,30 +106,33 @@ BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
{
}
-BreakpointResolverName::BreakpointResolverName(Breakpoint *bkpt,
- const char *class_name,
- const char *method,
- Breakpoint::MatchType type,
- bool skip_prologue ) :
- BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
+BreakpointResolverName::BreakpointResolverName
+(
+ Breakpoint *bkpt,
+ const char *class_name,
+ const char *method,
+ Breakpoint::MatchType type,
+ lldb::addr_t offset,
+ bool skip_prologue
+) :
+ BreakpointResolver (bkpt, BreakpointResolver::NameResolver, offset),
m_class_name (class_name),
m_regex (),
m_match_type (type),
m_language (eLanguageTypeUnknown),
m_skip_prologue (skip_prologue)
{
- LookupInfo lookup;
- lookup.name.SetCString(method);
- lookup.lookup_name = lookup.name;
- lookup.name_type_mask = eFunctionNameTypeMethod;
- lookup.match_name_after_lookup = false;
+ Module::LookupInfo lookup;
+ lookup.SetName(ConstString(method));
+ lookup.SetLookupName(lookup.GetName());
+ lookup.SetNameTypeMask(eFunctionNameTypeMethod);
m_lookups.push_back (lookup);
}
BreakpointResolverName::~BreakpointResolverName() = default;
BreakpointResolverName::BreakpointResolverName(const BreakpointResolverName &rhs) :
- BreakpointResolver(rhs.m_breakpoint, BreakpointResolver::NameResolver),
+ BreakpointResolver(rhs.m_breakpoint, BreakpointResolver::NameResolver, rhs.m_offset),
m_lookups(rhs.m_lookups),
m_class_name(rhs.m_class_name),
m_regex(rhs.m_regex),
@@ -144,47 +152,20 @@ BreakpointResolverName::AddNameLookup (const ConstString &name, uint32_t name_ty
objc_method.GetFullNames(objc_names, true);
for (ConstString objc_name : objc_names)
{
- LookupInfo lookup;
- lookup.name = name;
- lookup.lookup_name = objc_name;
- lookup.name_type_mask = eFunctionNameTypeFull;
- lookup.match_name_after_lookup = false;
+ Module::LookupInfo lookup;
+ lookup.SetName(name);
+ lookup.SetLookupName(objc_name);
+ lookup.SetNameTypeMask(eFunctionNameTypeFull);
m_lookups.push_back (lookup);
}
}
else
{
- LookupInfo lookup;
- lookup.name = name;
- Module::PrepareForFunctionNameLookup(lookup.name, name_type_mask, m_language, lookup.lookup_name, lookup.name_type_mask, lookup.match_name_after_lookup);
+ Module::LookupInfo lookup(name, name_type_mask, m_language);
m_lookups.push_back (lookup);
}
}
-void
-BreakpointResolverName::LookupInfo::Prune (SymbolContextList &sc_list, size_t start_idx) const
-{
- if (match_name_after_lookup && name)
- {
- SymbolContext sc;
- size_t i = start_idx;
- while (i < sc_list.GetSize())
- {
- if (!sc_list.GetContextAtIndex(i, sc))
- break;
- ConstString full_name (sc.GetFunctionName());
- if (full_name && ::strstr(full_name.GetCString(), name.GetCString()) == nullptr)
- {
- sc_list.RemoveContextAtIndex(i);
- }
- else
- {
- ++i;
- }
- }
- }
-}
-
// FIXME: Right now we look at the module level, and call the module's "FindFunctions".
// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables.
@@ -222,16 +203,17 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter,
case Breakpoint::Exact:
if (context.module_sp)
{
- for (const LookupInfo &lookup : m_lookups)
+ for (const auto &lookup : m_lookups)
{
const size_t start_func_idx = func_list.GetSize();
- context.module_sp->FindFunctions(lookup.lookup_name,
+ context.module_sp->FindFunctions(lookup.GetLookupName(),
nullptr,
- lookup.name_type_mask,
+ lookup.GetNameTypeMask(),
include_symbols,
include_inlines,
append,
func_list);
+
const size_t end_func_idx = func_list.GetSize();
if (start_func_idx < end_func_idx)
@@ -344,7 +326,7 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter,
{
if (filter.AddressPasses(break_addr))
{
- BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
+ BreakpointLocationSP bp_loc_sp (AddLocation(break_addr, &new_location));
bp_loc_sp->SetIsReExported(is_reexported);
if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
{
@@ -379,15 +361,15 @@ BreakpointResolverName::GetDescription (Stream *s)
{
size_t num_names = m_lookups.size();
if (num_names == 1)
- s->Printf("name = '%s'", m_lookups[0].name.GetCString());
+ s->Printf("name = '%s'", m_lookups[0].GetName().GetCString());
else
{
s->Printf("names = {");
- for (size_t i = 0; i < num_names - 1; i++)
+ for (size_t i = 0; i < num_names; i++)
{
- s->Printf ("'%s', ", m_lookups[i].name.GetCString());
+ s->Printf ("%s'%s'", (i == 0 ? "" : ", "), m_lookups[i].GetName().GetCString());
}
- s->Printf ("'%s'}", m_lookups[num_names - 1].name.GetCString());
+ s->Printf ("}");
}
}
if (m_language != eLanguageTypeUnknown)
diff --git a/source/Breakpoint/BreakpointSite.cpp b/source/Breakpoint/BreakpointSite.cpp
index d2aaea098cdb..b4112f7fc012 100644
--- a/source/Breakpoint/BreakpointSite.cpp
+++ b/source/Breakpoint/BreakpointSite.cpp
@@ -23,17 +23,15 @@
using namespace lldb;
using namespace lldb_private;
-BreakpointSite::BreakpointSite(BreakpointSiteList *list,
- const BreakpointLocationSP& owner,
- lldb::addr_t addr,
- bool use_hardware) :
- StoppointLocation(GetNextID(), addr, 0, use_hardware),
- m_type (eSoftware), // Process subclasses need to set this correctly using SetType()
- m_saved_opcode(),
- m_trap_opcode(),
- m_enabled(false), // Need to create it disabled, so the first enable turns it on.
- m_owners(),
- m_owners_mutex(Mutex::eMutexTypeRecursive)
+BreakpointSite::BreakpointSite(BreakpointSiteList *list, const BreakpointLocationSP &owner, lldb::addr_t addr,
+ bool use_hardware)
+ : StoppointLocation(GetNextID(), addr, 0, use_hardware),
+ m_type(eSoftware), // Process subclasses need to set this correctly using SetType()
+ m_saved_opcode(),
+ m_trap_opcode(),
+ m_enabled(false), // Need to create it disabled, so the first enable turns it on.
+ m_owners(),
+ m_owners_mutex()
{
m_owners.Add(owner);
}
@@ -61,7 +59,7 @@ BreakpointSite::GetNextID()
bool
BreakpointSite::ShouldStop (StoppointCallbackContext *context)
{
- Mutex::Locker locker(m_owners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
IncrementHitCount();
return m_owners.ShouldStop (context);
}
@@ -69,7 +67,7 @@ BreakpointSite::ShouldStop (StoppointCallbackContext *context)
bool
BreakpointSite::IsBreakpointAtThisSite (lldb::break_id_t bp_id)
{
- Mutex::Locker locker(m_owners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
const size_t owner_count = m_owners.GetSize();
for (size_t i = 0; i < owner_count; i++)
{
@@ -96,7 +94,7 @@ BreakpointSite::Dump(Stream *s) const
void
BreakpointSite::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
- Mutex::Locker locker(m_owners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
if (level != lldb::eDescriptionLevelBrief)
s->Printf ("breakpoint site: %d at 0x%8.8" PRIx64, GetID(), GetLoadAddress());
m_owners.GetDescription (s, level);
@@ -166,14 +164,14 @@ BreakpointSite::SetEnabled (bool enabled)
void
BreakpointSite::AddOwner (const BreakpointLocationSP &owner)
{
- Mutex::Locker locker(m_owners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
m_owners.Add(owner);
}
size_t
BreakpointSite::RemoveOwner (lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
{
- Mutex::Locker locker(m_owners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
m_owners.Remove(break_id, break_loc_id);
return m_owners.GetSize();
}
@@ -181,28 +179,28 @@ BreakpointSite::RemoveOwner (lldb::break_id_t break_id, lldb::break_id_t break_l
size_t
BreakpointSite::GetNumberOfOwners ()
{
- Mutex::Locker locker(m_owners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
return m_owners.GetSize();
}
BreakpointLocationSP
BreakpointSite::GetOwnerAtIndex (size_t index)
{
- Mutex::Locker locker(m_owners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
return m_owners.GetByIndex (index);
}
bool
BreakpointSite::ValidForThisThread (Thread *thread)
{
- Mutex::Locker locker(m_owners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
return m_owners.ValidForThisThread(thread);
}
void
BreakpointSite::BumpHitCounts()
{
- Mutex::Locker locker(m_owners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations())
{
loc_sp->BumpHitCount();
@@ -255,7 +253,7 @@ BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size, lldb::addr_t *in
size_t
BreakpointSite::CopyOwnersList (BreakpointLocationCollection &out_collection)
{
- Mutex::Locker locker(m_owners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations())
{
out_collection.Add(loc_sp);
diff --git a/source/Breakpoint/BreakpointSiteList.cpp b/source/Breakpoint/BreakpointSiteList.cpp
index 1eaadb62a384..de9a5ad0b310 100644
--- a/source/Breakpoint/BreakpointSiteList.cpp
+++ b/source/Breakpoint/BreakpointSiteList.cpp
@@ -19,9 +19,7 @@
using namespace lldb;
using namespace lldb_private;
-BreakpointSiteList::BreakpointSiteList() :
- m_mutex (Mutex::eMutexTypeRecursive),
- m_bp_site_list()
+BreakpointSiteList::BreakpointSiteList() : m_mutex(), m_bp_site_list()
{
}
@@ -36,7 +34,7 @@ lldb::break_id_t
BreakpointSiteList::Add(const BreakpointSiteSP &bp)
{
lldb::addr_t bp_site_load_addr = bp->GetLoadAddress();
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::iterator iter = m_bp_site_list.find (bp_site_load_addr);
if (iter == m_bp_site_list.end())
@@ -81,7 +79,7 @@ BreakpointSiteList::FindIDByAddress (lldb::addr_t addr)
bool
BreakpointSiteList::Remove (lldb::break_id_t break_id)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::iterator pos = GetIDIterator(break_id); // Predicate
if (pos != m_bp_site_list.end())
{
@@ -94,7 +92,7 @@ BreakpointSiteList::Remove (lldb::break_id_t break_id)
bool
BreakpointSiteList::RemoveByAddress (lldb::addr_t address)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::iterator pos = m_bp_site_list.find(address);
if (pos != m_bp_site_list.end())
{
@@ -124,7 +122,7 @@ private:
BreakpointSiteList::collection::iterator
BreakpointSiteList::GetIDIterator (lldb::break_id_t break_id)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return std::find_if(m_bp_site_list.begin(), m_bp_site_list.end(), // Search full range
BreakpointSiteIDMatches(break_id)); // Predicate
}
@@ -132,7 +130,7 @@ BreakpointSiteList::GetIDIterator (lldb::break_id_t break_id)
BreakpointSiteList::collection::const_iterator
BreakpointSiteList::GetIDConstIterator (lldb::break_id_t break_id) const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return std::find_if(m_bp_site_list.begin(), m_bp_site_list.end(), // Search full range
BreakpointSiteIDMatches(break_id)); // Predicate
}
@@ -140,7 +138,7 @@ BreakpointSiteList::GetIDConstIterator (lldb::break_id_t break_id) const
BreakpointSiteSP
BreakpointSiteList::FindByID (lldb::break_id_t break_id)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
BreakpointSiteSP stop_sp;
collection::iterator pos = GetIDIterator(break_id);
if (pos != m_bp_site_list.end())
@@ -152,7 +150,7 @@ BreakpointSiteList::FindByID (lldb::break_id_t break_id)
const BreakpointSiteSP
BreakpointSiteList::FindByID (lldb::break_id_t break_id) const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
BreakpointSiteSP stop_sp;
collection::const_iterator pos = GetIDConstIterator(break_id);
if (pos != m_bp_site_list.end())
@@ -165,7 +163,7 @@ BreakpointSiteSP
BreakpointSiteList::FindByAddress (lldb::addr_t addr)
{
BreakpointSiteSP found_sp;
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::iterator iter = m_bp_site_list.find(addr);
if (iter != m_bp_site_list.end())
found_sp = iter->second;
@@ -175,7 +173,7 @@ BreakpointSiteList::FindByAddress (lldb::addr_t addr)
bool
BreakpointSiteList::BreakpointSiteContainsBreakpoint (lldb::break_id_t bp_site_id, lldb::break_id_t bp_id)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::const_iterator pos = GetIDConstIterator(bp_site_id);
if (pos != m_bp_site_list.end())
return pos->second->IsBreakpointAtThisSite (bp_id);
@@ -200,7 +198,7 @@ BreakpointSiteList::Dump (Stream *s) const
void
BreakpointSiteList::ForEach (std::function <void(BreakpointSite *)> const &callback)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
for (auto pair : m_bp_site_list)
callback (pair.second.get());
}
@@ -210,8 +208,8 @@ BreakpointSiteList::FindInRange (lldb::addr_t lower_bound, lldb::addr_t upper_bo
{
if (lower_bound > upper_bound)
return false;
-
- Mutex::Locker locker(m_mutex);
+
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::const_iterator lower, upper, pos;
lower = m_bp_site_list.lower_bound(lower_bound);
if (lower == m_bp_site_list.end()
diff --git a/source/Breakpoint/Makefile b/source/Breakpoint/Makefile
deleted file mode 100644
index 223e4c24465f..000000000000
--- a/source/Breakpoint/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Breakpoint/Makefile --------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LIBRARYNAME := lldbBreakpoint
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Breakpoint/WatchpointList.cpp b/source/Breakpoint/WatchpointList.cpp
index 64bf5cd63ed0..f662c24cecee 100644
--- a/source/Breakpoint/WatchpointList.cpp
+++ b/source/Breakpoint/WatchpointList.cpp
@@ -18,10 +18,7 @@
using namespace lldb;
using namespace lldb_private;
-WatchpointList::WatchpointList() :
- m_watchpoints (),
- m_mutex (Mutex::eMutexTypeRecursive),
- m_next_wp_id (0)
+WatchpointList::WatchpointList() : m_watchpoints(), m_mutex(), m_next_wp_id(0)
{
}
@@ -33,7 +30,7 @@ WatchpointList::~WatchpointList()
lldb::watch_id_t
WatchpointList::Add (const WatchpointSP &wp_sp, bool notify)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
wp_sp->SetID(++m_next_wp_id);
m_watchpoints.push_back(wp_sp);
if (notify)
@@ -54,7 +51,7 @@ WatchpointList::Dump (Stream *s) const
void
WatchpointList::DumpWithLevel (Stream *s, lldb::DescriptionLevel description_level) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
s->Printf("%p: ", static_cast<const void*>(this));
//s->Indent();
s->Printf("WatchpointList with %" PRIu64 " Watchpoints:\n",
@@ -70,7 +67,7 @@ const WatchpointSP
WatchpointList::FindByAddress (lldb::addr_t addr) const
{
WatchpointSP wp_sp;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_watchpoints.empty())
{
wp_collection::const_iterator pos, end = m_watchpoints.end();
@@ -93,7 +90,7 @@ const WatchpointSP
WatchpointList::FindBySpec (std::string spec) const
{
WatchpointSP wp_sp;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_watchpoints.empty())
{
wp_collection::const_iterator pos, end = m_watchpoints.end();
@@ -142,7 +139,7 @@ WatchpointSP
WatchpointList::FindByID (lldb::watch_id_t watch_id) const
{
WatchpointSP wp_sp;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
wp_collection::const_iterator pos = GetIDConstIterator(watch_id);
if (pos != m_watchpoints.end())
wp_sp = *pos;
@@ -175,7 +172,7 @@ WatchpointList::FindIDBySpec (std::string spec)
WatchpointSP
WatchpointList::GetByIndex (uint32_t i)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
WatchpointSP wp_sp;
if (i < m_watchpoints.size())
{
@@ -189,7 +186,7 @@ WatchpointList::GetByIndex (uint32_t i)
const WatchpointSP
WatchpointList::GetByIndex (uint32_t i) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
WatchpointSP wp_sp;
if (i < m_watchpoints.size())
{
@@ -213,7 +210,7 @@ WatchpointList::GetWatchpointIDs() const
bool
WatchpointList::Remove (lldb::watch_id_t watch_id, bool notify)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
wp_collection::iterator pos = GetIDIterator(watch_id);
if (pos != m_watchpoints.end())
{
@@ -234,7 +231,7 @@ uint32_t
WatchpointList::GetHitCount () const
{
uint32_t hit_count = 0;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
wp_collection::const_iterator pos, end = m_watchpoints.end();
for (pos = m_watchpoints.begin(); pos != end; ++pos)
hit_count += (*pos)->GetHitCount();
@@ -261,7 +258,7 @@ WatchpointList::ShouldStop (StoppointCallbackContext *context, lldb::watch_id_t
void
WatchpointList::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
wp_collection::iterator pos, end = m_watchpoints.end();
for (pos = m_watchpoints.begin(); pos != end; ++pos)
@@ -274,7 +271,7 @@ WatchpointList::GetDescription (Stream *s, lldb::DescriptionLevel level)
void
WatchpointList::SetEnabledAll (bool enabled)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
wp_collection::iterator pos, end = m_watchpoints.end();
for (pos = m_watchpoints.begin(); pos != end; ++pos)
@@ -284,7 +281,7 @@ WatchpointList::SetEnabledAll (bool enabled)
void
WatchpointList::RemoveAll (bool notify)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (notify)
{
@@ -305,7 +302,7 @@ WatchpointList::RemoveAll (bool notify)
}
void
-WatchpointList::GetListMutex (Mutex::Locker &locker)
+WatchpointList::GetListMutex(std::unique_lock<std::recursive_mutex> &lock)
{
- return locker.Lock (m_mutex);
+ lock = std::unique_lock<std::recursive_mutex>(m_mutex);
}
diff --git a/source/Commands/CommandCompletions.cpp b/source/Commands/CommandCompletions.cpp
index 37696e3bbfdb..dd0ecb4b82e9 100644
--- a/source/Commands/CommandCompletions.cpp
+++ b/source/Commands/CommandCompletions.cpp
@@ -15,11 +15,14 @@
// C++ Includes
// Other libraries and framework includes
+#include "llvm/ADT/SmallString.h"
+
// Project includes
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/FileSpecList.h"
-#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -36,7 +39,7 @@ using namespace lldb_private;
CommandCompletions::CommonCompletionElement
CommandCompletions::g_common_completions[] =
{
- {eCustomCompletion, NULL},
+ {eCustomCompletion, nullptr},
{eSourceFileCompletion, CommandCompletions::SourceFiles},
{eDiskFileCompletion, CommandCompletions::DiskFiles},
{eDiskDirectoryCompletion, CommandCompletions::DiskDirectories},
@@ -46,21 +49,18 @@ CommandCompletions::g_common_completions[] =
{ePlatformPluginCompletion, CommandCompletions::PlatformPluginNames},
{eArchitectureCompletion, CommandCompletions::ArchitectureNames},
{eVariablePathCompletion, CommandCompletions::VariablePath},
- {eNoCompletion, NULL} // This one has to be last in the list.
+ {eNoCompletion, nullptr} // This one has to be last in the list.
};
bool
-CommandCompletions::InvokeCommonCompletionCallbacks
-(
- CommandInterpreter &interpreter,
- uint32_t completion_mask,
- const char *completion_str,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches
-)
+CommandCompletions::InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter,
+ uint32_t completion_mask,
+ const char *completion_str,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ StringList &matches)
{
bool handled = false;
@@ -72,7 +72,7 @@ CommandCompletions::InvokeCommonCompletionCallbacks
if (g_common_completions[i].type == eNoCompletion)
break;
else if ((g_common_completions[i].type & completion_mask) == g_common_completions[i].type
- && g_common_completions[i].callback != NULL)
+ && g_common_completions[i].callback != nullptr)
{
handled = true;
g_common_completions[i].callback (interpreter,
@@ -88,16 +88,13 @@ CommandCompletions::InvokeCommonCompletionCallbacks
}
int
-CommandCompletions::SourceFiles
-(
- CommandInterpreter &interpreter,
- const char *partial_file_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches
-)
+CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ StringList &matches)
{
word_complete = true;
// Find some way to switch "include support files..."
@@ -108,7 +105,7 @@ CommandCompletions::SourceFiles
max_return_elements,
matches);
- if (searcher == NULL)
+ if (searcher == nullptr)
{
lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
SearchFilterForUnconstrainedSearches null_searcher (target_sp);
@@ -166,8 +163,7 @@ FileSpec::EnumerateDirectoryResult DiskFilesOrDirectoriesCallback(void *baton, F
isa_directory = true;
else if (file_type == FileSpec::eFileTypeSymbolicLink)
{
- struct stat stat_buf;
- if ((stat(partial_name_copy, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode))
+ if (FileSpec(partial_name_copy, false).IsDirectory())
isa_directory = true;
}
@@ -187,13 +183,10 @@ FileSpec::EnumerateDirectoryResult DiskFilesOrDirectoriesCallback(void *baton, F
}
static int
-DiskFilesOrDirectories
-(
- const char *partial_file_name,
- bool only_directories,
- bool &saw_directory,
- StringList &matches
-)
+DiskFilesOrDirectories(const char *partial_file_name,
+ bool only_directories,
+ bool &saw_directory,
+ StringList &matches)
{
// I'm going to use the "glob" function with GLOB_TILDE for user directory expansion.
// If it is not defined on your host system, you'll need to implement it yourself...
@@ -224,7 +217,7 @@ DiskFilesOrDirectories
// This will store the resolved form of the containing directory
llvm::SmallString<64> containing_part;
- if (end_ptr == NULL)
+ if (end_ptr == nullptr)
{
// There's no directory. If the thing begins with a "~" then this is a bare
// user name.
@@ -312,18 +305,14 @@ DiskFilesOrDirectories
}
int
-CommandCompletions::DiskFiles
-(
- CommandInterpreter &interpreter,
- const char *partial_file_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches
-)
+CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ StringList &matches)
{
-
int ret_val = DiskFilesOrDirectories (partial_file_name,
false,
word_complete,
@@ -333,16 +322,13 @@ CommandCompletions::DiskFiles
}
int
-CommandCompletions::DiskDirectories
-(
- CommandInterpreter &interpreter,
- const char *partial_file_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches
-)
+CommandCompletions::DiskDirectories(CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ StringList &matches)
{
int ret_val = DiskFilesOrDirectories (partial_file_name,
true,
@@ -353,16 +339,13 @@ CommandCompletions::DiskDirectories
}
int
-CommandCompletions::Modules
-(
- CommandInterpreter &interpreter,
- const char *partial_file_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches
-)
+CommandCompletions::Modules(CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ StringList &matches)
{
word_complete = true;
ModuleCompleter completer (interpreter,
@@ -371,7 +354,7 @@ CommandCompletions::Modules
max_return_elements,
matches);
- if (searcher == NULL)
+ if (searcher == nullptr)
{
lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
SearchFilterForUnconstrainedSearches null_searcher (target_sp);
@@ -385,15 +368,13 @@ CommandCompletions::Modules
}
int
-CommandCompletions::Symbols
-(
- CommandInterpreter &interpreter,
- const char *partial_file_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches)
+CommandCompletions::Symbols(CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ StringList &matches)
{
word_complete = true;
SymbolCompleter completer (interpreter,
@@ -402,7 +383,7 @@ CommandCompletions::Symbols
max_return_elements,
matches);
- if (searcher == NULL)
+ if (searcher == nullptr)
{
lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
SearchFilterForUnconstrainedSearches null_searcher (target_sp);
@@ -433,7 +414,7 @@ CommandCompletions::SettingsNames (CommandInterpreter &interpreter,
if (properties_sp)
{
StreamString strm;
- properties_sp->DumpValue(NULL, strm, OptionValue::eDumpOptionName);
+ properties_sp->DumpValue(nullptr, strm, OptionValue::eDumpOptionName);
const std::string &str = strm.GetString();
g_property_names.SplitIntoLines(str.c_str(), str.size());
}
@@ -445,7 +426,6 @@ CommandCompletions::SettingsNames (CommandInterpreter &interpreter,
return num_matches;
}
-
int
CommandCompletions::PlatformPluginNames (CommandInterpreter &interpreter,
const char *partial_name,
@@ -474,7 +454,6 @@ CommandCompletions::ArchitectureNames (CommandInterpreter &interpreter,
return num_matches;
}
-
int
CommandCompletions::VariablePath (CommandInterpreter &interpreter,
const char *partial_name,
@@ -487,15 +466,11 @@ CommandCompletions::VariablePath (CommandInterpreter &interpreter,
return Variable::AutoComplete (interpreter.GetExecutionContext(), partial_name, matches, word_complete);
}
-
-CommandCompletions::Completer::Completer
-(
- CommandInterpreter &interpreter,
- const char *completion_str,
- int match_start_point,
- int max_return_elements,
- StringList &matches
-) :
+CommandCompletions::Completer::Completer(CommandInterpreter &interpreter,
+ const char *completion_str,
+ int match_start_point,
+ int max_return_elements,
+ StringList &matches) :
m_interpreter (interpreter),
m_completion_str (completion_str),
m_match_start_point (match_start_point),
@@ -504,24 +479,18 @@ CommandCompletions::Completer::Completer
{
}
-CommandCompletions::Completer::~Completer ()
-{
-
-}
+CommandCompletions::Completer::~Completer() = default;
//----------------------------------------------------------------------
// SourceFileCompleter
//----------------------------------------------------------------------
-CommandCompletions::SourceFileCompleter::SourceFileCompleter
-(
- CommandInterpreter &interpreter,
- bool include_support_files,
- const char *completion_str,
- int match_start_point,
- int max_return_elements,
- StringList &matches
-) :
+CommandCompletions::SourceFileCompleter::SourceFileCompleter(CommandInterpreter &interpreter,
+ bool include_support_files,
+ const char *completion_str,
+ int match_start_point,
+ int max_return_elements,
+ StringList &matches) :
CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches),
m_include_support_files (include_support_files),
m_matching_files()
@@ -538,14 +507,12 @@ CommandCompletions::SourceFileCompleter::GetDepth()
}
Searcher::CallbackReturn
-CommandCompletions::SourceFileCompleter::SearchCallback (
- SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool complete
-)
+CommandCompletions::SourceFileCompleter::SearchCallback(SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool complete)
{
- if (context.comp_unit != NULL)
+ if (context.comp_unit != nullptr)
{
if (m_include_support_files)
{
@@ -568,7 +535,6 @@ CommandCompletions::SourceFileCompleter::SearchCallback (
m_matching_files.AppendIfUnique(sfile_spec);
}
}
-
}
else
{
@@ -603,7 +569,6 @@ CommandCompletions::SourceFileCompleter::DoCompletion (SearchFilter *filter)
m_matches.AppendString (m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString());
}
return m_matches.GetSize();
-
}
//----------------------------------------------------------------------
@@ -613,29 +578,24 @@ CommandCompletions::SourceFileCompleter::DoCompletion (SearchFilter *filter)
static bool
regex_chars (const char comp)
{
- if (comp == '[' || comp == ']' ||
- comp == '(' || comp == ')' ||
- comp == '{' || comp == '}' ||
- comp == '+' ||
- comp == '.' ||
- comp == '*' ||
- comp == '|' ||
- comp == '^' ||
- comp == '$' ||
- comp == '\\' ||
- comp == '?')
- return true;
- else
- return false;
+ return (comp == '[' || comp == ']' ||
+ comp == '(' || comp == ')' ||
+ comp == '{' || comp == '}' ||
+ comp == '+' ||
+ comp == '.' ||
+ comp == '*' ||
+ comp == '|' ||
+ comp == '^' ||
+ comp == '$' ||
+ comp == '\\' ||
+ comp == '?');
}
-CommandCompletions::SymbolCompleter::SymbolCompleter
-(
- CommandInterpreter &interpreter,
- const char *completion_str,
- int match_start_point,
- int max_return_elements,
- StringList &matches
-) :
+
+CommandCompletions::SymbolCompleter::SymbolCompleter(CommandInterpreter &interpreter,
+ const char *completion_str,
+ int match_start_point,
+ int max_return_elements,
+ StringList &matches) :
CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches)
{
std::string regex_str;
@@ -665,12 +625,10 @@ CommandCompletions::SymbolCompleter::GetDepth()
}
Searcher::CallbackReturn
-CommandCompletions::SymbolCompleter::SearchCallback (
- SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool complete
-)
+CommandCompletions::SymbolCompleter::SearchCallback(SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool complete)
{
if (context.module_sp)
{
@@ -709,14 +667,11 @@ CommandCompletions::SymbolCompleter::DoCompletion (SearchFilter *filter)
//----------------------------------------------------------------------
// ModuleCompleter
//----------------------------------------------------------------------
-CommandCompletions::ModuleCompleter::ModuleCompleter
-(
- CommandInterpreter &interpreter,
- const char *completion_str,
- int match_start_point,
- int max_return_elements,
- StringList &matches
-) :
+CommandCompletions::ModuleCompleter::ModuleCompleter(CommandInterpreter &interpreter,
+ const char *completion_str,
+ int match_start_point,
+ int max_return_elements,
+ StringList &matches) :
CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches)
{
FileSpec partial_spec (m_completion_str.c_str(), false);
@@ -731,12 +686,10 @@ CommandCompletions::ModuleCompleter::GetDepth()
}
Searcher::CallbackReturn
-CommandCompletions::ModuleCompleter::SearchCallback (
- SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool complete
-)
+CommandCompletions::ModuleCompleter::SearchCallback(SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool complete)
{
if (context.module_sp)
{
diff --git a/source/Commands/CommandObjectApropos.cpp b/source/Commands/CommandObjectApropos.cpp
index 47890b1e83b7..29e1f14e3b28 100644
--- a/source/Commands/CommandObjectApropos.cpp
+++ b/source/Commands/CommandObjectApropos.cpp
@@ -7,16 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectApropos.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "CommandObjectApropos.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/Property.h"
-
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -27,11 +25,8 @@ using namespace lldb_private;
// CommandObjectApropos
//-------------------------------------------------------------------------
-CommandObjectApropos::CommandObjectApropos (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "apropos",
- "Find a list of debugger commands related to a particular word/subject.",
- NULL)
+CommandObjectApropos::CommandObjectApropos(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "apropos", "List debugger commands related to a word or subject.", nullptr)
{
CommandArgumentEntry arg;
CommandArgumentData search_word_arg;
@@ -47,10 +42,7 @@ CommandObjectApropos::CommandObjectApropos (CommandInterpreter &interpreter) :
m_arguments.push_back (arg);
}
-CommandObjectApropos::~CommandObjectApropos()
-{
-}
-
+CommandObjectApropos::~CommandObjectApropos() = default;
bool
CommandObjectApropos::DoExecute (Args& args, CommandReturnObject &result)
@@ -60,20 +52,17 @@ CommandObjectApropos::DoExecute (Args& args, CommandReturnObject &result)
if (argc == 1)
{
const char *search_word = args.GetArgumentAtIndex(0);
- if ((search_word != NULL)
+ if ((search_word != nullptr)
&& (strlen (search_word) > 0))
{
// The bulk of the work must be done inside the Command Interpreter, since the command dictionary
// is private.
StringList commands_found;
StringList commands_help;
- StringList user_commands_found;
- StringList user_commands_help;
- m_interpreter.FindCommandsForApropos (search_word, commands_found, commands_help, true, false);
- m_interpreter.FindCommandsForApropos (search_word, user_commands_found, user_commands_help, false, true);
+ m_interpreter.FindCommandsForApropos (search_word, commands_found, commands_help, true, true, true);
- if (commands_found.GetSize() == 0 && user_commands_found.GetSize() == 0)
+ if (commands_found.GetSize() == 0)
{
result.AppendMessageWithFormat ("No commands found pertaining to '%s'. Try 'help' to see a complete list of debugger commands.\n", search_word);
}
@@ -81,7 +70,7 @@ CommandObjectApropos::DoExecute (Args& args, CommandReturnObject &result)
{
if (commands_found.GetSize() > 0)
{
- result.AppendMessageWithFormat ("The following built-in commands may relate to '%s':\n", search_word);
+ result.AppendMessageWithFormat ("The following commands may relate to '%s':\n", search_word);
size_t max_len = 0;
for (size_t i = 0; i < commands_found.GetSize(); ++i)
@@ -97,33 +86,9 @@ CommandObjectApropos::DoExecute (Args& args, CommandReturnObject &result)
"--",
commands_help.GetStringAtIndex(i),
max_len);
- if (user_commands_found.GetSize() > 0)
- result.AppendMessage("");
- }
-
- if (user_commands_found.GetSize() > 0)
- {
- result.AppendMessageWithFormat ("The following user commands may relate to '%s':\n", search_word);
- size_t max_len = 0;
-
- for (size_t i = 0; i < user_commands_found.GetSize(); ++i)
- {
- size_t len = strlen (user_commands_found.GetStringAtIndex (i));
- if (len > max_len)
- max_len = len;
- }
-
- for (size_t i = 0; i < user_commands_found.GetSize(); ++i)
- m_interpreter.OutputFormattedHelpText (result.GetOutputStream(),
- user_commands_found.GetStringAtIndex(i),
- "--",
- user_commands_help.GetStringAtIndex(i),
- max_len);
}
-
}
-
std::vector<const Property *> properties;
const size_t num_properties = m_interpreter.GetDebugger().Apropos(search_word, properties);
if (num_properties)
diff --git a/source/Commands/CommandObjectArgs.cpp b/source/Commands/CommandObjectArgs.cpp
index 9f22bba78c55..206a26f45e4d 100644
--- a/source/Commands/CommandObjectArgs.cpp
+++ b/source/Commands/CommandObjectArgs.cpp
@@ -7,12 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectArgs.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "CommandObjectArgs.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -44,10 +43,7 @@ CommandObjectArgs::CommandOptions::CommandOptions (CommandInterpreter &interpret
OptionParsingStarting();
}
-
-CommandObjectArgs::CommandOptions::~CommandOptions ()
-{
-}
+CommandObjectArgs::CommandOptions::~CommandOptions() = default;
Error
CommandObjectArgs::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
@@ -80,9 +76,7 @@ CommandObjectArgs::CommandObjectArgs (CommandInterpreter &interpreter) :
{
}
-CommandObjectArgs::~CommandObjectArgs ()
-{
-}
+CommandObjectArgs::~CommandObjectArgs() = default;
Options *
CommandObjectArgs::GetOptions ()
@@ -94,8 +88,7 @@ bool
CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result)
{
ConstString target_triple;
-
-
+
Process *process = m_exe_ctx.GetProcessPtr();
if (!process)
{
@@ -263,7 +256,6 @@ CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result)
OptionDefinition
CommandObjectArgs::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp
index bb59e1f82e8d..6a71389a3f69 100644
--- a/source/Commands/CommandObjectBreakpoint.cpp
+++ b/source/Commands/CommandObjectBreakpoint.cpp
@@ -7,13 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectBreakpoint.h"
-#include "CommandObjectBreakpointCommand.h"
-
// C Includes
// C++ Includes
+#include <vector>
+
// Other libraries and framework includes
// Project includes
+#include "CommandObjectBreakpoint.h"
+#include "CommandObjectBreakpointCommand.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
@@ -33,8 +34,6 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"
-#include <vector>
-
using namespace lldb;
using namespace lldb_private;
@@ -51,11 +50,9 @@ AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel leve
// CommandObjectBreakpointSet
//-------------------------------------------------------------------------
-
class CommandObjectBreakpointSet : public CommandObjectParsed
{
public:
-
typedef enum BreakpointSetType
{
eSetTypeInvalid,
@@ -76,8 +73,7 @@ public:
{
}
-
- ~CommandObjectBreakpointSet () override {}
+ ~CommandObjectBreakpointSet() override = default;
Options *
GetOptions () override
@@ -88,7 +84,6 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_condition (),
@@ -118,8 +113,7 @@ public:
{
}
-
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -153,6 +147,7 @@ public:
error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
break;
}
+
case 'c':
m_condition.assign(option_arg);
break;
@@ -217,12 +212,10 @@ public:
break;
case 'i':
- {
m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
if (m_ignore_count == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
break;
- }
case 'K':
{
@@ -284,6 +277,16 @@ public:
m_breakpoint_names.push_back (option_arg);
break;
+ case 'R':
+ {
+ ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
+ lldb::addr_t tmp_offset_addr;
+ tmp_offset_addr = Args::StringToAddress(&exe_ctx, option_arg, 0, &error);
+ if (error.Success())
+ m_offset_addr = tmp_offset_addr;
+ }
+ break;
+
case 'o':
m_one_shot = true;
break;
@@ -306,10 +309,8 @@ public:
break;
case 's':
- {
m_modules.AppendIfUnique (FileSpec (option_arg, false));
break;
- }
case 'S':
m_func_names.push_back (option_arg);
@@ -317,12 +318,10 @@ public:
break;
case 't' :
- {
m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
if (m_thread_id == LLDB_INVALID_THREAD_ID)
error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
- }
- break;
+ break;
case 'T':
m_thread_name.assign (option_arg);
@@ -338,14 +337,15 @@ public:
break;
case 'x':
- {
m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
if (m_thread_id == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
-
- }
- break;
+ break;
+ case 'X':
+ m_source_regex_func_names.insert(option_arg);
+ break;
+
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -353,6 +353,7 @@ public:
return error;
}
+
void
OptionParsingStarting () override
{
@@ -366,6 +367,7 @@ public:
m_source_text_regexp.clear();
m_modules.Clear();
m_load_addr = LLDB_INVALID_ADDRESS;
+ m_offset_addr = 0;
m_ignore_count = 0;
m_thread_id = LLDB_INVALID_THREAD_ID;
m_thread_index = UINT32_MAX;
@@ -383,6 +385,7 @@ public:
m_all_files = false;
m_exception_extra_args.Clear();
m_move_to_nearest_code = eLazyBoolCalculate;
+ m_source_regex_func_names.clear();
}
const OptionDefinition*
@@ -408,6 +411,7 @@ public:
std::string m_source_text_regexp;
FileSpecList m_modules;
lldb::addr_t m_load_addr;
+ lldb::addr_t m_offset_addr;
uint32_t m_ignore_count;
lldb::tid_t m_thread_id;
uint32_t m_thread_index;
@@ -424,7 +428,7 @@ public:
bool m_all_files;
Args m_exception_extra_args;
LazyBool m_move_to_nearest_code;
-
+ std::unordered_set<std::string> m_source_regex_func_names;
};
protected:
@@ -464,9 +468,13 @@ protected:
else if (m_options.m_exception_language != eLanguageTypeUnknown)
break_type = eSetTypeException;
- Breakpoint *bp = NULL;
+ Breakpoint *bp = nullptr;
FileSpec module_spec;
const bool internal = false;
+
+ // If the user didn't specify skip-prologue, having an offset should turn that off.
+ if (m_options.m_offset_addr != 0 && m_options.m_skip_prologue == eLazyBoolCalculate)
+ m_options.m_skip_prologue = eLazyBoolNo;
switch (break_type)
{
@@ -498,6 +506,7 @@ protected:
bp = target->CreateBreakpoint (&(m_options.m_modules),
file,
m_options.m_line_num,
+ m_options.m_offset_addr,
check_inlines,
m_options.m_skip_prologue,
internal,
@@ -545,6 +554,7 @@ protected:
m_options.m_func_names,
name_type_mask,
m_options.m_language,
+ m_options.m_offset_addr,
m_options.m_skip_prologue,
internal,
m_options.m_hardware).get();
@@ -604,6 +614,7 @@ protected:
}
bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
&(m_options.m_filenames),
+ m_options.m_source_regex_func_names,
regexp,
internal,
m_options.m_hardware,
@@ -701,7 +712,7 @@ private:
if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
{
StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
- if (cur_frame == NULL)
+ if (cur_frame == nullptr)
{
result.AppendError ("No selected frame to use to find the default file.");
result.SetStatus (eReturnStatusFailed);
@@ -733,60 +744,62 @@ private:
CommandOptions m_options;
};
+
// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
+#define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
#define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
#define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) )
OptionDefinition
CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
+ { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
"Set the breakpoint only in this shared library. "
"Can repeat this option multiple times to specify multiple shared libraries."},
- { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount,
+ { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount,
"Set the number of times this breakpoint is skipped before stopping." },
- { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"The breakpoint is deleted the first time it causes a stop." },
- { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
+ { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression,
"The breakpoint stops only if this condition expression evaluates to true."},
- { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
+ { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex,
"The breakpoint stops only for the thread whose indeX matches this argument."},
- { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
+ { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID,
"The breakpoint stops only for the thread whose TID matches this argument."},
- { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
+ { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName,
"The breakpoint stops only for the thread whose thread name matches this argument."},
- { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Require the breakpoint to use hardware breakpoints."},
- { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
+ { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName,
"The breakpoint stops only for threads in the queue whose name is given by this argument."},
- { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
+ { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
"Specifies the source file in which to set this breakpoint. "
"Note, by default lldb only looks for files that are #included if they use the standard include file extensions. "
"To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
" to \"always\"."},
- { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
+ { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
"Specifies the line number on which to set this breakpoint."},
// Comment out this option for the moment, as we don't actually use it, but will in the future.
// This way users won't see it, but the infrastructure is left in place.
- // { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "<column>",
+ // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>",
// "Set the breakpoint by source location at this particular column."},
- { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
+ { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression,
"Set the breakpoint at the specified address. "
"If the address maps uniquely to a particular "
"binary, then the address will be converted to a \"file\" address, so that the breakpoint will track that binary+offset no matter where "
@@ -796,64 +809,72 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
"subsequent reloads. The module need not have been loaded at the time you specify this breakpoint, and will "
"get resolved when the module is loaded."},
- { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
+ { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
"Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple names" },
- { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
+ { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
+ "When used with '-p' limits the source regex to source contained in the named functions. Can be repeated multiple times." },
+
+ { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
"Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
"for Objective C this means a full function prototype with class and selector. "
"Can be repeated multiple times to make one breakpoint for multiple names." },
- { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
+ { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSelector,
"Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
- { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
+ { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeMethod,
"Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." },
- { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
+ { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression,
"Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
- { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
+ { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
"Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
"Can be repeated multiple times to make one breakpoint for multiple symbols." },
- { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
+ { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression,
"Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
"specified with the -f option. The -f option can be specified more than once. "
- "If no source files are specified, uses the current \"default source file\"" },
+ "If no source files are specified, uses the current \"default source file\". "
+ "If you want to match against all source files, pass the \"--all-files\" option." },
- { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"All files are searched for source pattern matches." },
- { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
+ { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,
"Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
- { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
+ { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
"Set the breakpoint on exception throW." },
- { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
+ { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
"Set the breakpoint on exception catcH." },
// Don't add this option till it actually does something useful...
-// { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName,
+// { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName,
// "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" },
- { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
+ { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,
"Specifies the Language to use when interpreting the breakpoint's expression (note: currently only implemented for setting breakpoints on identifiers). If not set the target.language setting is used." },
- { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
+ { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
"sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." },
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
- { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
- "Adds this to the list of names for this breakopint."},
+ { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName,
+ "Adds this to the list of names for this breakpoint."},
+
+ { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress,
+ "Add the specified offset to whatever address(es) the breakpoint resolves to. "
+ "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries."},
- { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
+ { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
"Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." },
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -864,14 +885,13 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
class CommandObjectBreakpointModify : public CommandObjectParsed
{
public:
-
CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "breakpoint modify",
- "Modify the options on a breakpoint or set of breakpoints in the executable. "
- "If no breakpoint is specified, acts on the last created breakpoint. "
- "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "breakpoint modify",
+ "Modify the options on a breakpoint or set of breakpoints in the executable. "
+ "If no breakpoint is specified, acts on the last created breakpoint. "
+ "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
+ nullptr),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -880,8 +900,7 @@ public:
m_arguments.push_back (arg);
}
-
- ~CommandObjectBreakpointModify () override {}
+ ~CommandObjectBreakpointModify() override = default;
Options *
GetOptions () override
@@ -892,7 +911,6 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_ignore_count (0),
@@ -914,7 +932,7 @@ public:
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -925,7 +943,7 @@ public:
switch (short_option)
{
case 'c':
- if (option_arg != NULL)
+ if (option_arg != nullptr)
m_condition.assign (option_arg);
else
m_condition.clear();
@@ -943,12 +961,10 @@ public:
m_enable_value = true;
break;
case 'i':
- {
m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
if (m_ignore_count == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
- }
- break;
+ break;
case 'o':
{
bool value, success;
@@ -963,7 +979,6 @@ public:
}
break;
case 't' :
- {
if (option_arg[0] == '\0')
{
m_thread_id = LLDB_INVALID_THREAD_ID;
@@ -977,24 +992,22 @@ public:
else
m_thread_id_passed = true;
}
- }
- break;
+ break;
case 'T':
- if (option_arg != NULL)
+ if (option_arg != nullptr)
m_thread_name.assign (option_arg);
else
m_thread_name.clear();
m_name_passed = true;
break;
case 'q':
- if (option_arg != NULL)
+ if (option_arg != nullptr)
m_queue_name.assign (option_arg);
else
m_queue_name.clear();
m_queue_passed = true;
break;
case 'x':
- {
if (option_arg[0] == '\n')
{
m_thread_index = UINT32_MAX;
@@ -1008,8 +1021,7 @@ public:
else
m_thread_index_passed = true;
}
- }
- break;
+ break;
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -1017,6 +1029,7 @@ public:
return error;
}
+
void
OptionParsingStarting () override
{
@@ -1043,7 +1056,6 @@ public:
return g_option_table;
}
-
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table[];
@@ -1066,7 +1078,6 @@ public:
bool m_condition_passed;
bool m_one_shot_passed;
bool m_use_dummy;
-
};
protected:
@@ -1074,16 +1085,16 @@ protected:
DoExecute (Args& command, CommandReturnObject &result) override
{
Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
result.SetStatus (eReturnStatusFailed);
return false;
}
- Mutex::Locker locker;
- target->GetBreakpointList().GetListMutex(locker);
-
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
+
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
@@ -1163,18 +1174,18 @@ private:
OptionDefinition
CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
-{ LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
-{ LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
-{ LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
-{ LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
-{ LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
-{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
-{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
-{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
-{ LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
-
-{ 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
+{ LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
+{ LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
+{ LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
+{ LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
+{ LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
+{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
+{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint."},
+{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint."},
+{ LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+
+{ 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -1186,10 +1197,10 @@ class CommandObjectBreakpointEnable : public CommandObjectParsed
{
public:
CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "enable",
- "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "enable",
+ "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
+ nullptr)
{
CommandArgumentEntry arg;
CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
@@ -1197,23 +1208,22 @@ public:
m_arguments.push_back (arg);
}
-
- ~CommandObjectBreakpointEnable () override {}
+ ~CommandObjectBreakpointEnable() override = default;
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
Target *target = GetSelectedOrDummyTarget();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
result.SetStatus (eReturnStatusFailed);
return false;
}
- Mutex::Locker locker;
- target->GetBreakpointList().GetListMutex(locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
const BreakpointList &breakpoints = target->GetBreakpointList();
@@ -1284,18 +1294,20 @@ protected:
class CommandObjectBreakpointDisable : public CommandObjectParsed
{
public:
- CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "breakpoint disable",
- "Disable the specified breakpoint(s) without removing them. If none are specified, disable all breakpoints.",
- NULL)
+ CommandObjectBreakpointDisable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint disable", "Disable the specified breakpoint(s) without deleting "
+ "them. If none are specified, disable all "
+ "breakpoints.",
+ nullptr)
{
- SetHelpLong(
-"Disable the specified breakpoint(s) without removing them. \
-If none are specified, disable all breakpoints." R"(
+ SetHelpLong("Disable the specified breakpoint(s) without deleting them. \
+If none are specified, disable all breakpoints."
+ R"(
-)" "Note: disabling a breakpoint will cause none of its locations to be hit \
-regardless of whether they are enabled or disabled. After the sequence:" R"(
+)"
+ "Note: disabling a breakpoint will cause none of its locations to be hit \
+regardless of whether individual locations are enabled or disabled. After the sequence:"
+ R"(
(lldb) break disable 1
(lldb) break enable 1.1
@@ -1305,34 +1317,32 @@ execution will NOT stop at location 1.1. To achieve that, type:
(lldb) break disable 1.*
(lldb) break enable 1.1
-)" "The first command disables all the locations of breakpoint 1, \
-the second re-enables the first location."
- );
-
+)"
+ "The first command disables all locations for breakpoint 1, \
+the second re-enables the first location.");
+
CommandArgumentEntry arg;
CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
// Add the entry for the first argument for this command to the object's arguments vector.
m_arguments.push_back (arg);
-
}
-
- ~CommandObjectBreakpointDisable () override {}
+ ~CommandObjectBreakpointDisable() override = default;
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
Target *target = GetSelectedOrDummyTarget();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
result.SetStatus (eReturnStatusFailed);
return false;
}
- Mutex::Locker locker;
- target->GetBreakpointList().GetListMutex(locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
const BreakpointList &breakpoints = target->GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
@@ -1393,7 +1403,6 @@ protected:
return result.Succeeded();
}
-
};
//-------------------------------------------------------------------------
@@ -1405,10 +1414,10 @@ class CommandObjectBreakpointList : public CommandObjectParsed
{
public:
CommandObjectBreakpointList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "breakpoint list",
- "List some or all breakpoints at configurable levels of detail.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "breakpoint list",
+ "List some or all breakpoints at configurable levels of detail.",
+ nullptr),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -1425,8 +1434,7 @@ public:
m_arguments.push_back (arg);
}
-
- ~CommandObjectBreakpointList () override {}
+ ~CommandObjectBreakpointList() override = default;
Options *
GetOptions () override
@@ -1437,7 +1445,6 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_level (lldb::eDescriptionLevelBrief),
@@ -1445,7 +1452,7 @@ public:
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -1510,7 +1517,7 @@ protected:
{
Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("Invalid target. No current target or breakpoints.");
result.SetStatus (eReturnStatusSuccessFinishNoResult);
@@ -1518,8 +1525,8 @@ protected:
}
const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
- Mutex::Locker locker;
- target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList(m_options.m_internal).GetListMutex(lock);
size_t num_breakpoints = breakpoints.GetSize();
@@ -1561,7 +1568,7 @@ protected:
}
else
{
- result.AppendError ("Invalid breakpoint id.");
+ result.AppendError("Invalid breakpoint ID.");
result.SetStatus (eReturnStatusFailed);
}
}
@@ -1577,24 +1584,24 @@ private:
OptionDefinition
CommandObjectBreakpointList::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Show debugger internal breakpoints" },
- { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Give a brief description of the breakpoint (no location info)."},
// FIXME: We need to add an "internal" command, and then add this sort of thing to it.
// But I need to see it for now, and don't want to wait.
- { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Give a full description of the breakpoint and its locations."},
- { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Explain everything we know about the breakpoint (for debugging debugger bugs)." },
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -1605,23 +1612,21 @@ CommandObjectBreakpointList::CommandOptions::g_option_table[] =
class CommandObjectBreakpointClear : public CommandObjectParsed
{
public:
-
typedef enum BreakpointClearType
{
eClearTypeInvalid,
eClearTypeFileAndLine
} BreakpointClearType;
- CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "breakpoint clear",
- "Clears a breakpoint or set of breakpoints in the executable.",
- "breakpoint clear <cmd-options>"),
- m_options (interpreter)
+ CommandObjectBreakpointClear(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint clear",
+ "Delete or disable breakpoints matching the specified source file and line.",
+ "breakpoint clear <cmd-options>"),
+ m_options(interpreter)
{
}
- ~CommandObjectBreakpointClear () override {}
+ ~CommandObjectBreakpointClear() override = default;
Options *
GetOptions () override
@@ -1632,7 +1637,6 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_filename (),
@@ -1640,7 +1644,7 @@ public:
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -1695,7 +1699,7 @@ protected:
DoExecute (Args& command, CommandReturnObject &result) override
{
Target *target = GetSelectedOrDummyTarget();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
result.SetStatus (eReturnStatusFailed);
@@ -1710,8 +1714,8 @@ protected:
if (m_options.m_line_num != 0)
break_type = eClearTypeFileAndLine;
- Mutex::Locker locker;
- target->GetBreakpointList().GetListMutex(locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
BreakpointList &breakpoints = target->GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
@@ -1729,7 +1733,7 @@ protected:
// First create a copy of all the IDs.
std::vector<break_id_t> BreakIDs;
for (size_t i = 0; i < num_breakpoints; ++i)
- BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
+ BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
int num_cleared = 0;
StreamString ss;
@@ -1789,13 +1793,13 @@ private:
OptionDefinition
CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
+ { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
"Specify the breakpoint by source location in this particular file."},
- { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
+ { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
"Specify the breakpoint by source location at this particular line."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -1807,10 +1811,10 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed
{
public:
CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "breakpoint delete",
- "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "breakpoint delete",
+ "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
+ nullptr),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -1819,7 +1823,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectBreakpointDelete () override {}
+ ~CommandObjectBreakpointDelete() override = default;
Options *
GetOptions () override
@@ -1830,7 +1834,6 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_use_dummy (false),
@@ -1838,7 +1841,7 @@ public:
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -1892,16 +1895,16 @@ protected:
{
Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
result.SetStatus (eReturnStatusFailed);
return false;
}
- Mutex::Locker locker;
- target->GetBreakpointList().GetListMutex(locker);
-
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
+
const BreakpointList &breakpoints = target->GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
@@ -1968,6 +1971,7 @@ protected:
}
return result.Succeeded();
}
+
private:
CommandOptions m_options;
};
@@ -1975,26 +1979,26 @@ private:
OptionDefinition
CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Delete all breakpoints without querying for confirmation."},
- { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
// CommandObjectBreakpointName
//-------------------------------------------------------------------------
-static OptionDefinition
-g_breakpoint_name_options[] =
-{
- { LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
- { LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID, "Specify a breakpoint id to use."},
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
- "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+static OptionDefinition g_breakpoint_name_options[] = {
+ {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName,
+ "Specifies a breakpoint name to use."},
+ {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0,
+ eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
+ {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
+ "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
};
class BreakpointNameOptionGroup : public OptionGroup
{
@@ -2004,13 +2008,10 @@ public:
m_breakpoint(LLDB_INVALID_BREAK_ID),
m_use_dummy (false)
{
-
}
- ~BreakpointNameOptionGroup () override
- {
- }
-
+ ~BreakpointNameOptionGroup() override = default;
+
uint32_t
GetNumDefinitions () override
{
@@ -2068,7 +2069,6 @@ public:
OptionValueBoolean m_use_dummy;
};
-
class CommandObjectBreakpointNameAdd : public CommandObjectParsed
{
public:
@@ -2092,14 +2092,14 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectBreakpointNameAdd () override {}
+ ~CommandObjectBreakpointNameAdd() override = default;
+
+ Options *
+ GetOptions() override
+ {
+ return &m_option_group;
+ }
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
-
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -2112,16 +2112,16 @@ protected:
Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
result.SetStatus (eReturnStatusFailed);
return false;
}
- Mutex::Locker locker;
- target->GetBreakpointList().GetListMutex(locker);
-
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
+
const BreakpointList &breakpoints = target->GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
@@ -2162,8 +2162,6 @@ private:
OptionGroupOptions m_option_group;
};
-
-
class CommandObjectBreakpointNameDelete : public CommandObjectParsed
{
public:
@@ -2187,14 +2185,14 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectBreakpointNameDelete () override {}
+ ~CommandObjectBreakpointNameDelete() override = default;
+
+ Options *
+ GetOptions() override
+ {
+ return &m_option_group;
+ }
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
-
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -2207,16 +2205,16 @@ protected:
Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
result.SetStatus (eReturnStatusFailed);
return false;
}
- Mutex::Locker locker;
- target->GetBreakpointList().GetListMutex(locker);
-
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
+
const BreakpointList &breakpoints = target->GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
@@ -2271,21 +2269,21 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectBreakpointNameList () override {}
+ ~CommandObjectBreakpointNameList() override = default;
+
+ Options *
+ GetOptions() override
+ {
+ return &m_option_group;
+ }
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
-
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
result.SetStatus (eReturnStatusFailed);
@@ -2295,9 +2293,9 @@ protected:
if (m_name_options.m_name.OptionWasSet())
{
const char *name = m_name_options.m_name.GetCurrentValue();
- Mutex::Locker locker;
- target->GetBreakpointList().GetListMutex(locker);
-
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
+
BreakpointList &breakpoints = target->GetBreakpointList();
for (BreakpointSP bp_sp : breakpoints.Breakpoints())
{
@@ -2350,11 +2348,9 @@ private:
class CommandObjectBreakpointName : public CommandObjectMultiword
{
public:
- CommandObjectBreakpointName (CommandInterpreter &interpreter) :
- CommandObjectMultiword(interpreter,
- "name",
- "A set of commands to manage name tags for breakpoints",
- "breakpoint name <command> [<command-options>]")
+ CommandObjectBreakpointName(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "name", "Commands to manage name tags for breakpoints",
+ "breakpoint name <subcommand> [<command-options>]")
{
CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
@@ -2363,26 +2359,20 @@ public:
LoadSubCommand ("add", add_command_object);
LoadSubCommand ("delete", delete_command_object);
LoadSubCommand ("list", list_command_object);
-
- }
-
- ~CommandObjectBreakpointName () override
- {
}
+ ~CommandObjectBreakpointName() override = default;
};
-
//-------------------------------------------------------------------------
// CommandObjectMultiwordBreakpoint
//-------------------------------------------------------------------------
#pragma mark MultiwordBreakpoint
-CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "breakpoint",
- "A set of commands for operating on breakpoints. Also see _regexp-break.",
- "breakpoint <command> [<command-options>]")
+CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "breakpoint",
+ "Commands for operating on breakpoints (see 'help b' for shorthand.)",
+ "breakpoint <subcommand> [<command-options>]")
{
CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
@@ -2415,9 +2405,7 @@ CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInter
LoadSubCommand ("name", name_command_object);
}
-CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
-{
-}
+CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
void
CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
@@ -2473,7 +2461,7 @@ CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
{
BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- if (breakpoint != NULL)
+ if (breakpoint != nullptr)
{
const size_t num_locations = breakpoint->GetNumLocations();
if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
@@ -2491,7 +2479,8 @@ CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
else
{
i = valid_ids->GetSize() + 1;
- result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
+ result.AppendErrorWithFormat("'%d' is not a currently valid breakpoint ID.\n",
+ cur_bp_id.GetBreakpointID());
result.SetStatus (eReturnStatusFailed);
}
}
diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp
index 7b58bf9185bc..57572c8ef144 100644
--- a/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -9,11 +9,10 @@
// C Includes
// C++ Includes
-
-
+// Other libraries and framework includes
+// Project includes
#include "CommandObjectBreakpointCommand.h"
#include "CommandObjectBreakpoint.h"
-
#include "lldb/Core/IOHandler.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -32,21 +31,18 @@ using namespace lldb_private;
// CommandObjectBreakpointCommandAdd
//-------------------------------------------------------------------------
-
class CommandObjectBreakpointCommandAdd :
public CommandObjectParsed,
public IOHandlerDelegateMultiline
{
public:
-
- CommandObjectBreakpointCommandAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "add",
- "Add a set of commands to a breakpoint, to be executed whenever the breakpoint is hit."
- " If no breakpoint is specified, adds the commands to the last created breakpoint.",
- NULL),
- IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
- m_options (interpreter)
+ CommandObjectBreakpointCommandAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "add",
+ "Add LLDB commands to a breakpoint, to be executed whenever the breakpoint is hit."
+ " If no breakpoint is specified, adds the commands to the last created breakpoint.",
+ nullptr),
+ IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand),
+ m_options(interpreter)
{
SetHelpLong (
R"(
@@ -178,7 +174,7 @@ are no syntax errors may indicate that a function was declared but never called.
m_arguments.push_back (arg);
}
- ~CommandObjectBreakpointCommandAdd () override {}
+ ~CommandObjectBreakpointCommandAdd() override = default;
Options *
GetOptions () override
@@ -196,8 +192,7 @@ are no syntax errors may indicate that a function was declared but never called.
output_sp->Flush();
}
}
-
-
+
void
IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override
{
@@ -210,7 +205,7 @@ are no syntax errors may indicate that a function was declared but never called.
continue;
std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
- if (data_ap.get())
+ if (data_ap)
{
data_ap->user_source.SplitIntoLines (line.c_str(), line.size());
BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
@@ -248,7 +243,6 @@ are no syntax errors may indicate that a function was declared but never called.
BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp);
}
- return;
}
static bool
@@ -258,10 +252,9 @@ are no syntax errors may indicate that a function was declared but never called.
lldb::user_id_t break_loc_id)
{
bool ret_value = true;
- if (baton == NULL)
+ if (baton == nullptr)
return true;
-
-
+
BreakpointOptions::CommandData *data = (BreakpointOptions::CommandData *) baton;
StringList &commands = data->user_source;
@@ -302,7 +295,6 @@ are no syntax errors may indicate that a function was declared but never called.
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_use_commands (false),
@@ -314,7 +306,7 @@ are no syntax errors may indicate that a function was declared but never called.
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -355,11 +347,9 @@ are no syntax errors may indicate that a function was declared but never called.
break;
case 'F':
- {
- m_use_one_liner = false;
- m_use_script_language = true;
- m_function_name.assign(option_arg);
- }
+ m_use_one_liner = false;
+ m_use_script_language = true;
+ m_function_name.assign(option_arg);
break;
case 'D':
@@ -371,6 +361,7 @@ are no syntax errors may indicate that a function was declared but never called.
}
return error;
}
+
void
OptionParsingStarting () override
{
@@ -415,7 +406,7 @@ protected:
{
Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("There is not a current executable; there are no breakpoints to which to add commands");
result.SetStatus (eReturnStatusFailed);
@@ -432,7 +423,7 @@ protected:
return false;
}
- if (m_options.m_use_script_language == false && m_options.m_function_name.size())
+ if (!m_options.m_use_script_language && !m_options.m_function_name.empty())
{
result.AppendError ("need to enable scripting to have a function run as a breakpoint command");
result.SetStatus (eReturnStatusFailed);
@@ -454,7 +445,7 @@ protected:
if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
{
Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- BreakpointOptions *bp_options = NULL;
+ BreakpointOptions *bp_options = nullptr;
if (cur_bp_id.GetLocationID() == LLDB_INVALID_BREAK_ID)
{
// This breakpoint does not have an associated location.
@@ -485,7 +476,7 @@ protected:
script_interp->SetBreakpointCommandCallback (m_bp_options_vec,
m_options.m_one_liner.c_str());
}
- else if (m_options.m_function_name.size())
+ else if (!m_options.m_function_name.empty())
{
script_interp->SetBreakpointCommandCallbackFunction (m_bp_options_vec,
m_options.m_function_name.c_str());
@@ -506,7 +497,6 @@ protected:
CollectDataForBreakpointCommandCallback (m_bp_options_vec,
result);
}
-
}
return result.Succeeded();
@@ -526,7 +516,6 @@ private:
// so it isn't worthwhile to come up with a more complex mechanism
// to address this particular weakness right now.
static const char *g_reader_instructions;
-
};
const char *
@@ -541,28 +530,28 @@ g_script_option_enumeration[4] =
{ eScriptLanguageNone, "command", "Commands are in the lldb command interpreter language"},
{ eScriptLanguagePython, "python", "Commands are in the Python language."},
{ eSortOrderByName, "default-script", "Commands are in the default scripting language."},
- { 0, NULL, NULL }
+ { 0, nullptr, nullptr }
};
OptionDefinition
CommandObjectBreakpointCommandAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner,
+ { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner,
"Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
- { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
+ { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
"Specify whether breakpoint command execution should terminate on error." },
- { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, NULL, g_script_option_enumeration, 0, eArgTypeNone,
+ { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, g_script_option_enumeration, 0, eArgTypeNone,
"Specify the language for the commands - if none is specified, the lldb command interpreter will be used."},
- { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction,
+ { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction,
"Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate."},
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -573,10 +562,10 @@ class CommandObjectBreakpointCommandDelete : public CommandObjectParsed
{
public:
CommandObjectBreakpointCommandDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "delete",
- "Delete the set of commands from a breakpoint.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "delete",
+ "Delete the set of commands from a breakpoint.",
+ nullptr),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -593,8 +582,7 @@ public:
m_arguments.push_back (arg);
}
-
- ~CommandObjectBreakpointCommandDelete () override {}
+ ~CommandObjectBreakpointCommandDelete() override = default;
Options *
GetOptions () override
@@ -605,14 +593,13 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_use_dummy (false)
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -660,7 +647,7 @@ protected:
{
Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("There is not a current executable; there are no breakpoints from which to delete commands");
result.SetStatus (eReturnStatusFailed);
@@ -719,6 +706,7 @@ protected:
}
return result.Succeeded();
}
+
private:
CommandOptions m_options;
};
@@ -726,13 +714,12 @@ private:
OptionDefinition
CommandObjectBreakpointCommandDelete::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
//-------------------------------------------------------------------------
// CommandObjectBreakpointCommandList
//-------------------------------------------------------------------------
@@ -741,10 +728,10 @@ class CommandObjectBreakpointCommandList : public CommandObjectParsed
{
public:
CommandObjectBreakpointCommandList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "list",
- "List the script or set of commands to be executed when the breakpoint is hit.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "list",
+ "List the script or set of commands to be executed when the breakpoint is hit.",
+ nullptr)
{
CommandArgumentEntry arg;
CommandArgumentData bp_id_arg;
@@ -760,7 +747,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectBreakpointCommandList () override {}
+ ~CommandObjectBreakpointCommandList() override = default;
protected:
bool
@@ -769,7 +756,7 @@ protected:
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("There is not a current executable; there are no breakpoints for which to list commands");
result.SetStatus (eReturnStatusFailed);
@@ -808,7 +795,7 @@ protected:
if (bp)
{
- const BreakpointOptions *bp_options = NULL;
+ const BreakpointOptions *bp_options = nullptr;
if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
{
BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID()));
@@ -855,7 +842,6 @@ protected:
result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n", cur_bp_id.GetBreakpointID());
result.SetStatus (eReturnStatusFailed);
}
-
}
}
}
@@ -868,11 +854,11 @@ protected:
// CommandObjectBreakpointCommand
//-------------------------------------------------------------------------
-CommandObjectBreakpointCommand::CommandObjectBreakpointCommand (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "command",
- "A set of commands for adding, removing and examining bits of code to be executed when the breakpoint is hit (breakpoint 'commands').",
- "command <sub-command> [<sub-command-options>] <breakpoint-id>")
+CommandObjectBreakpointCommand::CommandObjectBreakpointCommand(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "command",
+ "Commands for adding, removing and listing LLDB commands executed when a breakpoint is hit.",
+ "command <sub-command> [<sub-command-options>] <breakpoint-id>")
{
CommandObjectSP add_command_object (new CommandObjectBreakpointCommandAdd (interpreter));
CommandObjectSP delete_command_object (new CommandObjectBreakpointCommandDelete (interpreter));
@@ -887,8 +873,4 @@ CommandObjectBreakpointCommand::CommandObjectBreakpointCommand (CommandInterpret
LoadSubCommand ("list", list_command_object);
}
-CommandObjectBreakpointCommand::~CommandObjectBreakpointCommand ()
-{
-}
-
-
+CommandObjectBreakpointCommand::~CommandObjectBreakpointCommand() = default;
diff --git a/source/Commands/CommandObjectBugreport.cpp b/source/Commands/CommandObjectBugreport.cpp
index 3d00cb817e3d..db8c06c0e9e3 100644
--- a/source/Commands/CommandObjectBugreport.cpp
+++ b/source/Commands/CommandObjectBugreport.cpp
@@ -130,11 +130,9 @@ private:
// CommandObjectMultiwordBugreport
//-------------------------------------------------------------------------
-CommandObjectMultiwordBugreport::CommandObjectMultiwordBugreport(CommandInterpreter &interpreter) :
- CommandObjectMultiword(interpreter,
- "bugreport",
- "Set of commands for creating domain specific bugreports.",
- "bugreport <subcommand> [<subcommand-options>]")
+CommandObjectMultiwordBugreport::CommandObjectMultiwordBugreport(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "bugreport", "Commands for creating domain-specific bug reports.",
+ "bugreport <subcommand> [<subcommand-options>]")
{
LoadSubCommand("unwind", CommandObjectSP(new CommandObjectBugreportUnwind(interpreter)));
diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp
index e859b5d64b11..dd2fd9a0efc8 100644
--- a/source/Commands/CommandObjectCommands.cpp
+++ b/source/Commands/CommandObjectCommands.cpp
@@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectCommands.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
// Project includes
+#include "CommandObjectCommands.h"
+#include "CommandObjectHelp.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Core/StringList.h"
@@ -24,6 +24,7 @@
#include "lldb/Interpreter/CommandObjectRegexCommand.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
+#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/OptionValueUInt64.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
@@ -39,15 +40,15 @@ class CommandObjectCommandsHistory : public CommandObjectParsed
{
public:
CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "command history",
- "Dump the history of commands in this session.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "command history",
+ "Dump the history of commands in this session.",
+ nullptr),
m_options (interpreter)
{
}
- ~CommandObjectCommandsHistory () override {}
+ ~CommandObjectCommandsHistory() override = default;
Options *
GetOptions () override
@@ -56,11 +57,9 @@ public:
}
protected:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_start_idx(0),
@@ -70,7 +69,7 @@ protected:
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -222,14 +221,13 @@ protected:
OptionDefinition
CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
-{ LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."},
-{ LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
-{ LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeBoolean, "Clears the current command history."},
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
+{ LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."},
+{ LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
+{ LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Clears the current command history."},
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
//-------------------------------------------------------------------------
// CommandObjectCommandsSource
//-------------------------------------------------------------------------
@@ -237,12 +235,10 @@ CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
class CommandObjectCommandsSource : public CommandObjectParsed
{
public:
- CommandObjectCommandsSource(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "command source",
- "Read in debugger commands from the file <filename> and execute them.",
- NULL),
- m_options (interpreter)
+ CommandObjectCommandsSource(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "command source", "Read and execute LLDB commands from the file <filename>.",
+ nullptr),
+ m_options(interpreter)
{
CommandArgumentEntry arg;
CommandArgumentData file_arg;
@@ -258,7 +254,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectCommandsSource () override {}
+ ~CommandObjectCommandsSource() override = default;
const char*
GetRepeatCommand (Args &current_command_args, uint32_t index) override
@@ -279,14 +275,14 @@ public:
std::string completion_str (input.GetArgumentAtIndex(cursor_index));
completion_str.erase (cursor_char_position);
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eDiskFileCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -297,11 +293,9 @@ public:
}
protected:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_stop_on_error (true),
@@ -310,7 +304,7 @@ protected:
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -374,7 +368,7 @@ protected:
const char *filename = command.GetArgumentAtIndex(0);
FileSpec cmd_file (filename, true);
- ExecutionContext *exe_ctx = NULL; // Just use the default context.
+ ExecutionContext *exe_ctx = nullptr; // Just use the default context.
// If any options were set, then use them
if (m_options.m_stop_on_error.OptionWasSet() ||
@@ -392,7 +386,6 @@ protected:
exe_ctx,
options,
result);
-
}
else
{
@@ -403,7 +396,6 @@ protected:
exe_ctx,
options,
result);
-
}
}
else
@@ -412,18 +404,18 @@ protected:
result.SetStatus (eReturnStatusFailed);
}
return result.Succeeded();
-
}
+
CommandOptions m_options;
};
OptionDefinition
CommandObjectCommandsSource::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
-{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
-{ LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
+{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
+{ LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
#pragma mark CommandObjectCommandsAlias
@@ -435,18 +427,94 @@ static const char *g_python_command_instructions = "Enter your Python command(
"You must define a Python function with this signature:\n"
"def my_command_impl(debugger, args, result, internal_dict):\n";
-
class CommandObjectCommandsAlias : public CommandObjectRaw
{
-
+protected:
+ class CommandOptions : public OptionGroup
+ {
+ public:
+ CommandOptions () :
+ OptionGroup(),
+ m_help(),
+ m_long_help()
+ {}
+
+ ~CommandOptions() override = default;
+
+ uint32_t
+ GetNumDefinitions () override
+ {
+ return 3;
+ }
+
+ const OptionDefinition*
+ GetDefinitions () override
+ {
+ return g_option_table;
+ }
+
+ Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value) override
+ {
+ Error error;
+
+ const int short_option = g_option_table[option_idx].short_option;
+
+ switch (short_option)
+ {
+ case 'h':
+ m_help.SetCurrentValue(option_value);
+ m_help.SetOptionWasSet();
+ break;
+
+ case 'H':
+ m_long_help.SetCurrentValue(option_value);
+ m_long_help.SetOptionWasSet();
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ OptionParsingStarting (CommandInterpreter &interpreter) override
+ {
+ m_help.Clear();
+ m_long_help.Clear();
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+ OptionValueString m_help;
+ OptionValueString m_long_help;
+ };
+
+ OptionGroupOptions m_option_group;
+ CommandOptions m_command_options;
public:
- CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "command alias",
- "Allow users to define their own debugger command abbreviations.",
- NULL)
+ Options *
+ GetOptions () override
+ {
+ return &m_option_group;
+ }
+
+ CommandObjectCommandsAlias(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "command alias", "Define a custom command in terms of an existing command.",
+ nullptr),
+ m_option_group(interpreter),
+ m_command_options()
{
+ m_option_group.Append(&m_command_options);
+ m_option_group.Finalize();
+
SetHelpLong(
"'alias' allows the user to create a short-cut or abbreviation for long \
commands, multi-word commands, and commands that take particular options. \
@@ -551,22 +619,70 @@ rather than using a positional placeholder:" R"(
m_arguments.push_back (arg3);
}
- ~CommandObjectCommandsAlias () override
- {
- }
+ ~CommandObjectCommandsAlias() override = default;
protected:
bool
DoExecute (const char *raw_command_line, CommandReturnObject &result) override
{
- Args args (raw_command_line);
- std::string raw_command_string (raw_command_line);
+ if (!raw_command_line || !raw_command_line[0])
+ {
+ result.AppendError ("'command alias' requires at least two arguments");
+ return false;
+ }
+
+ m_option_group.NotifyOptionParsingStarting();
+
+ const char * remainder = nullptr;
+
+ if (raw_command_line[0] == '-')
+ {
+ // We have some options and these options MUST end with --.
+ const char *end_options = nullptr;
+ const char *s = raw_command_line;
+ while (s && s[0])
+ {
+ end_options = ::strstr (s, "--");
+ if (end_options)
+ {
+ end_options += 2; // Get past the "--"
+ if (::isspace (end_options[0]))
+ {
+ remainder = end_options;
+ while (::isspace (*remainder))
+ ++remainder;
+ break;
+ }
+ }
+ s = end_options;
+ }
+
+ if (end_options)
+ {
+ Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
+ if (!ParseOptions (args, result))
+ return false;
+
+ Error error (m_option_group.NotifyOptionParsingFinished());
+ if (error.Fail())
+ {
+ result.AppendError (error.AsCString());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+ }
+ if (nullptr == remainder)
+ remainder = raw_command_line;
+
+ std::string raw_command_string (remainder);
+ Args args (raw_command_string.c_str());
size_t argc = args.GetArgumentCount();
if (argc < 2)
{
- result.AppendError ("'alias' requires at least two arguments");
+ result.AppendError ("'command alias' requires at least two arguments");
result.SetStatus (eReturnStatusFailed);
return false;
}
@@ -574,6 +690,17 @@ protected:
// Get the alias command.
const std::string alias_command = args.GetArgumentAtIndex (0);
+ if (alias_command.size() > 1 &&
+ alias_command[0] == '-')
+ {
+ result.AppendError("aliases starting with a dash are not supported");
+ if (alias_command == "--help" || alias_command == "--long-help")
+ {
+ result.AppendWarning("if trying to pass options to 'command alias' add a -- at the end of the options");
+ }
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
// Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
// does the stripping itself.
@@ -604,12 +731,13 @@ protected:
// Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
// raw_command_string is returned with the name of the command object stripped off the front.
+ std::string original_raw_command_string(raw_command_string);
CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
if (!cmd_obj)
{
- result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
- " No alias created.", raw_command_string.c_str());
+ result.AppendErrorWithFormat ("invalid command given to 'command alias'. '%s' does not begin with a valid command."
+ " No alias created.", original_raw_command_string.c_str());
result.SetStatus (eReturnStatusFailed);
return false;
}
@@ -632,43 +760,36 @@ protected:
// Verify & handle any options/arguments passed to the alias command
OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
- OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
-
- CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
-
- if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
- {
- result.AppendError ("Unable to create requested alias.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- // Create the alias
- if (m_interpreter.AliasExists (alias_command.c_str())
- || m_interpreter.UserCommandExists (alias_command.c_str()))
+
+ if (CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false))
{
- OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
- if (temp_option_arg_sp.get())
+ if (m_interpreter.AliasExists (alias_command.c_str())
+ || m_interpreter.UserCommandExists (alias_command.c_str()))
{
- if (option_arg_vector->size() == 0)
- m_interpreter.RemoveAliasOptions (alias_command.c_str());
+ result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
+ alias_command.c_str());
}
- result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
- alias_command.c_str());
- }
-
- if (cmd_obj_sp)
- {
- m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
- if (option_arg_vector->size() > 0)
- m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ if (CommandAlias *alias = m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp, raw_command_string.c_str()))
+ {
+ if (m_command_options.m_help.OptionWasSet())
+ alias->SetHelp(m_command_options.m_help.GetCurrentValue());
+ if (m_command_options.m_long_help.OptionWasSet())
+ alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ }
+ else
+ {
+ result.AppendError ("Unable to create requested alias.\n");
+ result.SetStatus (eReturnStatusFailed);
+ }
+
}
else
{
result.AppendError ("Unable to create requested alias.\n");
result.SetStatus (eReturnStatusFailed);
}
+
return result.Succeeded ();
}
@@ -679,7 +800,7 @@ protected:
if (argc < 2)
{
- result.AppendError ("'alias' requires at least two arguments");
+ result.AppendError ("'command alias' requires at least two arguments");
result.SetStatus (eReturnStatusFailed);
return false;
}
@@ -703,12 +824,11 @@ protected:
CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
CommandObjectSP subcommand_obj_sp;
bool use_subcommand = false;
- if (command_obj_sp.get())
+ if (command_obj_sp)
{
CommandObject *cmd_obj = command_obj_sp.get();
- CommandObject *sub_cmd_obj = NULL;
+ CommandObject *sub_cmd_obj = nullptr;
OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
- OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
{
@@ -717,7 +837,7 @@ protected:
const std::string sub_command = args.GetArgumentAtIndex(0);
assert (sub_command.length() != 0);
subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
- if (subcommand_obj_sp.get())
+ if (subcommand_obj_sp)
{
sub_cmd_obj = subcommand_obj_sp.get();
use_subcommand = true;
@@ -737,45 +857,40 @@ protected:
// Verify & handle any options/arguments passed to the alias command
+ std::string args_string;
+
if (args.GetArgumentCount () > 0)
{
CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
if (use_subcommand)
tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
- std::string args_string;
args.GetCommandString (args_string);
-
- if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
- {
- result.AppendError ("Unable to create requested alias.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
}
-
- // Create the alias.
-
+
if (m_interpreter.AliasExists (alias_command.c_str())
|| m_interpreter.UserCommandExists (alias_command.c_str()))
{
- OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
- if (tmp_option_arg_sp.get())
- {
- if (option_arg_vector->size() == 0)
- m_interpreter.RemoveAliasOptions (alias_command.c_str());
- }
- result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
+ result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
alias_command.c_str());
}
-
- if (use_subcommand)
- m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
+
+ if (CommandAlias *alias = m_interpreter.AddAlias(alias_command.c_str(),
+ use_subcommand ? subcommand_obj_sp : command_obj_sp,
+ args_string.c_str()))
+ {
+ if (m_command_options.m_help.OptionWasSet())
+ alias->SetHelp(m_command_options.m_help.GetCurrentValue());
+ if (m_command_options.m_long_help.OptionWasSet())
+ alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ }
else
- m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
- if (option_arg_vector->size() > 0)
- m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ {
+ result.AppendError ("Unable to create requested alias.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
}
else
{
@@ -787,7 +902,14 @@ protected:
return result.Succeeded();
}
-
+};
+
+OptionDefinition
+CommandObjectCommandsAlias::CommandOptions::g_option_table[] =
+{
+ { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Help text for this command"},
+ { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Long help text for this command"},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
#pragma mark CommandObjectCommandsUnalias
@@ -798,11 +920,9 @@ protected:
class CommandObjectCommandsUnalias : public CommandObjectParsed
{
public:
- CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "command unalias",
- "Allow the user to remove/delete a user-defined command abbreviation.",
- NULL)
+ CommandObjectCommandsUnalias(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "command unalias",
+ "Delete one or more custom commands defined by 'command alias'.", nullptr)
{
CommandArgumentEntry arg;
CommandArgumentData alias_arg;
@@ -818,9 +938,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectCommandsUnalias() override
- {
- }
+ ~CommandObjectCommandsUnalias() override = default;
protected:
bool
@@ -851,8 +969,7 @@ protected:
}
else
{
-
- if (m_interpreter.RemoveAlias (command_name) == false)
+ if (!m_interpreter.RemoveAlias(command_name))
{
if (m_interpreter.AliasExists (command_name))
result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
@@ -891,11 +1008,9 @@ protected:
class CommandObjectCommandsDelete : public CommandObjectParsed
{
public:
- CommandObjectCommandsDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "command delete",
- "Allow the user to delete user-defined regular expression, python or multi-word commands.",
- NULL)
+ CommandObjectCommandsDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "command delete",
+ "Delete one or more custom commands defined by 'command regex'.", nullptr)
{
CommandArgumentEntry arg;
CommandArgumentData alias_arg;
@@ -911,9 +1026,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectCommandsDelete() override
- {
- }
+ ~CommandObjectCommandsDelete() override = default;
protected:
bool
@@ -939,14 +1052,24 @@ protected:
}
else
{
- result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
- command_name);
+ StreamString error_msg_stream;
+ const bool generate_apropos = true;
+ const bool generate_type_lookup = false;
+ CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
+ command_name,
+ nullptr,
+ nullptr,
+ generate_apropos,
+ generate_type_lookup);
+ result.AppendErrorWithFormat ("%s", error_msg_stream.GetData());
result.SetStatus (eReturnStatusFailed);
}
}
else
{
- result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ());
+ result.AppendErrorWithFormat(
+ "must call '%s' with one or more valid user defined regular expression command names",
+ GetCommandName());
result.SetStatus (eReturnStatusFailed);
}
@@ -964,13 +1087,12 @@ class CommandObjectCommandsAddRegex :
public IOHandlerDelegateMultiline
{
public:
- CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "command regex",
- "Allow the user to create a regular expression command.",
- "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
- IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand),
- m_options (interpreter)
+ CommandObjectCommandsAddRegex(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "command regex",
+ "Define a custom command in terms of existing commands by matching regular expressions.",
+ "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
+ IOHandlerDelegateMultiline("", IOHandlerDelegate::Completion::LLDBCommand),
+ m_options(interpreter)
{
SetHelpLong(R"(
)" "This command allows the user to create powerful regular expression commands \
@@ -997,14 +1119,10 @@ a number follows 'f':" R"(
(lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')"
);
}
-
- ~CommandObjectCommandsAddRegex() override
- {
- }
-
-
+
+ ~CommandObjectCommandsAddRegex() override = default;
+
protected:
-
void
IOHandlerActivated (IOHandler &io_handler) override
{
@@ -1020,7 +1138,7 @@ protected:
IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
{
io_handler.SetIsDone(true);
- if (m_regex_cmd_ap.get())
+ if (m_regex_cmd_ap)
{
StringList lines;
if (lines.SplitIntoLines (data))
@@ -1075,15 +1193,15 @@ protected:
Debugger &debugger = m_interpreter.GetDebugger();
bool color_prompt = debugger.GetUseColor();
const bool multiple_lines = true; // Get multiple lines
- IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
- IOHandler::Type::Other,
- "lldb-regex", // Name of input reader for history
- "> ", // Prompt
- NULL, // Continuation prompt
- multiple_lines,
- color_prompt,
- 0, // Don't show line numbers
- *this));
+ IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger,
+ IOHandler::Type::Other,
+ "lldb-regex", // Name of input reader for history
+ "> ", // Prompt
+ nullptr, // Continuation prompt
+ multiple_lines,
+ color_prompt,
+ 0, // Don't show line numbers
+ *this));
if (io_handler_sp)
{
@@ -1122,7 +1240,7 @@ protected:
{
Error error;
- if (m_regex_cmd_ap.get() == NULL)
+ if (!m_regex_cmd_ap)
{
error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
(int)regex_sed.size(),
@@ -1190,7 +1308,6 @@ protected:
regex_sed.data() + (third_separator_char_pos + 1));
return error;
}
-
}
else if (first_separator_char_pos + 1 == second_separator_char_pos)
{
@@ -1213,7 +1330,7 @@ protected:
return error;
}
- if (check_only == false)
+ if (!check_only)
{
std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
@@ -1226,7 +1343,7 @@ protected:
void
AddRegexCommandToInterpreter()
{
- if (m_regex_cmd_ap.get())
+ if (m_regex_cmd_ap)
{
if (m_regex_cmd_ap->HasRegexEntries())
{
@@ -1242,14 +1359,13 @@ private:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -1264,7 +1380,6 @@ private:
case 's':
m_syntax.assign (option_arg);
break;
-
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -1291,21 +1406,20 @@ private:
static OptionDefinition g_option_table[];
const char *
- GetHelp ()
+ GetHelp()
{
- if (m_help.empty())
- return NULL;
- return m_help.c_str();
+ return (m_help.empty() ? nullptr : m_help.c_str());
}
+
const char *
GetSyntax ()
{
- if (m_syntax.empty())
- return NULL;
- return m_syntax.c_str();
+ return (m_syntax.empty() ? nullptr : m_syntax.c_str());
}
- // Instance variables to hold the values for command options.
+
protected:
+ // Instance variables to hold the values for command options.
+
std::string m_help;
std::string m_syntax;
};
@@ -1322,30 +1436,23 @@ private:
OptionDefinition
CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."},
-{ LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
-{ 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The help text to display for this command."},
+{ LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
+{ 0 , false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
class CommandObjectPythonFunction : public CommandObjectRaw
{
-private:
- std::string m_function_name;
- ScriptedCommandSynchronicity m_synchro;
- bool m_fetched_help_long;
-
public:
-
CommandObjectPythonFunction (CommandInterpreter &interpreter,
std::string name,
std::string funct,
std::string help,
ScriptedCommandSynchronicity synch) :
- CommandObjectRaw (interpreter,
- name.c_str(),
- NULL,
- NULL),
+ CommandObjectRaw(interpreter,
+ name.c_str(),
+ nullptr,
+ nullptr),
m_function_name(funct),
m_synchro(synch),
m_fetched_help_long(false)
@@ -1359,11 +1466,9 @@ public:
SetHelp(stream.GetData());
}
}
-
- ~CommandObjectPythonFunction () override
- {
- }
-
+
+ ~CommandObjectPythonFunction() override = default;
+
bool
IsRemovable () const override
{
@@ -1393,7 +1498,7 @@ public:
std::string docstring;
m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
if (!docstring.empty())
- SetHelpLong(docstring);
+ SetHelpLong(docstring.c_str());
}
}
return CommandObjectRaw::GetHelpLong();
@@ -1409,12 +1514,12 @@ protected:
result.SetStatus(eReturnStatusInvalid);
- if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
- raw_command_line,
- m_synchro,
- result,
- error,
- m_exe_ctx) == false)
+ if (!scripter || !scripter->RunScriptBasedCommand(m_function_name.c_str(),
+ raw_command_line,
+ m_synchro,
+ result,
+ error,
+ m_exe_ctx))
{
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
@@ -1424,7 +1529,7 @@ protected:
// Don't change the status if the command already set it...
if (result.GetStatus() == eReturnStatusInvalid)
{
- if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
+ if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
result.SetStatus(eReturnStatusSuccessFinishNoResult);
else
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -1433,31 +1538,28 @@ protected:
return result.Succeeded();
}
-
+
+private:
+ std::string m_function_name;
+ ScriptedCommandSynchronicity m_synchro;
+ bool m_fetched_help_long;
};
class CommandObjectScriptingObject : public CommandObjectRaw
{
-private:
- StructuredData::GenericSP m_cmd_obj_sp;
- ScriptedCommandSynchronicity m_synchro;
- bool m_fetched_help_short:1;
- bool m_fetched_help_long:1;
-
public:
-
CommandObjectScriptingObject (CommandInterpreter &interpreter,
std::string name,
StructuredData::GenericSP cmd_obj_sp,
ScriptedCommandSynchronicity synch) :
- CommandObjectRaw (interpreter,
- name.c_str(),
- NULL,
- NULL),
- m_cmd_obj_sp(cmd_obj_sp),
- m_synchro(synch),
- m_fetched_help_short(false),
- m_fetched_help_long(false)
+ CommandObjectRaw(interpreter,
+ name.c_str(),
+ nullptr,
+ nullptr),
+ m_cmd_obj_sp(cmd_obj_sp),
+ m_synchro(synch),
+ m_fetched_help_short(false),
+ m_fetched_help_long(false)
{
StreamString stream;
stream.Printf("For more information run 'help %s'",name.c_str());
@@ -1465,11 +1567,9 @@ public:
if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
}
-
- ~CommandObjectScriptingObject () override
- {
- }
-
+
+ ~CommandObjectScriptingObject() override = default;
+
bool
IsRemovable () const override
{
@@ -1499,7 +1599,7 @@ public:
std::string docstring;
m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
if (!docstring.empty())
- SetHelp(docstring);
+ SetHelp(docstring.c_str());
}
}
return CommandObjectRaw::GetHelp();
@@ -1516,7 +1616,7 @@ public:
std::string docstring;
m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
if (!docstring.empty())
- SetHelpLong(docstring);
+ SetHelpLong(docstring.c_str());
}
}
return CommandObjectRaw::GetHelpLong();
@@ -1532,12 +1632,12 @@ protected:
result.SetStatus(eReturnStatusInvalid);
- if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp,
- raw_command_line,
- m_synchro,
- result,
- error,
- m_exe_ctx) == false)
+ if (!scripter || !scripter->RunScriptBasedCommand(m_cmd_obj_sp,
+ raw_command_line,
+ m_synchro,
+ result,
+ error,
+ m_exe_ctx))
{
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
@@ -1547,7 +1647,7 @@ protected:
// Don't change the status if the command already set it...
if (result.GetStatus() == eReturnStatusInvalid)
{
- if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
+ if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
result.SetStatus(eReturnStatusSuccessFinishNoResult);
else
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -1556,7 +1656,12 @@ protected:
return result.Succeeded();
}
-
+
+private:
+ StructuredData::GenericSP m_cmd_obj_sp;
+ ScriptedCommandSynchronicity m_synchro;
+ bool m_fetched_help_short: 1;
+ bool m_fetched_help_long: 1;
};
//-------------------------------------------------------------------------
@@ -1567,10 +1672,10 @@ class CommandObjectCommandsScriptImport : public CommandObjectParsed
{
public:
CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "command script import",
- "Import a scripting module in LLDB.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "command script import",
+ "Import a scripting module in LLDB.",
+ nullptr),
m_options(interpreter)
{
CommandArgumentEntry arg1;
@@ -1586,11 +1691,9 @@ public:
// Push the data for the first argument into the m_arguments vector.
m_arguments.push_back (arg1);
}
-
- ~CommandObjectCommandsScriptImport () override
- {
- }
-
+
+ ~CommandObjectCommandsScriptImport() override = default;
+
int
HandleArgumentCompletion (Args &input,
int &cursor_index,
@@ -1604,14 +1707,14 @@ public:
std::string completion_str (input.GetArgumentAtIndex(cursor_index));
completion_str.erase (cursor_char_position);
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eDiskFileCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -1622,18 +1725,16 @@ public:
}
protected:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -1730,11 +1831,10 @@ protected:
OptionDefinition
CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptAdd
//-------------------------------------------------------------------------
@@ -1745,10 +1845,10 @@ class CommandObjectCommandsScriptAdd :
{
public:
CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "command script add",
- "Add a scripted function as an LLDB command.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "command script add",
+ "Add a scripted function as an LLDB command.",
+ nullptr),
IOHandlerDelegateMultiline ("DONE"),
m_options (interpreter)
{
@@ -1765,11 +1865,9 @@ public:
// Push the data for the first argument into the m_arguments vector.
m_arguments.push_back (arg1);
}
-
- ~CommandObjectCommandsScriptAdd () override
- {
- }
-
+
+ ~CommandObjectCommandsScriptAdd() override = default;
+
Options *
GetOptions () override
{
@@ -1777,11 +1875,9 @@ public:
}
protected:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_class_name(),
@@ -1790,9 +1886,9 @@ protected:
m_synchronicity(eScriptedCommandSynchronicitySynchronous)
{
}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -1922,15 +2018,12 @@ protected:
}
io_handler.SetIsDone(true);
-
-
}
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
-
if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
{
result.AppendError ("only scripting language supported for scripted commands is currently Python");
@@ -1956,10 +2049,10 @@ protected:
{
if (m_options.m_funct_name.empty())
{
- m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
- *this, // IOHandlerDelegate
- true, // Run IOHandler in async mode
- NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
+ m_interpreter.GetPythonCommandsFromIOHandler(" ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ nullptr); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
}
else
{
@@ -2013,7 +2106,6 @@ protected:
}
return result.Succeeded();
-
}
CommandOptions m_options;
@@ -2027,17 +2119,17 @@ static OptionEnumValueElement g_script_synchro_type[] =
{ eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
{ eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
{ eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
- { 0, NULL, NULL }
+ { 0, nullptr, nullptr }
};
OptionDefinition
CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
- { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name."},
- { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."},
- { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
+ { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name."},
+ { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "The help text to display for this command."},
+ { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -2046,33 +2138,26 @@ CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
class CommandObjectCommandsScriptList : public CommandObjectParsed
{
-private:
-
public:
CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "command script list",
- "List defined scripted commands.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "command script list",
+ "List defined scripted commands.",
+ nullptr)
{
}
-
- ~CommandObjectCommandsScriptList () override
- {
- }
-
+
+ ~CommandObjectCommandsScriptList() override = default;
+
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
-
m_interpreter.GetHelp(result,
CommandInterpreter::eCommandTypesUserDef);
result.SetStatus (eReturnStatusSuccessFinishResult);
return true;
-
-
}
};
@@ -2082,26 +2167,21 @@ public:
class CommandObjectCommandsScriptClear : public CommandObjectParsed
{
-private:
-
public:
CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "command script clear",
- "Delete all scripted commands.",
- NULL)
- {
- }
-
- ~CommandObjectCommandsScriptClear () override
+ CommandObjectParsed(interpreter,
+ "command script clear",
+ "Delete all scripted commands.",
+ nullptr)
{
}
-
+
+ ~CommandObjectCommandsScriptClear() override = default;
+
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
-
m_interpreter.RemoveAllUser();
result.SetStatus (eReturnStatusSuccessFinishResult);
@@ -2118,10 +2198,10 @@ class CommandObjectCommandsScriptDelete : public CommandObjectParsed
{
public:
CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "command script delete",
- "Delete a scripted command.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "command script delete",
+ "Delete a scripted command.",
+ nullptr)
{
CommandArgumentEntry arg1;
CommandArgumentData cmd_arg;
@@ -2136,11 +2216,9 @@ public:
// Push the data for the first argument into the m_arguments vector.
m_arguments.push_back (arg1);
}
-
- ~CommandObjectCommandsScriptDelete () override
- {
- }
-
+
+ ~CommandObjectCommandsScriptDelete() override = default;
+
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -2169,7 +2247,6 @@ protected:
}
return result.Succeeded();
-
}
};
@@ -2182,11 +2259,10 @@ protected:
class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
{
public:
- CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "command script",
- "A set of commands for managing or customizing script commands.",
- "command script <subcommand> [<subcommand-options>]")
+ CommandObjectMultiwordCommandsScript(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "command script",
+ "Commands for managing custom commands implemented by interpreter scripts.",
+ "command script <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
@@ -2195,24 +2271,18 @@ public:
LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
}
- ~CommandObjectMultiwordCommandsScript () override
- {
- }
-
+ ~CommandObjectMultiwordCommandsScript() override = default;
};
-
#pragma mark CommandObjectMultiwordCommands
//-------------------------------------------------------------------------
// CommandObjectMultiwordCommands
//-------------------------------------------------------------------------
-CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "command",
- "A set of commands for managing or customizing the debugger commands.",
- "command <subcommand> [<subcommand-options>]")
+CommandObjectMultiwordCommands::CommandObjectMultiwordCommands(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "command", "Commands for managing custom LLDB commands.",
+ "command <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
@@ -2223,7 +2293,4 @@ CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpret
LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
}
-CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
-{
-}
-
+CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands() = default;
diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp
index 100d8692039f..07a847aaebae 100644
--- a/source/Commands/CommandObjectDisassemble.cpp
+++ b/source/Commands/CommandObjectDisassemble.cpp
@@ -7,12 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectDisassemble.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "CommandObjectDisassemble.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
@@ -54,9 +53,7 @@ CommandObjectDisassemble::CommandOptions::CommandOptions (CommandInterpreter &in
OptionParsingStarting();
}
-CommandObjectDisassemble::CommandOptions::~CommandOptions ()
-{
-}
+CommandObjectDisassemble::CommandOptions::~CommandOptions() = default;
Error
CommandObjectDisassemble::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
@@ -105,6 +102,7 @@ CommandObjectDisassemble::CommandOptions::SetOptionValue (uint32_t option_idx, c
some_location_specified = true;
}
break;
+
case 'n':
func_name.assign (option_arg);
some_location_specified = true;
@@ -139,6 +137,7 @@ CommandObjectDisassemble::CommandOptions::SetOptionValue (uint32_t option_idx, c
error.SetErrorStringWithFormat("Disassembler flavors are currently only supported for x86 and x86_64 targets.");
break;
}
+
case 'r':
raw = true;
break;
@@ -218,7 +217,6 @@ CommandObjectDisassemble::CommandOptions::OptionParsingFinished ()
if (!some_location_specified)
current_function = true;
return Error();
-
}
const OptionDefinition*
@@ -230,55 +228,51 @@ CommandObjectDisassemble::CommandOptions::GetDefinitions ()
OptionDefinition
CommandObjectDisassemble::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL, false, "bytes" , 'b', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Show opcode bytes when disassembling."},
-{ LLDB_OPT_SET_ALL, false, "context" , 'C', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeNumLines, "Number of context lines of source to show."},
-{ LLDB_OPT_SET_ALL, false, "mixed" , 'm', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Enable mixed source and assembly display."},
-{ LLDB_OPT_SET_ALL, false, "raw" , 'r', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Print raw disassembly with no symbol information."},
-{ LLDB_OPT_SET_ALL, false, "plugin" , 'P', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use."},
-{ LLDB_OPT_SET_ALL, false, "flavor" , 'F', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. "
+{ LLDB_OPT_SET_ALL, false, "bytes" , 'b', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Show opcode bytes when disassembling."},
+{ LLDB_OPT_SET_ALL, false, "context" , 'C', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeNumLines, "Number of context lines of source to show."},
+{ LLDB_OPT_SET_ALL, false, "mixed" , 'm', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Enable mixed source and assembly display."},
+{ LLDB_OPT_SET_ALL, false, "raw" , 'r', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Print raw disassembly with no symbol information."},
+{ LLDB_OPT_SET_ALL, false, "plugin" , 'P', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use."},
+{ LLDB_OPT_SET_ALL, false, "flavor" , 'F', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. "
"Currently the only valid options are default, and for Intel"
" architectures, att and intel."},
-{ LLDB_OPT_SET_ALL, false, "arch" , 'A', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeArchitecture,"Specify the architecture to use from cross disassembly."},
+{ LLDB_OPT_SET_ALL, false, "arch" , 'A', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeArchitecture,"Specify the architecture to use from cross disassembly."},
{ LLDB_OPT_SET_1 |
- LLDB_OPT_SET_2 , true , "start-address", 's', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeAddressOrExpression,"Address at which to start disassembling."},
-{ LLDB_OPT_SET_1 , false, "end-address" , 'e', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeAddressOrExpression, "Address at which to end disassembling."},
+ LLDB_OPT_SET_2 , true , "start-address", 's', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeAddressOrExpression,"Address at which to start disassembling."},
+{ LLDB_OPT_SET_1 , false, "end-address" , 'e', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Address at which to end disassembling."},
{ LLDB_OPT_SET_2 |
LLDB_OPT_SET_3 |
LLDB_OPT_SET_4 |
- LLDB_OPT_SET_5 , false, "count" , 'c', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
-{ LLDB_OPT_SET_3 , false, "name" , 'n', OptionParser::eRequiredArgument , NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
+ LLDB_OPT_SET_5 , false, "count" , 'c', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeNumLines, "Number of instructions to display."},
+{ LLDB_OPT_SET_3 , false, "name" , 'n', OptionParser::eRequiredArgument , nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
"Disassemble entire contents of the given function name."},
-{ LLDB_OPT_SET_4 , false, "frame" , 'f', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."},
-{ LLDB_OPT_SET_5 , false, "pc" , 'p', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Disassemble around the current pc."},
-{ LLDB_OPT_SET_6 , false, "line" , 'l', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there is debug line table information, else disassemble around the pc."},
-{ LLDB_OPT_SET_7 , false, "address" , 'a', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeAddressOrExpression, "Disassemble function containing this address."},
-{ 0 , false, NULL , 0, 0 , NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_4 , false, "frame" , 'f', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."},
+{ LLDB_OPT_SET_5 , false, "pc" , 'p', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Disassemble around the current pc."},
+{ LLDB_OPT_SET_6 , false, "line" , 'l', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there is debug line table information, else disassemble around the pc."},
+{ LLDB_OPT_SET_7 , false, "address" , 'a', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Disassemble function containing this address."},
+{ 0 , false, nullptr , 0, 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
-
//-------------------------------------------------------------------------
// CommandObjectDisassemble
//-------------------------------------------------------------------------
-CommandObjectDisassemble::CommandObjectDisassemble (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "disassemble",
- "Disassemble bytes in the current function, or elsewhere in the executable program as specified by the user.",
- "disassemble [<cmd-options>]"),
- m_options (interpreter)
+CommandObjectDisassemble::CommandObjectDisassemble(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "disassemble", "Disassemble specified instructions in the current target. "
+ "Defaults to the current function for the current thread and "
+ "stack frame.",
+ "disassemble [<cmd-options>]"),
+ m_options(interpreter)
{
}
-CommandObjectDisassemble::~CommandObjectDisassemble()
-{
-}
+CommandObjectDisassemble::~CommandObjectDisassemble() = default;
bool
CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("invalid target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -313,7 +307,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
result.SetStatus (eReturnStatusFailed);
return false;
}
- else if (flavor_string != NULL && !disassembler->FlavorValidForArchSpec(m_options.arch, flavor_string))
+ else if (flavor_string != nullptr && !disassembler->FlavorValidForArchSpec(m_options.arch, flavor_string))
result.AppendWarningWithFormat("invalid disassembler flavor \"%s\", using default.\n", flavor_string);
result.SetStatus (eReturnStatusSuccessFinishResult);
@@ -346,17 +340,17 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
{
ConstString name(m_options.func_name.c_str());
- if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
- m_options.arch,
- plugin_name,
- flavor_string,
- m_exe_ctx,
- name,
- NULL, // Module *
- m_options.num_instructions,
- m_options.show_mixed ? m_options.num_lines_context : 0,
- options,
- result.GetOutputStream()))
+ if (Disassembler::Disassemble(m_interpreter.GetDebugger(),
+ m_options.arch,
+ plugin_name,
+ flavor_string,
+ m_exe_ctx,
+ name,
+ nullptr, // Module *
+ m_options.num_instructions,
+ m_options.show_mixed ? m_options.num_lines_context : 0,
+ options,
+ result.GetOutputStream()))
{
result.SetStatus (eReturnStatusSuccessFinishResult);
}
@@ -373,7 +367,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
StackFrame *frame = m_exe_ctx.GetFramePtr();
if (m_options.frame_line)
{
- if (frame == NULL)
+ if (frame == nullptr)
{
result.AppendError ("Cannot disassemble around the current line without a selected frame.\n");
result.SetStatus (eReturnStatusFailed);
@@ -392,7 +386,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
}
else if (m_options.current_function)
{
- if (frame == NULL)
+ if (frame == nullptr)
{
result.AppendError ("Cannot disassemble around the current function without a selected frame.\n");
result.SetStatus (eReturnStatusFailed);
@@ -412,7 +406,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
{
if (m_options.at_pc)
{
- if (frame == NULL)
+ if (frame == nullptr)
{
result.AppendError ("Cannot disassemble around the current PC without a selected frame.\n");
result.SetStatus (eReturnStatusFailed);
@@ -498,7 +492,6 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
}
}
}
-
}
}
}
@@ -509,7 +502,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
if (m_options.num_instructions != 0)
{
- if (ranges.size() == 0)
+ if (ranges.empty())
{
// The default action is to disassemble the current frame function.
if (frame)
@@ -561,7 +554,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
}
else
{
- if (ranges.size() == 0)
+ if (ranges.empty())
{
// The default action is to disassemble the current frame function.
if (frame)
diff --git a/source/Commands/CommandObjectDisassemble.h b/source/Commands/CommandObjectDisassemble.h
index d892824d017d..ef19b3cf316a 100644
--- a/source/Commands/CommandObjectDisassemble.h
+++ b/source/Commands/CommandObjectDisassemble.h
@@ -30,7 +30,6 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter);
~CommandOptions() override;
@@ -47,16 +46,14 @@ public:
const char *
GetPluginName ()
{
- if (plugin_name.empty())
- return NULL;
- return plugin_name.c_str();
+ return (plugin_name.empty() ? nullptr : plugin_name.c_str());
}
const char *
GetFlavorString ()
{
if (flavor_string.empty() || flavor_string == "default")
- return NULL;
+ return nullptr;
return flavor_string.c_str();
}
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index 7f0b03b37c20..f2bd3ed367ca 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -7,12 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectExpression.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+
// Project includes
+#include "CommandObjectExpression.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
@@ -32,8 +34,6 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringRef.h"
using namespace lldb;
using namespace lldb_private;
@@ -43,31 +43,30 @@ CommandObjectExpression::CommandOptions::CommandOptions () :
{
}
-
-CommandObjectExpression::CommandOptions::~CommandOptions ()
-{
-}
+CommandObjectExpression::CommandOptions::~CommandOptions() = default;
static OptionEnumValueElement g_description_verbosity_type[] =
{
{ eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact", "Only show the description string"},
{ eLanguageRuntimeDescriptionDisplayVerbosityFull, "full", "Show the full output, including persistent variable's name and type"},
- { 0, NULL, NULL }
+ { 0, nullptr, nullptr }
};
OptionDefinition
CommandObjectExpression::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Specifies the Language to use when parsing the expression. If not set the target.language setting is used." },
- { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, NULL, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specifies the Language to use when parsing the expression. If not set the target.language setting is used." },
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "If true, simple fix-it hints will be automatically applied to the expression." },
+ { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, nullptr, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "top-level", 'p', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Interpret the expression as top-level definitions rather than code to be immediately executed."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "allow-jit", 'j', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Controls whether the expression can fall back to being JITted if it's not supported by the interpreter (defaults to true)."}
};
-
uint32_t
CommandObjectExpression::CommandOptions::GetNumDefinitions ()
{
@@ -113,6 +112,18 @@ CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &int
error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
break;
}
+
+ case 'j':
+ {
+ bool success;
+ bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
+ if (success)
+ allow_jit = tmp_value;
+ else
+ error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
+ break;
+ }
+
case 't':
{
bool success;
@@ -152,7 +163,22 @@ CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &int
unwind_on_error = false;
ignore_breakpoints = false;
break;
+
+ case 'p':
+ top_level = true;
+ break;
+ case 'X':
+ {
+ bool success;
+ bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
+ if (success)
+ auto_apply_fixits = tmp_value ? eLazyBoolYes : eLazyBoolNo;
+ else
+ error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
+ break;
+ }
+
default:
error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
break;
@@ -165,7 +191,7 @@ void
CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
{
Process *process = interpreter.GetExecutionContext().GetProcessPtr();
- if (process != NULL)
+ if (process != nullptr)
{
ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
unwind_on_error = process->GetUnwindOnErrorInExpressions();
@@ -182,6 +208,9 @@ CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpret
debug = false;
language = eLanguageTypeUnknown;
m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
+ auto_apply_fixits = eLazyBoolCalculate;
+ top_level = false;
+ allow_jit = true;
}
const OptionDefinition*
@@ -190,19 +219,18 @@ CommandObjectExpression::CommandOptions::GetDefinitions ()
return g_option_table;
}
-CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "expression",
- "Evaluate an expression in the current program context, using user defined variables and variables currently in scope.",
- NULL,
- eCommandProcessMustBePaused | eCommandTryTargetAPILock),
- IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
- m_option_group (interpreter),
- m_format_options (eFormatDefault),
- m_repl_option (LLDB_OPT_SET_1, false, "repl", 'r', "Drop into REPL", false, true),
- m_command_options (),
- m_expr_line_count (0),
- m_expr_lines ()
+CommandObjectExpression::CommandObjectExpression(CommandInterpreter &interpreter)
+ : CommandObjectRaw(
+ interpreter, "expression",
+ "Evaluate an expression on the current thread. Displays any returned value with LLDB's default formatting.",
+ nullptr, eCommandProcessMustBePaused | eCommandTryTargetAPILock),
+ IOHandlerDelegate(IOHandlerDelegate::Completion::Expression),
+ m_option_group(interpreter),
+ m_format_options(eFormatDefault),
+ m_repl_option(LLDB_OPT_SET_1, false, "repl", 'r', "Drop into REPL", false, true),
+ m_command_options(),
+ m_expr_line_count(0),
+ m_expr_lines()
{
SetHelpLong(
R"(
@@ -259,9 +287,7 @@ Examples:
m_option_group.Finalize();
}
-CommandObjectExpression::~CommandObjectExpression ()
-{
-}
+CommandObjectExpression::~CommandObjectExpression() = default;
Options *
CommandObjectExpression::GetOptions ()
@@ -269,14 +295,23 @@ CommandObjectExpression::GetOptions ()
return &m_option_group;
}
+static lldb_private::Error
+CanBeUsedForElementCountPrinting (ValueObject& valobj)
+{
+ CompilerType type(valobj.GetCompilerType());
+ CompilerType pointee;
+ if (!type.IsPointerType(&pointee))
+ return Error("as it does not refer to a pointer");
+ if (pointee.IsVoidType())
+ return Error("as it refers to a pointer to void");
+ return Error();
+}
+
bool
-CommandObjectExpression::EvaluateExpression
-(
- const char *expr,
- Stream *output_stream,
- Stream *error_stream,
- CommandReturnObject *result
-)
+CommandObjectExpression::EvaluateExpression(const char *expr,
+ Stream *output_stream,
+ Stream *error_stream,
+ CommandReturnObject *result)
{
// Don't use m_exe_ctx as this might be called asynchronously
// after the command object DoExecute has finished when doing
@@ -303,6 +338,20 @@ CommandObjectExpression::EvaluateExpression
options.SetTryAllThreads(m_command_options.try_all_threads);
options.SetDebug(m_command_options.debug);
options.SetLanguage(m_command_options.language);
+ options.SetExecutionPolicy(m_command_options.allow_jit ?
+ EvaluateExpressionOptions::default_execution_policy :
+ lldb_private::eExecutionPolicyNever);
+
+ bool auto_apply_fixits;
+ if (m_command_options.auto_apply_fixits == eLazyBoolCalculate)
+ auto_apply_fixits = target->GetEnableAutoApplyFixIts();
+ else
+ auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes ? true : false;
+
+ options.SetAutoApplyFixIts(auto_apply_fixits);
+
+ if (m_command_options.top_level)
+ options.SetExecutionPolicy(eExecutionPolicyTopLevel);
// If there is any chance we are going to stop and want to see
// what went wrong with our expression, we should generate debug info
@@ -315,7 +364,14 @@ CommandObjectExpression::EvaluateExpression
else
options.SetTimeoutUsec(0);
- target->EvaluateExpression(expr, frame, result_valobj_sp, options);
+ ExpressionResults success = target->EvaluateExpression(expr, frame, result_valobj_sp, options, &m_fixed_expression);
+
+ // We only tell you about the FixIt if we applied it. The compiler errors will suggest the FixIt if it parsed.
+ if (error_stream && !m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts())
+ {
+ if (success == eExpressionCompleted)
+ error_stream->Printf (" Fix-it applied, fixed expression was: \n %s\n", m_fixed_expression.c_str());
+ }
if (result_valobj_sp)
{
@@ -328,6 +384,17 @@ CommandObjectExpression::EvaluateExpression
if (format != eFormatDefault)
result_valobj_sp->SetFormat (format);
+ if (m_varobj_options.elem_count > 0)
+ {
+ Error error(CanBeUsedForElementCountPrinting(*result_valobj_sp));
+ if (error.Fail())
+ {
+ result->AppendErrorWithFormat("expression cannot be used with --element-count %s\n", error.AsCString(""));
+ result->SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
options.SetVariableFormatDisplayLanguage(result_valobj_sp->GetPreferredDisplayLanguage());
@@ -400,28 +467,21 @@ CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::str
error_sp->Flush();
}
-LineStatus
-CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
- StringList &lines,
- uint32_t line_idx,
- Error &error)
+bool
+CommandObjectExpression::IOHandlerIsInputComplete (IOHandler &io_handler,
+ StringList &lines)
{
- if (line_idx == UINT32_MAX)
+ // An empty lines is used to indicate the end of input
+ const size_t num_lines = lines.GetSize();
+ if (num_lines > 0 && lines[num_lines - 1].empty())
{
- // Remove the last line from "lines" so it doesn't appear
- // in our final expression
+ // Remove the last empty line from "lines" so it doesn't appear
+ // in our resulting input and return true to indicate we are done
+ // getting lines
lines.PopBack();
- error.Clear();
- return LineStatus::Done;
- }
- else if (line_idx + 1 == lines.GetSize())
- {
- // The last line was edited, if this line is empty, then we are done
- // getting our multiple lines.
- if (lines[line_idx].empty())
- return LineStatus::Done;
+ return true;
}
- return LineStatus::Success;
+ return false;
}
void
@@ -433,15 +493,15 @@ CommandObjectExpression::GetMultilineExpression ()
Debugger &debugger = GetCommandInterpreter().GetDebugger();
bool color_prompt = debugger.GetUseColor();
const bool multiple_lines = true; // Get multiple lines
- IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
- IOHandler::Type::Expression,
- "lldb-expr", // Name of input reader for history
- NULL, // No prompt
- NULL, // Continuation prompt
- multiple_lines,
- color_prompt,
- 1, // Show line numbers starting at 1
- *this));
+ IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger,
+ IOHandler::Type::Expression,
+ "lldb-expr", // Name of input reader for history
+ nullptr, // No prompt
+ nullptr, // Continuation prompt
+ multiple_lines,
+ color_prompt,
+ 1, // Show line numbers starting at 1
+ *this));
StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
if (output_sp)
@@ -453,15 +513,13 @@ CommandObjectExpression::GetMultilineExpression ()
}
bool
-CommandObjectExpression::DoExecute
-(
- const char *command,
- CommandReturnObject &result
-)
+CommandObjectExpression::DoExecute(const char *command,
+ CommandReturnObject &result)
{
+ m_fixed_expression.clear();
m_option_group.NotifyOptionParsingStarting();
- const char * expr = NULL;
+ const char * expr = nullptr;
if (command[0] == '\0')
{
@@ -472,7 +530,7 @@ CommandObjectExpression::DoExecute
if (command[0] == '-')
{
// We have some options and these options MUST end with --.
- const char *end_options = NULL;
+ const char *end_options = nullptr;
const char *s = command;
while (s && s[0])
{
@@ -568,7 +626,7 @@ CommandObjectExpression::DoExecute
}
}
// No expression following options
- else if (expr == NULL || expr[0] == '\0')
+ else if (expr == nullptr || expr[0] == '\0')
{
GetMultilineExpression ();
return result.Succeeded();
@@ -576,13 +634,31 @@ CommandObjectExpression::DoExecute
}
}
- if (expr == NULL)
+ if (expr == nullptr)
expr = command;
if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
+ {
+ Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
+ if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts())
+ {
+ CommandHistory &history = m_interpreter.GetCommandHistory();
+ // FIXME: Can we figure out what the user actually typed (e.g. some alias for expr???)
+ // If we can it would be nice to show that.
+ std::string fixed_command("expression ");
+ if (expr == command)
+ fixed_command.append(m_fixed_expression);
+ else
+ {
+ // Add in any options that might have been in the original command:
+ fixed_command.append(command, expr - command);
+ fixed_command.append(m_fixed_expression);
+ }
+ history.AppendString(fixed_command);
+ }
return true;
+ }
result.SetStatus (eReturnStatusFailed);
return false;
}
-
diff --git a/source/Commands/CommandObjectExpression.h b/source/Commands/CommandObjectExpression.h
index 7103675f3992..3445aef27665 100644
--- a/source/Commands/CommandObjectExpression.h
+++ b/source/Commands/CommandObjectExpression.h
@@ -14,13 +14,13 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/lldb-private-enumerations.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Target/ExecutionContext.h"
-
namespace lldb_private {
class CommandObjectExpression :
@@ -54,8 +54,10 @@ public:
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table[];
+ bool top_level;
bool unwind_on_error;
bool ignore_breakpoints;
+ bool allow_jit;
bool show_types;
bool show_summary;
bool debug;
@@ -63,6 +65,7 @@ public:
bool try_all_threads;
lldb::LanguageType language;
LanguageRuntimeDescriptionDisplayVerbosity m_verbosity;
+ LazyBool auto_apply_fixits;
};
CommandObjectExpression (CommandInterpreter &interpreter);
@@ -80,12 +83,11 @@ protected:
void
IOHandlerInputComplete(IOHandler &io_handler,
std::string &line) override;
-
- virtual LineStatus
- IOHandlerLinesUpdated (IOHandler &io_handler,
- StringList &lines,
- uint32_t line_idx,
- Error &error);
+
+ bool
+ IOHandlerIsInputComplete (IOHandler &io_handler,
+ StringList &lines) override;
+
bool
DoExecute(const char *command,
CommandReturnObject &result) override;
@@ -106,6 +108,7 @@ protected:
CommandOptions m_command_options;
uint32_t m_expr_line_count;
std::string m_expr_lines; // Multi-line expression support
+ std::string m_fixed_expression; // Holds the current expression's fixed text.
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp
index 9477b50a58df..cd436dfdb97a 100644
--- a/source/Commands/CommandObjectFrame.cpp
+++ b/source/Commands/CommandObjectFrame.cpp
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectFrame.h"
-
// C Includes
// C++ Includes
#include <string>
+
// Other libraries and framework includes
// Project includes
+#include "CommandObjectFrame.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
@@ -58,22 +58,15 @@ using namespace lldb_private;
class CommandObjectFrameInfo : public CommandObjectParsed
{
public:
-
- CommandObjectFrameInfo (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "frame info",
- "List information about the currently selected frame in the current thread.",
- "frame info",
- eCommandRequiresFrame |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused )
+ CommandObjectFrameInfo(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "frame info",
+ "List information about the current stack frame in the current thread.", "frame info",
+ eCommandRequiresFrame | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused)
{
}
- ~CommandObjectFrameInfo () override
- {
- }
+ ~CommandObjectFrameInfo() override = default;
protected:
bool
@@ -94,20 +87,16 @@ protected:
class CommandObjectFrameSelect : public CommandObjectParsed
{
public:
-
- class CommandOptions : public Options
+ class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options(interpreter)
{
OptionParsingStarting ();
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -148,17 +137,14 @@ public:
static OptionDefinition g_option_table[];
int32_t relative_frame_offset;
};
-
- CommandObjectFrameSelect (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "frame select",
- "Select a frame by index from within the current thread and make it the current frame.",
- NULL,
- eCommandRequiresThread |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_options (interpreter)
+
+ CommandObjectFrameSelect(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "frame select",
+ "Select the current stack frame by index from within the current thread (see 'thread backtrace'.)",
+ nullptr, eCommandRequiresThread | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
+ m_options(interpreter)
{
CommandArgumentEntry arg;
CommandArgumentData index_arg;
@@ -174,9 +160,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectFrameSelect () override
- {
- }
+ ~CommandObjectFrameSelect() override = default;
Options *
GetOptions () override
@@ -184,7 +168,6 @@ public:
return &m_options;
}
-
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -209,7 +192,7 @@ protected:
if (frame_idx == 0)
{
//If you are already at the bottom of the stack, then just warn and don't reset the frame.
- result.AppendError("Already at the bottom of the stack");
+ result.AppendError("Already at the bottom of the stack.");
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -229,7 +212,7 @@ protected:
if (frame_idx == num_frames - 1)
{
//If we are already at the top of the stack, just warn and don't reset the frame.
- result.AppendError("Already at the top of the stack");
+ result.AppendError("Already at the top of the stack.");
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -247,7 +230,7 @@ protected:
frame_idx = StringConvert::ToUInt32 (frame_idx_cstr, UINT32_MAX, 0, &success);
if (!success)
{
- result.AppendErrorWithFormat ("invalid frame index argument '%s'", frame_idx_cstr);
+ result.AppendErrorWithFormat("invalid frame index argument '%s'.", frame_idx_cstr);
result.SetStatus (eReturnStatusFailed);
return false;
}
@@ -283,16 +266,16 @@ protected:
return result.Succeeded();
}
-protected:
+protected:
CommandOptions m_options;
};
OptionDefinition
CommandObjectFrameSelect::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_1, false, "relative", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "A relative frame index offset from the current frame index."},
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_1, false, "relative", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "A relative frame index offset from the current frame index."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
#pragma mark CommandObjectFrameVariable
@@ -302,26 +285,19 @@ CommandObjectFrameSelect::CommandOptions::g_option_table[] =
class CommandObjectFrameVariable : public CommandObjectParsed
{
public:
-
- CommandObjectFrameVariable (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "frame variable",
- "Show frame variables. All argument and local variables "
- "that are in scope will be shown when no arguments are given. "
- "If any arguments are specified, they can be names of "
- "argument, local, file static and file global variables. "
- "Children of aggregate variables can be specified such as "
- "'var->child.x'.",
- NULL,
- eCommandRequiresFrame |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused |
- eCommandRequiresProcess),
- m_option_group (interpreter),
- m_option_variable(true), // Include the frame specific options by passing "true"
- m_option_format (eFormatDefault),
- m_varobj_options()
+ CommandObjectFrameVariable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "frame variable", "Show variables for the current stack frame. Defaults to all "
+ "arguments and local variables in scope. Names of argument, "
+ "local, file static and file global variables can be specified. "
+ "Children of aggregate variables can be specified such as "
+ "'var->child.x'.",
+ nullptr, eCommandRequiresFrame | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused | eCommandRequiresProcess),
+ m_option_group(interpreter),
+ m_option_variable(true), // Include the frame specific options by passing "true"
+ m_option_format(eFormatDefault),
+ m_varobj_options()
{
CommandArgumentEntry arg;
CommandArgumentData var_name_arg;
@@ -342,9 +318,7 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectFrameVariable () override
- {
- }
+ ~CommandObjectFrameVariable() override = default;
Options *
GetOptions () override
@@ -352,7 +326,6 @@ public:
return &m_option_group;
}
-
int
HandleArgumentCompletion (Args &input,
int &cursor_index,
@@ -367,14 +340,14 @@ public:
std::string completion_str (input.GetArgumentAtIndex(cursor_index));
completion_str.erase (cursor_char_position);
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eVariablePathCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eVariablePathCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -387,17 +360,15 @@ protected:
Stream &s = result.GetOutputStream();
- bool get_file_globals = true;
-
// Be careful about the stack frame, if any summary formatter runs code, it might clear the StackFrameList
// for the thread. So hold onto a shared pointer to the frame so it stays alive.
- VariableList *variable_list = frame->GetVariableList (get_file_globals);
+ VariableList *variable_list = frame->GetVariableList (m_option_variable.show_globals);
VariableSP var_sp;
ValueObjectSP valobj_sp;
- const char *name_cstr = NULL;
+ const char *name_cstr = nullptr;
size_t idx;
TypeSummaryImplSP summary_format_sp;
@@ -423,7 +394,7 @@ protected:
// If we have any args to the variable command, we will make
// variable objects from them...
- for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != NULL; ++idx)
+ for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != nullptr; ++idx)
{
if (m_option_variable.use_regex)
{
@@ -502,16 +473,18 @@ protected:
options.SetVariableFormatDisplayLanguage(valobj_sp->GetPreferredDisplayLanguage());
Stream &output_stream = result.GetOutputStream();
- options.SetRootValueObjectName(valobj_sp->GetParent() ? name_cstr : NULL);
+ options.SetRootValueObjectName(valobj_sp->GetParent() ? name_cstr : nullptr);
valobj_sp->Dump(output_stream,options);
}
else
{
- const char *error_cstr = error.AsCString(NULL);
+ const char *error_cstr = error.AsCString(nullptr);
if (error_cstr)
result.GetErrorStream().Printf("error: %s\n", error_cstr);
else
- result.GetErrorStream().Printf ("error: unable to find any variable expression path that matches '%s'\n", name_cstr);
+ result.GetErrorStream().Printf(
+ "error: unable to find any variable expression path that matches '%s'.\n",
+ name_cstr);
}
}
}
@@ -529,13 +502,16 @@ protected:
switch (var_sp->GetScope())
{
case eValueTypeVariableGlobal:
- dump_variable = m_option_variable.show_globals;
+ // Always dump globals since we only fetched them if
+ // m_option_variable.show_scope was true
if (dump_variable && m_option_variable.show_scope)
scope_string = "GLOBAL: ";
break;
case eValueTypeVariableStatic:
- dump_variable = m_option_variable.show_globals;
+ // Always dump globals since we only fetched them if
+ // m_option_variable.show_scope was true, or this is
+ // a static variable from a block in the current scope
if (dump_variable && m_option_variable.show_scope)
scope_string = "STATIC: ";
break;
@@ -552,6 +528,10 @@ protected:
scope_string = " LOCAL: ";
break;
+ case eValueTypeVariableThreadLocal:
+ if (dump_variable && m_option_variable.show_scope)
+ scope_string = "THREAD: ";
+ break;
default:
break;
}
@@ -572,8 +552,8 @@ protected:
// that are not in scope to avoid extra unneeded output
if (valobj_sp->IsInScope ())
{
- if (false == valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
- true == valobj_sp->IsRuntimeSupportValue())
+ if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
+ valobj_sp->IsRuntimeSupportValue())
continue;
if (!scope_string.empty())
@@ -607,33 +587,28 @@ protected:
return result.Succeeded();
}
-protected:
+protected:
OptionGroupOptions m_option_group;
OptionGroupVariable m_option_variable;
OptionGroupFormat m_option_format;
OptionGroupValueObjectDisplay m_varobj_options;
};
-
#pragma mark CommandObjectMultiwordFrame
//-------------------------------------------------------------------------
// CommandObjectMultiwordFrame
//-------------------------------------------------------------------------
-CommandObjectMultiwordFrame::CommandObjectMultiwordFrame (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "frame",
- "A set of commands for operating on the current thread's frames.",
- "frame <subcommand> [<subcommand-options>]")
+CommandObjectMultiwordFrame::CommandObjectMultiwordFrame(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "frame",
+ "Commands for selecting and examing the current thread's stack frames.",
+ "frame <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("info", CommandObjectSP (new CommandObjectFrameInfo (interpreter)));
LoadSubCommand ("select", CommandObjectSP (new CommandObjectFrameSelect (interpreter)));
LoadSubCommand ("variable", CommandObjectSP (new CommandObjectFrameVariable (interpreter)));
}
-CommandObjectMultiwordFrame::~CommandObjectMultiwordFrame ()
-{
-}
-
+CommandObjectMultiwordFrame::~CommandObjectMultiwordFrame() = default;
diff --git a/source/Commands/CommandObjectHelp.cpp b/source/Commands/CommandObjectHelp.cpp
index 18dc44a32b5a..4cf74885e998 100644
--- a/source/Commands/CommandObjectHelp.cpp
+++ b/source/Commands/CommandObjectHelp.cpp
@@ -7,12 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectHelp.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "CommandObjectHelp.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/Options.h"
@@ -25,11 +24,36 @@ using namespace lldb_private;
// CommandObjectHelp
//-------------------------------------------------------------------------
-CommandObjectHelp::CommandObjectHelp (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "help",
- "Show a list of all debugger commands, or give details about specific commands.",
- "help [<cmd-name>]"), m_options (interpreter)
+void
+CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage (Stream *s,
+ const char* command,
+ const char* prefix,
+ const char* subcommand,
+ bool include_apropos,
+ bool include_type_lookup)
+{
+ if (s && command && *command)
+ {
+ s->Printf("'%s' is not a known command.\n", command);
+ s->Printf("Try '%shelp' to see a current list of commands.\n", prefix ? prefix : "");
+ if (include_apropos)
+ {
+ s->Printf("Try '%sapropos %s' for a list of related commands.\n",
+ prefix ? prefix : "", subcommand ? subcommand : command);
+ }
+ if (include_type_lookup)
+ {
+ s->Printf("Try '%stype lookup %s' for information on types, methods, functions, modules, etc.",
+ prefix ? prefix : "", subcommand ? subcommand : command);
+ }
+ }
+}
+
+CommandObjectHelp::CommandObjectHelp(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "help",
+ "Show a list of all debugger commands, or give details about a specific command.",
+ "help [<cmd-name>]"),
+ m_options(interpreter)
{
CommandArgumentEntry arg;
CommandArgumentData command_arg;
@@ -45,17 +69,15 @@ CommandObjectHelp::CommandObjectHelp (CommandInterpreter &interpreter) :
m_arguments.push_back (arg);
}
-CommandObjectHelp::~CommandObjectHelp()
-{
-}
+CommandObjectHelp::~CommandObjectHelp() = default;
OptionDefinition
CommandObjectHelp::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "hide-aliases", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Hide aliases in the command list."},
- { LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Hide user-defined commands from the list."},
- { LLDB_OPT_SET_ALL, false, "show-hidden-commands", 'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Include commands prefixed with an underscore."},
- { 0, false, NULL, 0, 0, 0, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "hide-aliases", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Hide aliases in the command list."},
+ { LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Hide user-defined commands from the list."},
+ { LLDB_OPT_SET_ALL, false, "show-hidden-commands", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Include commands prefixed with an underscore."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
bool
@@ -88,17 +110,20 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
bool is_alias_command = m_interpreter.AliasExists (command.GetArgumentAtIndex (0));
std::string alias_name = command.GetArgumentAtIndex(0);
- if (cmd_obj != NULL)
+ if (cmd_obj != nullptr)
{
StringList matches;
bool all_okay = true;
CommandObject *sub_cmd_obj = cmd_obj;
// Loop down through sub_command dictionaries until we find the command object that corresponds
// to the help command entered.
+ std::string sub_command;
for (size_t i = 1; i < argc && all_okay; ++i)
{
- std::string sub_command = command.GetArgumentAtIndex(i);
+ sub_command = command.GetArgumentAtIndex(i);
matches.Clear();
+ if (sub_cmd_obj->IsAlias())
+ sub_cmd_obj = ((CommandAlias*)sub_cmd_obj)->GetUnderlyingCommand().get();
if (! sub_cmd_obj->IsMultiwordObject ())
{
all_okay = false;
@@ -107,7 +132,7 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
{
CommandObject *found_cmd;
found_cmd = sub_cmd_obj->GetSubcommandObject(sub_command.c_str(), &matches);
- if (found_cmd == NULL)
+ if (found_cmd == nullptr)
all_okay = false;
else if (matches.GetSize() > 1)
all_okay = false;
@@ -116,7 +141,7 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
}
}
- if (!all_okay || (sub_cmd_obj == NULL))
+ if (!all_okay || (sub_cmd_obj == nullptr))
{
std::string cmd_string;
command.GetCommandString (cmd_string);
@@ -136,21 +161,22 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
}
else if (!sub_cmd_obj)
{
- result.AppendErrorWithFormat("'%s' is not a known command.\n"
- "Try '%shelp' to see a current list of commands.\n",
- cmd_string.c_str(),
- m_interpreter.GetCommandPrefix());
+ StreamString error_msg_stream;
+ GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
+ cmd_string.c_str(),
+ m_interpreter.GetCommandPrefix(),
+ sub_command.c_str());
+ result.AppendErrorWithFormat("%s",error_msg_stream.GetData());
result.SetStatus (eReturnStatusFailed);
return false;
}
else
{
- result.GetOutputStream().Printf("'%s' is not a known command.\n"
- "Try '%shelp' to see a current list of commands.\n"
- "The closest match is '%s'. Help on it follows.\n\n",
- cmd_string.c_str(),
- m_interpreter.GetCommandPrefix(),
- sub_cmd_obj->GetCommandName());
+ GenerateAdditionalHelpAvenuesMessage(&result.GetOutputStream(),
+ cmd_string.c_str(),
+ m_interpreter.GetCommandPrefix(),
+ sub_command.c_str());
+ result.GetOutputStream().Printf("\nThe closest match is '%s'. Help on it follows.\n\n", sub_cmd_obj->GetCommandName());
}
}
@@ -159,7 +185,7 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
if (is_alias_command)
{
StreamString sstr;
- m_interpreter.GetAliasHelp (alias_name.c_str(), cmd_obj->GetCommandName(), sstr);
+ m_interpreter.GetAlias(alias_name.c_str())->GetAliasExpansion(sstr);
result.GetOutputStream().Printf ("\n'%s' is an abbreviation for %s\n", alias_name.c_str(), sstr.GetData());
}
}
@@ -185,10 +211,9 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
}
else
{
- result.AppendErrorWithFormat
- ("'%s' is not a known command.\nTry '%shelp' to see a current list of commands.\n",
- command.GetArgumentAtIndex(0),
- m_interpreter.GetCommandPrefix());
+ StreamString error_msg_stream;
+ GenerateAdditionalHelpAvenuesMessage(&error_msg_stream, command.GetArgumentAtIndex(0), m_interpreter.GetCommandPrefix());
+ result.AppendErrorWithFormat("%s",error_msg_stream.GetData());
result.SetStatus (eReturnStatusFailed);
}
}
@@ -198,16 +223,13 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
}
int
-CommandObjectHelp::HandleCompletion
-(
- Args &input,
- int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches
-)
+CommandObjectHelp::HandleCompletion(Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches)
{
// Return the completions of the commands in the help system:
if (cursor_index == 0)
diff --git a/source/Commands/CommandObjectHelp.h b/source/Commands/CommandObjectHelp.h
index 1dd7b9b8d6a8..a374a10e3e7d 100644
--- a/source/Commands/CommandObjectHelp.h
+++ b/source/Commands/CommandObjectHelp.h
@@ -40,6 +40,14 @@ public:
bool &word_complete,
StringList &matches) override;
+ static void
+ GenerateAdditionalHelpAvenuesMessage (Stream *s,
+ const char* command,
+ const char* prefix = nullptr,
+ const char* subcommand = nullptr,
+ bool include_apropos = true,
+ bool include_type_lookup = true);
+
class CommandOptions : public Options
{
public:
diff --git a/source/Commands/CommandObjectLanguage.cpp b/source/Commands/CommandObjectLanguage.cpp
index 5a8f166cb3a6..ebe33765acc6 100644
--- a/source/Commands/CommandObjectLanguage.cpp
+++ b/source/Commands/CommandObjectLanguage.cpp
@@ -20,22 +20,14 @@
using namespace lldb;
using namespace lldb_private;
-CommandObjectLanguage::CommandObjectLanguage (CommandInterpreter &interpreter) :
-CommandObjectMultiword (interpreter,
- "language",
- "A set of commands for managing language-specific functionality.'.",
- "language <language-name> <subcommand> [<subcommand-options>]"
- )
+CommandObjectLanguage::CommandObjectLanguage(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "language", "Commands specific to a source language.",
+ "language <language-name> <subcommand> [<subcommand-options>]")
{
//Let the LanguageRuntime populates this command with subcommands
LanguageRuntime::InitializeCommands(this);
}
-void
-CommandObjectLanguage::GenerateHelpText (Stream &output_stream) {
- CommandObjectMultiword::GenerateHelpText(output_stream);
-}
-
CommandObjectLanguage::~CommandObjectLanguage ()
{
}
diff --git a/source/Commands/CommandObjectLanguage.h b/source/Commands/CommandObjectLanguage.h
index 15902bb8ad4b..6003a590d77d 100644
--- a/source/Commands/CommandObjectLanguage.h
+++ b/source/Commands/CommandObjectLanguage.h
@@ -27,9 +27,6 @@ namespace lldb_private {
~CommandObjectLanguage() override;
- void
- GenerateHelpText(Stream &output_stream) override;
-
protected:
bool
DoExecute (Args& command, CommandReturnObject &result);
diff --git a/source/Commands/CommandObjectLog.cpp b/source/Commands/CommandObjectLog.cpp
index 8e29cd5223b0..ca6b39c0ebfa 100644
--- a/source/Commands/CommandObjectLog.cpp
+++ b/source/Commands/CommandObjectLog.cpp
@@ -7,12 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectLog.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "CommandObjectLog.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Host/FileSpec.h"
@@ -23,24 +22,20 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Timer.h"
-
#include "lldb/Core/Debugger.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
-
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
-
class CommandObjectLogEnable : public CommandObjectParsed
{
public:
@@ -48,13 +43,12 @@ public:
// Constructors and Destructors
//------------------------------------------------------------------
CommandObjectLogEnable(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "log enable",
- "Enable logging for a single log channel.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "log enable",
+ "Enable logging for a single log channel.",
+ nullptr),
m_options (interpreter)
{
-
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
CommandArgumentData channel_arg;
@@ -77,9 +71,7 @@ public:
m_arguments.push_back (arg2);
}
- ~CommandObjectLogEnable() override
- {
- }
+ ~CommandObjectLogEnable() override = default;
Options *
GetOptions () override
@@ -112,7 +104,6 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
log_file (),
@@ -120,10 +111,7 @@ public:
{
}
-
- ~CommandOptions () override
- {
- }
+ ~CommandOptions () override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -211,17 +199,17 @@ protected:
OptionDefinition
CommandObjectLogEnable::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Set the destination file to log to."},
-{ LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." },
-{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable verbose logging." },
-{ LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable debug logging." },
-{ LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." },
-{ LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Prepend all log lines with a timestamp." },
-{ LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." },
-{ LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." },
-{ LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Append a stack backtrace to each log line." },
-{ LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Append to the log file instead of overwriting." },
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Set the destination file to log to."},
+{ LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." },
+{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose logging." },
+{ LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable debug logging." },
+{ LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." },
+{ LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with a timestamp." },
+{ LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." },
+{ LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." },
+{ LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append a stack backtrace to each log line." },
+{ LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to the log file instead of overwriting." },
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
class CommandObjectLogDisable : public CommandObjectParsed
@@ -231,10 +219,10 @@ public:
// Constructors and Destructors
//------------------------------------------------------------------
CommandObjectLogDisable(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "log disable",
- "Disable one or more log channel categories.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "log disable",
+ "Disable one or more log channel categories.",
+ nullptr)
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -258,9 +246,7 @@ public:
m_arguments.push_back (arg2);
}
- ~CommandObjectLogDisable() override
- {
- }
+ ~CommandObjectLogDisable() override = default;
protected:
bool
@@ -310,10 +296,10 @@ public:
// Constructors and Destructors
//------------------------------------------------------------------
CommandObjectLogList(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "log list",
- "List the log categories for one or more log channels. If none specified, lists them all.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "log list",
+ "List the log categories for one or more log channels. If none specified, lists them all.",
+ nullptr)
{
CommandArgumentEntry arg;
CommandArgumentData channel_arg;
@@ -329,9 +315,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectLogList() override
- {
- }
+ ~CommandObjectLogList() override = default;
protected:
bool
@@ -392,9 +376,7 @@ public:
{
}
- ~CommandObjectLogTimer() override
- {
- }
+ ~CommandObjectLogTimer() override = default;
protected:
bool
@@ -429,7 +411,6 @@ protected:
Timer::ResetCategoryTimes ();
result.SetStatus(eReturnStatusSuccessFinishResult);
}
-
}
else if (argc == 2)
{
@@ -470,14 +451,9 @@ protected:
}
};
-//----------------------------------------------------------------------
-// CommandObjectLog constructor
-//----------------------------------------------------------------------
-CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "log",
- "A set of commands for operating on logs.",
- "log <command> [<command-options>]")
+CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "log", "Commands controlling LLDB internal logging.",
+ "log <subcommand> [<command-options>]")
{
LoadSubCommand ("enable", CommandObjectSP (new CommandObjectLogEnable (interpreter)));
LoadSubCommand ("disable", CommandObjectSP (new CommandObjectLogDisable (interpreter)));
@@ -485,13 +461,4 @@ CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) :
LoadSubCommand ("timers", CommandObjectSP (new CommandObjectLogTimer (interpreter)));
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-CommandObjectLog::~CommandObjectLog()
-{
-}
-
-
-
-
+CommandObjectLog::~CommandObjectLog() = default;
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index f8fe456d4d46..7065e65ac96b 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -7,60 +7,62 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectMemory.h"
-
// C Includes
#include <inttypes.h>
// C++ Includes
// Other libraries and framework includes
#include "clang/AST/Decl.h"
+
// Project includes
+#include "CommandObjectMemory.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
-#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Args.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupOutputFile.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/MemoryHistory.h"
+#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-private.h"
+
using namespace lldb;
using namespace lldb_private;
static OptionDefinition
g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "num-per-line" ,'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNumberPerLine ,"The number of items per line to display."},
- { LLDB_OPT_SET_2, false, "binary" ,'b', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone ,"If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that uses the format, size, count and number per line settings."},
- { LLDB_OPT_SET_3, true , "type" ,'t', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone ,"The name of a type to view memory as."},
- { LLDB_OPT_SET_3, false , "offset" ,'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount ,"How many elements of the specified type to skip before starting to display data."},
+ { LLDB_OPT_SET_1, false, "num-per-line" ,'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNumberPerLine ,"The number of items per line to display."},
+ { LLDB_OPT_SET_2, false, "binary" ,'b', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone ,"If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that uses the format, size, count and number per line settings."},
+ { LLDB_OPT_SET_3, true , "type" ,'t', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone ,"The name of a type to view memory as."},
+ { LLDB_OPT_SET_3, false , "offset" ,'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount ,"How many elements of the specified type to skip before starting to display data."},
{ LLDB_OPT_SET_1|
LLDB_OPT_SET_2|
- LLDB_OPT_SET_3, false, "force" ,'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone ,"Necessary if reading over target.max-memory-read-size bytes."},
+ LLDB_OPT_SET_3, false, "force" ,'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone ,"Necessary if reading over target.max-memory-read-size bytes."},
};
-
-
class OptionGroupReadMemory : public OptionGroup
{
public:
-
OptionGroupReadMemory () :
m_num_per_line (1,1),
m_output_as_binary (false),
@@ -69,11 +71,8 @@ public:
{
}
- ~OptionGroupReadMemory () override
- {
- }
-
-
+ ~OptionGroupReadMemory() override = default;
+
uint32_t
GetNumDefinitions () override
{
@@ -206,9 +205,11 @@ public:
if (byte_size_option_set)
{
if (byte_size_value > 1)
- error.SetErrorStringWithFormat ("display format (bytes/bytes with ascii) conflicts with the specified byte size %" PRIu64 "\n"
- "\tconsider using a different display format or don't specify the byte size",
- byte_size_value.GetCurrentValue());
+ error.SetErrorStringWithFormat(
+ "display format (bytes/bytes with ASCII) conflicts with the specified byte size %" PRIu64
+ "\n"
+ "\tconsider using a different display format or don't specify the byte size.",
+ byte_size_value.GetCurrentValue());
}
else
byte_size_value = 1;
@@ -217,6 +218,7 @@ public:
if (!count_option_set)
format_options.GetCountValue() = 32;
break;
+
case eFormatCharArray:
case eFormatChar:
case eFormatCharPrintable:
@@ -227,6 +229,7 @@ public:
if (!count_option_set)
format_options.GetCountValue() = 64;
break;
+
case eFormatComplex:
if (!byte_size_option_set)
byte_size_value = 8;
@@ -235,6 +238,7 @@ public:
if (!count_option_set)
format_options.GetCountValue() = 8;
break;
+
case eFormatComplexInteger:
if (!byte_size_option_set)
byte_size_value = 8;
@@ -243,6 +247,7 @@ public:
if (!count_option_set)
format_options.GetCountValue() = 8;
break;
+
case eFormatHex:
if (!byte_size_option_set)
byte_size_value = 4;
@@ -309,32 +314,26 @@ public:
OptionValueUInt64 m_offset;
};
-
-
//----------------------------------------------------------------------
// Read memory from the inferior process
//----------------------------------------------------------------------
class CommandObjectMemoryRead : public CommandObjectParsed
{
public:
-
- CommandObjectMemoryRead (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "memory read",
- "Read from the memory of the process being debugged.",
- NULL,
- eCommandRequiresTarget | eCommandProcessMustBePaused),
- m_option_group (interpreter),
- m_format_options (eFormatBytesWithASCII, 1, 8),
- m_memory_options (),
- m_outfile_options (),
- m_varobj_options(),
- m_next_addr(LLDB_INVALID_ADDRESS),
- m_prev_byte_size(0),
- m_prev_format_options (eFormatBytesWithASCII, 1, 8),
- m_prev_memory_options (),
- m_prev_outfile_options (),
- m_prev_varobj_options()
+ CommandObjectMemoryRead(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "memory read", "Read from the memory of the current target process.",
+ nullptr, eCommandRequiresTarget | eCommandProcessMustBePaused),
+ m_option_group(interpreter),
+ m_format_options(eFormatBytesWithASCII, 1, 8),
+ m_memory_options(),
+ m_outfile_options(),
+ m_varobj_options(),
+ m_next_addr(LLDB_INVALID_ADDRESS),
+ m_prev_byte_size(0),
+ m_prev_format_options(eFormatBytesWithASCII, 1, 8),
+ m_prev_memory_options(),
+ m_prev_outfile_options(),
+ m_prev_varobj_options()
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -376,9 +375,7 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectMemoryRead () override
- {
- }
+ ~CommandObjectMemoryRead() override = default;
Options *
GetOptions () override
@@ -487,7 +484,7 @@ protected:
{
case '*':
++pointer_count;
- // fall through...
+ LLVM_FALLTHROUGH;
case ' ':
case '\t':
type_str.erase(type_str.size()-1);
@@ -514,6 +511,7 @@ protected:
}
}
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
ConstString lookup_type_name(type_str.c_str());
StackFrame *frame = m_exe_ctx.GetFramePtr();
if (frame)
@@ -524,7 +522,8 @@ protected:
sc.module_sp->FindTypes (sc,
lookup_type_name,
exact_match,
- 1,
+ 1,
+ searched_symbol_files,
type_list);
}
}
@@ -533,7 +532,8 @@ protected:
target->GetImages().FindTypes (sc,
lookup_type_name,
exact_match,
- 1,
+ 1,
+ searched_symbol_files,
type_list);
}
@@ -541,7 +541,7 @@ protected:
{
if (ClangPersistentVariables *persistent_vars = llvm::dyn_cast_or_null<ClangPersistentVariables>(target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC)))
{
- clang::TypeDecl *tdecl = persistent_vars->GetPersistentType(ConstString(lookup_type_name));
+ clang::TypeDecl *tdecl = llvm::dyn_cast_or_null<clang::TypeDecl>(persistent_vars->GetPersistentDecl(ConstString(lookup_type_name)));
if (tdecl)
{
@@ -551,7 +551,7 @@ protected:
}
}
- if (clang_ast_type.IsValid() == false)
+ if (!clang_ast_type.IsValid())
{
if (type_list.GetSize() == 0)
{
@@ -662,7 +662,8 @@ protected:
if (argc == 2)
{
- lldb::addr_t end_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
+ lldb::addr_t end_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1),
+ LLDB_INVALID_ADDRESS, nullptr);
if (end_addr == LLDB_INVALID_ADDRESS)
{
result.AppendError("invalid end address expression.");
@@ -702,7 +703,7 @@ protected:
if (clang_ast_type.GetOpaqueQualType())
{
// Make sure we don't display our type as ASCII bytes like the default memory read
- if (m_format_options.GetFormatValue().OptionWasSet() == false)
+ if (!m_format_options.GetFormatValue().OptionWasSet())
m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
bytes_read = clang_ast_type.GetByteSize(nullptr) * m_format_options.GetCountValue().GetCurrentValue();
@@ -713,14 +714,14 @@ protected:
else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString)
{
data_sp.reset (new DataBufferHeap (total_byte_size, '\0'));
- if (data_sp->GetBytes() == NULL)
+ if (data_sp->GetBytes() == nullptr)
{
result.AppendErrorWithFormat ("can't allocate 0x%" PRIx32 " bytes for the memory read buffer, specify a smaller size to read", (uint32_t)total_byte_size);
result.SetStatus(eReturnStatusFailed);
return false;
}
- Address address(addr, NULL);
+ Address address(addr, nullptr);
bytes_read = target->ReadMemory(address, false, data_sp->GetBytes (), data_sp->GetByteSize(), error);
if (bytes_read == 0)
{
@@ -750,7 +751,7 @@ protected:
if (!m_format_options.GetCountValue().OptionWasSet())
item_count = 1;
data_sp.reset (new DataBufferHeap ((item_byte_size+1) * item_count, '\0')); // account for NULLs as necessary
- if (data_sp->GetBytes() == NULL)
+ if (data_sp->GetBytes() == nullptr)
{
result.AppendErrorWithFormat ("can't allocate 0x%" PRIx64 " bytes for the memory read buffer, specify a smaller size to read", (uint64_t)((item_byte_size+1) * item_count));
result.SetStatus(eReturnStatusFailed);
@@ -804,7 +805,7 @@ protected:
m_prev_clang_ast_type = clang_ast_type;
StreamFile outfile_stream;
- Stream *output_stream = NULL;
+ Stream *output_stream = nullptr;
const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue();
if (outfile_spec)
{
@@ -855,7 +856,6 @@ protected:
output_stream = &result.GetOutputStream();
}
-
ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
if (clang_ast_type.GetOpaqueQualType())
{
@@ -902,7 +902,7 @@ protected:
&& (item_byte_size != 1))
{
// if a count was not passed, or it is 1
- if (m_format_options.GetCountValue().OptionWasSet() == false || item_count == 1)
+ if (!m_format_options.GetCountValue().OptionWasSet() || item_count == 1)
{
// this turns requests such as
// memory read -fc -s10 -c1 *charPtrPtr
@@ -956,10 +956,10 @@ protected:
OptionDefinition
g_memory_find_option_table[] =
{
- { LLDB_OPT_SET_1, false, "expression", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."},
- { LLDB_OPT_SET_2, false, "string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Use text to find a byte pattern."},
- { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many times to perform the search."},
- { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "dump-offset", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."},
+ { LLDB_OPT_SET_1, true, "expression", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."},
+ { LLDB_OPT_SET_2, true, "string", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Use text to find a byte pattern."},
+ { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many times to perform the search."},
+ { LLDB_OPT_SET_ALL, false, "dump-offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."},
};
//----------------------------------------------------------------------
@@ -968,7 +968,6 @@ g_memory_find_option_table[] =
class CommandObjectMemoryFind : public CommandObjectParsed
{
public:
-
class OptionGroupFindMemory : public OptionGroup
{
public:
@@ -978,11 +977,9 @@ public:
m_offset(0)
{
}
-
- ~OptionGroupFindMemory () override
- {
- }
-
+
+ ~OptionGroupFindMemory() override = default;
+
uint32_t
GetNumDefinitions () override
{
@@ -1043,15 +1040,12 @@ public:
OptionValueUInt64 m_count;
OptionValueUInt64 m_offset;
};
-
- CommandObjectMemoryFind (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "memory find",
- "Find a value in the memory of the process being debugged.",
- NULL,
- eCommandRequiresProcess | eCommandProcessMustBeLaunched),
- m_option_group (interpreter),
- m_memory_options ()
+
+ CommandObjectMemoryFind(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "memory find", "Find a value in the memory of the current target process.",
+ nullptr, eCommandRequiresProcess | eCommandProcessMustBeLaunched),
+ m_option_group(interpreter),
+ m_memory_options()
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -1076,14 +1070,12 @@ public:
m_arguments.push_back (arg1);
m_arguments.push_back (arg2);
- m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
+ m_option_group.Append (&m_memory_options);
m_option_group.Finalize();
}
-
- ~CommandObjectMemoryFind () override
- {
- }
-
+
+ ~CommandObjectMemoryFind() override = default;
+
Options *
GetOptions () override
{
@@ -1136,7 +1128,7 @@ protected:
StackFrame* frame = m_exe_ctx.GetFramePtr();
ValueObjectSP result_sp;
if ((eExpressionCompleted == process->GetTarget().EvaluateExpression(m_memory_options.m_expr.GetStringValue(), frame, result_sp)) &&
- result_sp.get())
+ result_sp)
{
uint64_t value = result_sp->GetValueAsUnsigned(0);
switch (result_sp->GetCompilerType().GetByteSize(nullptr))
@@ -1246,12 +1238,11 @@ protected:
OptionGroupFindMemory m_memory_options;
};
-
OptionDefinition
g_memory_write_option_table[] =
{
-{ LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Write memory using the contents of a file."},
-{ LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "Start writing bytes from an offset within the input file."},
+{ LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Write memory using the contents of a file."},
+{ LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "Start writing bytes from an offset within the input file."},
};
//----------------------------------------------------------------------
@@ -1260,7 +1251,6 @@ g_memory_write_option_table[] =
class CommandObjectMemoryWrite : public CommandObjectParsed
{
public:
-
class OptionGroupWriteMemory : public OptionGroup
{
public:
@@ -1269,9 +1259,7 @@ public:
{
}
- ~OptionGroupWriteMemory () override
- {
- }
+ ~OptionGroupWriteMemory() override = default;
uint32_t
GetNumDefinitions () override
@@ -1333,15 +1321,12 @@ public:
off_t m_infile_offset;
};
- CommandObjectMemoryWrite (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "memory write",
- "Write to the memory of the process being debugged.",
- NULL,
- eCommandRequiresProcess | eCommandProcessMustBeLaunched),
- m_option_group (interpreter),
- m_format_options (eFormatBytes, 1, UINT64_MAX),
- m_memory_options ()
+ CommandObjectMemoryWrite(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "memory write", "Write to the memory of the current target process.",
+ nullptr, eCommandRequiresProcess | eCommandProcessMustBeLaunched),
+ m_option_group(interpreter),
+ m_format_options(eFormatBytes, 1, UINT64_MAX),
+ m_memory_options()
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -1370,12 +1355,9 @@ public:
m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_SIZE , LLDB_OPT_SET_1|LLDB_OPT_SET_2);
m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
m_option_group.Finalize();
-
}
- ~CommandObjectMemoryWrite () override
- {
- }
+ ~CommandObjectMemoryWrite() override = default;
Options *
GetOptions () override
@@ -1551,7 +1533,6 @@ protected:
case eFormatHex:
case eFormatHexUppercase:
case eFormatPointer:
-
// Decode hex bytes
uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 16, &success);
if (!success)
@@ -1699,13 +1680,12 @@ protected:
class CommandObjectMemoryHistory : public CommandObjectParsed
{
public:
-
- CommandObjectMemoryHistory (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "memory history",
- "Prints out the recorded stack traces for allocation/deallocation of a memory address.",
- NULL,
- eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBePaused | eCommandProcessMustBeLaunched)
+ CommandObjectMemoryHistory(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "memory history",
+ "Print recorded stack traces for allocation/deallocation events associated with an address.", nullptr,
+ eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBePaused |
+ eCommandProcessMustBeLaunched)
{
CommandArgumentEntry arg1;
CommandArgumentData addr_arg;
@@ -1720,11 +1700,9 @@ public:
// Push the data for the first argument into the m_arguments vector.
m_arguments.push_back (arg1);
}
-
- ~CommandObjectMemoryHistory () override
- {
- }
-
+
+ ~CommandObjectMemoryHistory() override = default;
+
const char *
GetRepeatCommand (Args &current_command_args, uint32_t index) override
{
@@ -1763,7 +1741,7 @@ protected:
const ProcessSP &process_sp = m_exe_ctx.GetProcessSP();
const MemoryHistorySP &memory_history = MemoryHistory::FindPlugin(process_sp);
- if (! memory_history.get())
+ if (!memory_history)
{
result.AppendError("no available memory history provider");
result.SetStatus(eReturnStatusFailed);
@@ -1780,26 +1758,124 @@ protected:
return true;
}
-
};
+//-------------------------------------------------------------------------
+// CommandObjectMemoryRegion
+//-------------------------------------------------------------------------
+#pragma mark CommandObjectMemoryRegion
+
+class CommandObjectMemoryRegion : public CommandObjectParsed
+{
+public:
+ CommandObjectMemoryRegion(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "memory region",
+ "Get information on the memory region containing an address in the current target process.",
+ "memory region ADDR", eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched),
+ m_prev_end_addr(LLDB_INVALID_ADDRESS)
+ {
+ }
+
+ ~CommandObjectMemoryRegion() override = default;
+
+protected:
+ bool
+ DoExecute(Args &command, CommandReturnObject &result) override
+ {
+ ProcessSP process_sp = m_exe_ctx.GetProcessSP();
+ if (process_sp)
+ {
+ Error error;
+ lldb::addr_t load_addr = m_prev_end_addr;
+ m_prev_end_addr = LLDB_INVALID_ADDRESS;
+
+ const size_t argc = command.GetArgumentCount();
+ if (argc > 1 || (argc == 0 && load_addr == LLDB_INVALID_ADDRESS))
+ {
+ result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n", m_cmd_name.c_str(),
+ m_cmd_syntax.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ else
+ {
+ const char *load_addr_cstr = command.GetArgumentAtIndex(0);
+ if (command.GetArgumentCount() == 1)
+ {
+ load_addr = Args::StringToAddress(&m_exe_ctx, load_addr_cstr, LLDB_INVALID_ADDRESS, &error);
+ if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS)
+ {
+ result.AppendErrorWithFormat("invalid address argument \"%s\": %s\n", load_addr_cstr,
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+
+ lldb_private::MemoryRegionInfo range_info;
+ error = process_sp->GetMemoryRegionInfo(load_addr, range_info);
+ if (error.Success())
+ {
+ lldb_private::Address addr;
+ ConstString section_name;
+ if (process_sp->GetTarget().ResolveLoadAddress(load_addr, addr))
+ {
+ SectionSP section_sp(addr.GetSection());
+ if (section_sp)
+ {
+ // Got the top most section, not the deepest section
+ while (section_sp->GetParent())
+ section_sp = section_sp->GetParent();
+ section_name = section_sp->GetName();
+ }
+ }
+ result.AppendMessageWithFormat(
+ "[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") %c%c%c%s%s\n", range_info.GetRange().GetRangeBase(),
+ range_info.GetRange().GetRangeEnd(), range_info.GetReadable() ? 'r' : '-',
+ range_info.GetWritable() ? 'w' : '-', range_info.GetExecutable() ? 'x' : '-',
+ section_name ? " " : "", section_name ? section_name.AsCString() : "");
+ m_prev_end_addr = range_info.GetRange().GetRangeEnd();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ result.SetStatus(eReturnStatusFailed);
+ result.AppendErrorWithFormat("%s\n", error.AsCString());
+ }
+ }
+ }
+ else
+ {
+ m_prev_end_addr = LLDB_INVALID_ADDRESS;
+ result.AppendError("invalid process");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
+
+ const char *
+ GetRepeatCommand(Args &current_command_args, uint32_t index) override
+ {
+ // If we repeat this command, repeat it without any arguments so we can
+ // show the next memory range
+ return m_cmd_name.c_str();
+ }
+
+ lldb::addr_t m_prev_end_addr;
+};
//-------------------------------------------------------------------------
// CommandObjectMemory
//-------------------------------------------------------------------------
-CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "memory",
- "A set of commands for operating on memory.",
- "memory <subcommand> [<subcommand-options>]")
+CommandObjectMemory::CommandObjectMemory(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "memory", "Commands for operating on memory in the current target process.",
+ "memory <subcommand> [<subcommand-options>]")
{
- LoadSubCommand ("find", CommandObjectSP (new CommandObjectMemoryFind (interpreter)));
- LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter)));
- LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter)));
- LoadSubCommand ("history", CommandObjectSP (new CommandObjectMemoryHistory (interpreter)));
+ LoadSubCommand("find", CommandObjectSP(new CommandObjectMemoryFind(interpreter)));
+ LoadSubCommand("read", CommandObjectSP(new CommandObjectMemoryRead(interpreter)));
+ LoadSubCommand("write", CommandObjectSP(new CommandObjectMemoryWrite(interpreter)));
+ LoadSubCommand("history", CommandObjectSP(new CommandObjectMemoryHistory(interpreter)));
+ LoadSubCommand("region", CommandObjectSP(new CommandObjectMemoryRegion(interpreter)));
}
-CommandObjectMemory::~CommandObjectMemory ()
-{
-}
+CommandObjectMemory::~CommandObjectMemory() = default;
diff --git a/source/Commands/CommandObjectMultiword.cpp b/source/Commands/CommandObjectMultiword.cpp
index 206f3b6fb7df..c951e0bbfa0d 100644
--- a/source/Commands/CommandObjectMultiword.cpp
+++ b/source/Commands/CommandObjectMultiword.cpp
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Interpreter/CommandObjectMultiword.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/Options.h"
@@ -24,22 +24,17 @@ using namespace lldb_private;
// CommandObjectMultiword
//-------------------------------------------------------------------------
-CommandObjectMultiword::CommandObjectMultiword
-(
- CommandInterpreter &interpreter,
- const char *name,
- const char *help,
- const char *syntax,
- uint32_t flags
-) :
+CommandObjectMultiword::CommandObjectMultiword(CommandInterpreter &interpreter,
+ const char *name,
+ const char *help,
+ const char *syntax,
+ uint32_t flags) :
CommandObject (interpreter, name, help, syntax, flags),
m_can_be_removed(false)
{
}
-CommandObjectMultiword::~CommandObjectMultiword ()
-{
-}
+CommandObjectMultiword::~CommandObjectMultiword() = default;
CommandObjectSP
CommandObjectMultiword::GetSubcommandSP (const char *sub_cmd, StringList *matches)
@@ -58,11 +53,10 @@ CommandObjectMultiword::GetSubcommandSP (const char *sub_cmd, StringList *matche
}
else
{
-
StringList local_matches;
- if (matches == NULL)
+ if (matches == nullptr)
matches = &local_matches;
- int num_matches = CommandObject::AddNamesMatchingPartialString (m_subcommand_dict, sub_cmd, *matches);
+ int num_matches = AddNamesMatchingPartialString (m_subcommand_dict, sub_cmd, *matches);
if (num_matches == 1)
{
@@ -86,12 +80,12 @@ CommandObjectMultiword::GetSubcommandObject (const char *sub_cmd, StringList *ma
}
bool
-CommandObjectMultiword::LoadSubCommand
-(
- const char *name,
- const CommandObjectSP& cmd_obj
-)
+CommandObjectMultiword::LoadSubCommand(const char *name,
+ const CommandObjectSP& cmd_obj)
{
+ if (cmd_obj)
+ assert((&GetCommandInterpreter() == &cmd_obj->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter");
+
CommandMap::iterator pos;
bool success = true;
@@ -129,7 +123,7 @@ CommandObjectMultiword::Execute(const char *args_string, CommandReturnObject &re
{
StringList matches;
CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches);
- if (sub_cmd_obj != NULL)
+ if (sub_cmd_obj != nullptr)
{
// Now call CommandObject::Execute to process and options in 'rest_of_line'. From there
// the command-specific version of Execute will be called, with the processed arguments.
@@ -184,10 +178,11 @@ CommandObjectMultiword::GenerateHelpText (Stream &output_stream)
// First time through here, generate the help text for the object and
// push it to the return result object as well
- output_stream.PutCString ("The following subcommands are supported:\n\n");
+ CommandObject::GenerateHelpText(output_stream);
+ output_stream.PutCString("\nThe following subcommands are supported:\n\n");
CommandMap::iterator pos;
- uint32_t max_len = m_interpreter.FindLongestCommandWord (m_subcommand_dict);
+ uint32_t max_len = FindLongestCommandWord (m_subcommand_dict);
if (max_len)
max_len += 4; // Indent the output by 4 spaces.
@@ -199,7 +194,7 @@ CommandObjectMultiword::GenerateHelpText (Stream &output_stream)
if (pos->second->WantsRawCommandString ())
{
std::string help_text (pos->second->GetHelp());
- help_text.append (" This command takes 'raw' input (no need to quote stuff).");
+ help_text.append(" Expects 'raw' input (see 'help raw-input'.)");
m_interpreter.OutputFormattedHelpText (output_stream,
indented_command.c_str(),
"--",
@@ -218,16 +213,13 @@ CommandObjectMultiword::GenerateHelpText (Stream &output_stream)
}
int
-CommandObjectMultiword::HandleCompletion
-(
- Args &input,
- int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches
-)
+CommandObjectMultiword::HandleCompletion(Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches)
{
// Any of the command matches will provide a complete word, otherwise the individual
// completers will override this.
@@ -236,18 +228,18 @@ CommandObjectMultiword::HandleCompletion
const char *arg0 = input.GetArgumentAtIndex(0);
if (cursor_index == 0)
{
- CommandObject::AddNamesMatchingPartialString (m_subcommand_dict,
- arg0,
- matches);
+ AddNamesMatchingPartialString (m_subcommand_dict,
+ arg0,
+ matches);
if (matches.GetSize() == 1
- && matches.GetStringAtIndex(0) != NULL
+ && matches.GetStringAtIndex(0) != nullptr
&& strcmp (arg0, matches.GetStringAtIndex(0)) == 0)
{
StringList temp_matches;
CommandObject *cmd_obj = GetSubcommandObject (arg0,
&temp_matches);
- if (cmd_obj != NULL)
+ if (cmd_obj != nullptr)
{
if (input.GetArgumentCount() == 1)
{
@@ -275,7 +267,7 @@ CommandObjectMultiword::HandleCompletion
{
CommandObject *sub_command_object = GetSubcommandObject (arg0,
&matches);
- if (sub_command_object == NULL)
+ if (sub_command_object == nullptr)
{
return matches.GetSize();
}
@@ -293,7 +285,6 @@ CommandObjectMultiword::HandleCompletion
word_complete,
matches);
}
-
}
}
@@ -302,14 +293,13 @@ CommandObjectMultiword::GetRepeatCommand (Args &current_command_args, uint32_t i
{
index++;
if (current_command_args.GetArgumentCount() <= index)
- return NULL;
+ return nullptr;
CommandObject *sub_command_object = GetSubcommandObject (current_command_args.GetArgumentAtIndex(index));
- if (sub_command_object == NULL)
- return NULL;
+ if (sub_command_object == nullptr)
+ return nullptr;
return sub_command_object->GetRepeatCommand(current_command_args, index);
}
-
void
CommandObjectMultiword::AproposAllSubCommands (const char *prefix,
const char *search_word,
@@ -340,8 +330,6 @@ CommandObjectMultiword::AproposAllSubCommands (const char *prefix,
}
}
-
-
CommandObjectProxy::CommandObjectProxy (CommandInterpreter &interpreter,
const char *name,
const char *help,
@@ -351,9 +339,7 @@ CommandObjectProxy::CommandObjectProxy (CommandInterpreter &interpreter,
{
}
-CommandObjectProxy::~CommandObjectProxy ()
-{
-}
+CommandObjectProxy::~CommandObjectProxy() = default;
const char *
CommandObjectProxy::GetHelpLong ()
@@ -361,7 +347,7 @@ CommandObjectProxy::GetHelpLong ()
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
return proxy_command->GetHelpLong();
- return NULL;
+ return nullptr;
}
bool
@@ -382,6 +368,15 @@ CommandObjectProxy::IsMultiwordObject ()
return false;
}
+CommandObjectMultiword*
+CommandObjectProxy::GetAsMultiwordCommand ()
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetAsMultiwordCommand();
+ return nullptr;
+}
+
void
CommandObjectProxy::GenerateHelpText (Stream &result)
{
@@ -405,7 +400,7 @@ CommandObjectProxy::GetSubcommandObject (const char *sub_cmd, StringList *matche
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
return proxy_command->GetSubcommandObject(sub_cmd, matches);
- return NULL;
+ return nullptr;
}
void
@@ -450,17 +445,15 @@ CommandObjectProxy::WantsCompletion()
return false;
}
-
Options *
CommandObjectProxy::GetOptions ()
{
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
return proxy_command->GetOptions ();
- return NULL;
+ return nullptr;
}
-
int
CommandObjectProxy::HandleCompletion (Args &input,
int &cursor_index,
@@ -482,6 +475,7 @@ CommandObjectProxy::HandleCompletion (Args &input,
matches.Clear();
return 0;
}
+
int
CommandObjectProxy::HandleArgumentCompletion (Args &input,
int &cursor_index,
@@ -513,7 +507,7 @@ CommandObjectProxy::GetRepeatCommand (Args &current_command_args,
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
return proxy_command->GetRepeatCommand (current_command_args, index);
- return NULL;
+ return nullptr;
}
bool
@@ -527,5 +521,3 @@ CommandObjectProxy::Execute (const char *args_string,
result.SetStatus (eReturnStatusFailed);
return false;
}
-
-
diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp
index aad8bea692e7..99bd63b6bdbb 100644
--- a/source/Commands/CommandObjectPlatform.cpp
+++ b/source/Commands/CommandObjectPlatform.cpp
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectPlatform.h"
-
// C Includes
// C++ Includes
+#include <mutex>
// Other libraries and framework includes
// Project includes
+#include "CommandObjectPlatform.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -64,19 +64,19 @@ ParsePermissionString(const char* permissions)
static OptionDefinition
g_permissions_options[] =
{
- { LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePermissionsNumber , "Give out the numeric value for permissions (e.g. 757)" },
- { LLDB_OPT_SET_ALL, false, "permissions-string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePermissionsString , "Give out the string value for permissions (e.g. rwxr-xr--)." },
- { LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow user to read." },
- { LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow user to write." },
- { LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow user to execute." },
-
- { LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow group to read." },
- { LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow group to write." },
- { LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow group to execute." },
-
- { LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow world to read." },
- { LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow world to write." },
- { LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow world to execute." },
+ { LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePermissionsNumber , "Give out the numeric value for permissions (e.g. 757)" },
+ { LLDB_OPT_SET_ALL, false, "permissions-string", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePermissionsString , "Give out the string value for permissions (e.g. rwxr-xr--)." },
+ { LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow user to read." },
+ { LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow user to write." },
+ { LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow user to execute." },
+
+ { LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow group to read." },
+ { LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow group to write." },
+ { LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow group to execute." },
+
+ { LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow world to read." },
+ { LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow world to write." },
+ { LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow world to execute." },
};
class OptionPermissions : public lldb_private::OptionGroup
@@ -85,11 +85,9 @@ public:
OptionPermissions ()
{
}
-
- ~OptionPermissions () override
- {
- }
-
+
+ ~OptionPermissions() override = default;
+
lldb_private::Error
SetOptionValue (CommandInterpreter &interpreter,
uint32_t option_idx,
@@ -117,6 +115,7 @@ public:
else
m_permissions = perms;
}
+ break;
case 'r':
m_permissions |= lldb::eFilePermissionsUserRead;
break;
@@ -144,7 +143,6 @@ public:
case 'e':
m_permissions |= lldb::eFilePermissionsWorldExecute;
break;
-
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -174,6 +172,7 @@ public:
// Instance variables to hold the values for command options.
uint32_t m_permissions;
+
private:
DISALLOW_COPY_AND_ASSIGN(OptionPermissions);
};
@@ -197,9 +196,7 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectPlatformSelect () override
- {
- }
+ ~CommandObjectPlatformSelect() override = default;
int
HandleCompletion (Args &input,
@@ -213,13 +210,13 @@ public:
std::string completion_str (input.GetArgumentAtIndex(cursor_index));
completion_str.erase (cursor_char_position);
- CommandCompletions::PlatformPluginNames (m_interpreter,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::PlatformPluginNames(m_interpreter,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -281,17 +278,15 @@ class CommandObjectPlatformList : public CommandObjectParsed
{
public:
CommandObjectPlatformList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform list",
- "List all platforms that are available.",
- NULL,
- 0)
+ CommandObjectParsed(interpreter,
+ "platform list",
+ "List all platforms that are available.",
+ nullptr,
+ 0)
{
}
- ~CommandObjectPlatformList () override
- {
- }
+ ~CommandObjectPlatformList() override = default;
protected:
bool
@@ -309,10 +304,10 @@ protected:
for (idx = 0; 1; ++idx)
{
const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (idx);
- if (plugin_name == NULL)
+ if (plugin_name == nullptr)
break;
const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (idx);
- if (plugin_desc == NULL)
+ if (plugin_desc == nullptr)
break;
ostrm.Printf("%s: %s\n", plugin_name, plugin_desc);
}
@@ -334,18 +329,12 @@ protected:
class CommandObjectPlatformStatus : public CommandObjectParsed
{
public:
- CommandObjectPlatformStatus (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform status",
- "Display status for the currently selected platform.",
- NULL,
- 0)
+ CommandObjectPlatformStatus(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform status", "Display status for the current platform.", nullptr, 0)
{
}
- ~CommandObjectPlatformStatus () override
- {
- }
+ ~CommandObjectPlatformStatus() override = default;
protected:
bool
@@ -383,18 +372,14 @@ protected:
class CommandObjectPlatformConnect : public CommandObjectParsed
{
public:
- CommandObjectPlatformConnect (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform connect",
- "Connect a platform by name to be the currently selected platform.",
- "platform connect <connect-url>",
- 0)
+ CommandObjectPlatformConnect(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform connect",
+ "Select the current platform by providing a connection URL.",
+ "platform connect <connect-url>", 0)
{
}
- ~CommandObjectPlatformConnect () override
- {
- }
+ ~CommandObjectPlatformConnect() override = default;
protected:
bool
@@ -436,16 +421,15 @@ protected:
GetOptions () override
{
PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- OptionGroupOptions* m_platform_options = NULL;
+ OptionGroupOptions* m_platform_options = nullptr;
if (platform_sp)
{
m_platform_options = platform_sp->GetConnectionOptions(m_interpreter);
- if (m_platform_options != NULL && !m_platform_options->m_did_finalize)
+ if (m_platform_options != nullptr && !m_platform_options->m_did_finalize)
m_platform_options->Finalize();
}
return m_platform_options;
}
-
};
//----------------------------------------------------------------------
@@ -454,18 +438,13 @@ protected:
class CommandObjectPlatformDisconnect : public CommandObjectParsed
{
public:
- CommandObjectPlatformDisconnect (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform disconnect",
- "Disconnect a platform by name to be the currently selected platform.",
- "platform disconnect",
- 0)
+ CommandObjectPlatformDisconnect(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform disconnect", "Disconnect from the current platform.",
+ "platform disconnect", 0)
{
}
- ~CommandObjectPlatformDisconnect () override
- {
- }
+ ~CommandObjectPlatformDisconnect() override = default;
protected:
bool
@@ -543,11 +522,9 @@ public:
{
m_options.Append (&m_option_working_dir, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
}
-
- ~CommandObjectPlatformSettings () override
- {
- }
-
+
+ ~CommandObjectPlatformSettings() override = default;
+
protected:
bool
DoExecute (Args& args, CommandReturnObject &result) override
@@ -569,18 +546,16 @@ protected:
Options *
GetOptions () override
{
- if (m_options.DidFinalize() == false)
+ if (!m_options.DidFinalize())
m_options.Finalize();
return &m_options;
}
+
protected:
-
OptionGroupOptions m_options;
OptionGroupFile m_option_working_dir;
-
};
-
//----------------------------------------------------------------------
// "platform mkdir"
//----------------------------------------------------------------------
@@ -588,19 +563,17 @@ class CommandObjectPlatformMkDir : public CommandObjectParsed
{
public:
CommandObjectPlatformMkDir (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform mkdir",
- "Make a new directory on the remote end.",
- NULL,
- 0),
- m_options(interpreter)
+ CommandObjectParsed(interpreter,
+ "platform mkdir",
+ "Make a new directory on the remote end.",
+ nullptr,
+ 0),
+ m_options(interpreter)
{
}
-
- ~CommandObjectPlatformMkDir () override
- {
- }
-
+
+ ~CommandObjectPlatformMkDir() override = default;
+
bool
DoExecute (Args& args, CommandReturnObject &result) override
{
@@ -637,15 +610,15 @@ public:
Options *
GetOptions () override
{
- if (m_options.DidFinalize() == false)
+ if (!m_options.DidFinalize())
{
m_options.Append(new OptionPermissions());
m_options.Finalize();
}
return &m_options;
}
+
OptionGroupOptions m_options;
-
};
//----------------------------------------------------------------------
@@ -655,19 +628,17 @@ class CommandObjectPlatformFOpen : public CommandObjectParsed
{
public:
CommandObjectPlatformFOpen (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform file open",
- "Open a file on the remote end.",
- NULL,
- 0),
- m_options(interpreter)
- {
- }
-
- ~CommandObjectPlatformFOpen () override
+ CommandObjectParsed(interpreter,
+ "platform file open",
+ "Open a file on the remote end.",
+ nullptr,
+ 0),
+ m_options(interpreter)
{
}
-
+
+ ~CommandObjectPlatformFOpen() override = default;
+
bool
DoExecute (Args& args, CommandReturnObject &result) override
{
@@ -706,16 +677,18 @@ public:
}
return result.Succeeded();
}
+
Options *
GetOptions () override
{
- if (m_options.DidFinalize() == false)
+ if (!m_options.DidFinalize())
{
m_options.Append(new OptionPermissions());
m_options.Finalize();
}
return &m_options;
}
+
OptionGroupOptions m_options;
};
@@ -726,18 +699,16 @@ class CommandObjectPlatformFClose : public CommandObjectParsed
{
public:
CommandObjectPlatformFClose (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform file close",
- "Close a file on the remote end.",
- NULL,
- 0)
+ CommandObjectParsed(interpreter,
+ "platform file close",
+ "Close a file on the remote end.",
+ nullptr,
+ 0)
{
}
-
- ~CommandObjectPlatformFClose () override
- {
- }
-
+
+ ~CommandObjectPlatformFClose() override = default;
+
bool
DoExecute (Args& args, CommandReturnObject &result) override
{
@@ -776,19 +747,17 @@ class CommandObjectPlatformFRead : public CommandObjectParsed
{
public:
CommandObjectPlatformFRead (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform file read",
- "Read data from a file on the remote end.",
- NULL,
- 0),
- m_options (interpreter)
- {
- }
-
- ~CommandObjectPlatformFRead () override
+ CommandObjectParsed(interpreter,
+ "platform file read",
+ "Read data from a file on the remote end.",
+ nullptr,
+ 0),
+ m_options (interpreter)
{
}
-
+
+ ~CommandObjectPlatformFRead() override = default;
+
bool
DoExecute (Args& args, CommandReturnObject &result) override
{
@@ -812,6 +781,7 @@ public:
}
return result.Succeeded();
}
+
Options *
GetOptions () override
{
@@ -822,16 +792,13 @@ protected:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
-
- ~CommandOptions () override
- {
- }
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -851,7 +818,6 @@ protected:
if (!success)
error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
break;
-
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -882,17 +848,18 @@ protected:
uint32_t m_offset;
uint32_t m_count;
};
+
CommandOptions m_options;
};
+
OptionDefinition
CommandObjectPlatformFRead::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "offset" , 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeIndex , "Offset into the file at which to start reading." },
- { LLDB_OPT_SET_1, false, "count" , 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount , "Number of bytes to read from the file." },
- { 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone , NULL }
+ { LLDB_OPT_SET_1, false, "offset" , 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex , "Offset into the file at which to start reading." },
+ { LLDB_OPT_SET_1, false, "count" , 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount , "Number of bytes to read from the file." },
+ { 0 , false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone , nullptr }
};
-
//----------------------------------------------------------------------
// "platform fwrite"
//----------------------------------------------------------------------
@@ -900,19 +867,17 @@ class CommandObjectPlatformFWrite : public CommandObjectParsed
{
public:
CommandObjectPlatformFWrite (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform file write",
- "Write data to a file on the remote end.",
- NULL,
- 0),
- m_options (interpreter)
- {
- }
-
- ~CommandObjectPlatformFWrite () override
+ CommandObjectParsed(interpreter,
+ "platform file write",
+ "Write data to a file on the remote end.",
+ nullptr,
+ 0),
+ m_options (interpreter)
{
}
-
+
+ ~CommandObjectPlatformFWrite() override = default;
+
bool
DoExecute (Args& args, CommandReturnObject &result) override
{
@@ -938,6 +903,7 @@ public:
}
return result.Succeeded();
}
+
Options *
GetOptions () override
{
@@ -948,16 +914,13 @@ protected:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
-
- ~CommandOptions () override
- {
- }
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -975,7 +938,6 @@ protected:
case 'd':
m_data.assign(option_arg);
break;
-
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -1006,14 +968,16 @@ protected:
uint32_t m_offset;
std::string m_data;
};
+
CommandOptions m_options;
};
+
OptionDefinition
CommandObjectPlatformFWrite::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "offset" , 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeIndex , "Offset into the file at which to start reading." },
- { LLDB_OPT_SET_1, false, "data" , 'd', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeValue , "Text to write to the file." },
- { 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone , NULL }
+ { LLDB_OPT_SET_1, false, "offset" , 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex , "Offset into the file at which to start reading." },
+ { LLDB_OPT_SET_1, false, "data" , 'd', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeValue , "Text to write to the file." },
+ { 0 , false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone , nullptr }
};
class CommandObjectPlatformFile : public CommandObjectMultiword
@@ -1022,22 +986,18 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- CommandObjectPlatformFile (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "platform file",
- "A set of commands to manage file access through a platform",
- "platform file [open|close|read|write] ...")
+ CommandObjectPlatformFile(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "platform file", "Commands to access files on the current platform.",
+ "platform file [open|close|read|write] ...")
{
LoadSubCommand ("open", CommandObjectSP (new CommandObjectPlatformFOpen (interpreter)));
LoadSubCommand ("close", CommandObjectSP (new CommandObjectPlatformFClose (interpreter)));
LoadSubCommand ("read", CommandObjectSP (new CommandObjectPlatformFRead (interpreter)));
LoadSubCommand ("write", CommandObjectSP (new CommandObjectPlatformFWrite (interpreter)));
}
-
- ~CommandObjectPlatformFile () override
- {
- }
-
+
+ ~CommandObjectPlatformFile() override = default;
+
private:
//------------------------------------------------------------------
// For CommandObjectPlatform only
@@ -1085,11 +1045,9 @@ R"(Examples:
m_arguments.push_back (arg1);
m_arguments.push_back (arg2);
}
-
- ~CommandObjectPlatformGetFile () override
- {
- }
-
+
+ ~CommandObjectPlatformGetFile() override = default;
+
bool
DoExecute (Args& args, CommandReturnObject &result) override
{
@@ -1162,11 +1120,9 @@ R"(Examples:
// Push the data for the first argument into the m_arguments vector.
m_arguments.push_back (arg1);
}
-
- ~CommandObjectPlatformGetSize () override
- {
- }
-
+
+ ~CommandObjectPlatformGetSize() override = default;
+
bool
DoExecute (Args& args, CommandReturnObject &result) override
{
@@ -1210,18 +1166,16 @@ class CommandObjectPlatformPutFile : public CommandObjectParsed
{
public:
CommandObjectPlatformPutFile (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform put-file",
- "Transfer a file from this system to the remote end.",
- NULL,
- 0)
+ CommandObjectParsed(interpreter,
+ "platform put-file",
+ "Transfer a file from this system to the remote end.",
+ nullptr,
+ 0)
{
}
-
- ~CommandObjectPlatformPutFile () override
- {
- }
-
+
+ ~CommandObjectPlatformPutFile() override = default;
+
bool
DoExecute (Args& args, CommandReturnObject &result) override
{
@@ -1269,11 +1223,9 @@ public:
m_options (interpreter)
{
}
-
- ~CommandObjectPlatformProcessLaunch () override
- {
- }
-
+
+ ~CommandObjectPlatformProcessLaunch() override = default;
+
Options *
GetOptions () override
{
@@ -1368,8 +1320,6 @@ protected:
ProcessLaunchCommandOptions m_options;
};
-
-
//----------------------------------------------------------------------
// "platform process list"
//----------------------------------------------------------------------
@@ -1385,11 +1335,9 @@ public:
m_options (interpreter)
{
}
-
- ~CommandObjectPlatformProcessList () override
- {
- }
-
+
+ ~CommandObjectPlatformProcessList() override = default;
+
Options *
GetOptions () override
{
@@ -1416,7 +1364,6 @@ protected:
Error error;
if (args.GetArgumentCount() == 0)
{
-
if (platform_sp)
{
Stream &ostrm = result.GetOutputStream();
@@ -1441,7 +1388,7 @@ protected:
{
ProcessInstanceInfoList proc_infos;
const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
- const char *match_desc = NULL;
+ const char *match_desc = nullptr;
const char *match_name = m_options.match_info.GetProcessInfo().GetName();
if (match_name && match_name[0])
{
@@ -1504,17 +1451,34 @@ protected:
class CommandOptions : public Options
{
public:
-
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- match_info ()
- {
- }
-
- ~CommandOptions () override
- {
+ CommandOptions(CommandInterpreter &interpreter) :
+ Options(interpreter),
+ match_info(),
+ show_args(false),
+ verbose(false)
+ {
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ PosixPlatformCommandOptionValidator *posix_validator = new PosixPlatformCommandOptionValidator();
+ for (size_t i=0; g_option_table[i].short_option != 0; ++i)
+ {
+ switch (g_option_table[i].short_option)
+ {
+ case 'u':
+ case 'U':
+ case 'g':
+ case 'G':
+ g_option_table[i].validator = posix_validator;
+ break;
+ default:
+ break;
+ }
+ }
+ });
}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -1622,39 +1586,35 @@ protected:
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table[];
-
+
// Instance variables to hold the values for command options.
ProcessInstanceInfoMatch match_info;
bool show_args;
bool verbose;
};
+
CommandOptions m_options;
};
-namespace
-{
- PosixPlatformCommandOptionValidator g_posix_validator;
-}
-
OptionDefinition
CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_1 , false, "pid" , 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePid , "List the process info for a specific process ID." },
-{ LLDB_OPT_SET_2 , true , "name" , 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." },
-{ LLDB_OPT_SET_3 , true , "ends-with" , 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that end with a string." },
-{ LLDB_OPT_SET_4 , true , "starts-with", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that start with a string." },
-{ LLDB_OPT_SET_5 , true , "contains" , 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that contain a string." },
-{ LLDB_OPT_SET_6 , true , "regex" , 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "parent" , 'P', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "uid" , 'u', OptionParser::eRequiredArgument, &g_posix_validator, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching user ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "euid" , 'U', OptionParser::eRequiredArgument, &g_posix_validator, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective user ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "gid" , 'g', OptionParser::eRequiredArgument, &g_posix_validator, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching group ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "egid" , 'G', OptionParser::eRequiredArgument, &g_posix_validator, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective group ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "arch" , 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
-{ LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args" , 'A', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
-{ LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose" , 'v', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone , "Enable verbose output." },
-{ 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone , NULL }
+{ LLDB_OPT_SET_1 , false, "pid" , 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid , "List the process info for a specific process ID." },
+{ LLDB_OPT_SET_2 , true , "name" , 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." },
+{ LLDB_OPT_SET_3 , true , "ends-with" , 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName , "Find processes with executable basenames that end with a string." },
+{ LLDB_OPT_SET_4 , true , "starts-with", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName , "Find processes with executable basenames that start with a string." },
+{ LLDB_OPT_SET_5 , true , "contains" , 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName , "Find processes with executable basenames that contain a string." },
+{ LLDB_OPT_SET_6 , true , "regex" , 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." },
+{ LLDB_OPT_SET_FROM_TO(2, 6), false, "parent" , 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
+{ LLDB_OPT_SET_FROM_TO(2, 6), false, "uid" , 'u', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger , "Find processes that have a matching user ID." },
+{ LLDB_OPT_SET_FROM_TO(2, 6), false, "euid" , 'U', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective user ID." },
+{ LLDB_OPT_SET_FROM_TO(2, 6), false, "gid" , 'g', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger , "Find processes that have a matching group ID." },
+{ LLDB_OPT_SET_FROM_TO(2, 6), false, "egid" , 'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective group ID." },
+{ LLDB_OPT_SET_FROM_TO(2, 6), false, "arch" , 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
+{ LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args" , 'A', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
+{ LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose" , 'v', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone , "Enable verbose output." },
+{ 0 , false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone , nullptr }
};
//----------------------------------------------------------------------
@@ -1683,11 +1643,9 @@ public:
// Push the data for the first argument into the m_arguments vector.
m_arguments.push_back (arg);
}
-
- ~CommandObjectPlatformProcessInfo () override
- {
- }
-
+
+ ~CommandObjectPlatformProcessInfo() override = default;
+
protected:
bool
DoExecute (Args& args, CommandReturnObject &result) override
@@ -1766,22 +1724,18 @@ protected:
class CommandObjectPlatformProcessAttach : public CommandObjectParsed
{
public:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options(interpreter)
{
// Keep default values of all options in one place: OptionParsingStarting ()
OptionParsingStarting ();
}
-
- ~CommandOptions () override
- {
- }
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -1859,7 +1813,7 @@ public:
// Look to see if there is a -P argument provided, and if so use that plugin, otherwise
// use the default plugin.
- const char *partial_name = NULL;
+ const char *partial_name = nullptr;
partial_name = input.GetArgumentAtIndex(opt_arg_pos);
PlatformSP platform_sp (m_interpreter.GetPlatform (true));
@@ -1905,11 +1859,9 @@ public:
m_options (interpreter)
{
}
-
- ~CommandObjectPlatformProcessAttach () override
- {
- }
-
+
+ ~CommandObjectPlatformProcessAttach() override = default;
+
bool
DoExecute (Args& command,
CommandReturnObject &result) override
@@ -1919,13 +1871,13 @@ public:
{
Error err;
ProcessSP remote_process_sp =
- platform_sp->Attach(m_options.attach_info, m_interpreter.GetDebugger(), NULL, err);
+ platform_sp->Attach(m_options.attach_info, m_interpreter.GetDebugger(), nullptr, err);
if (err.Fail())
{
result.AppendError(err.AsCString());
result.SetStatus (eReturnStatusFailed);
}
- else if (remote_process_sp.get() == NULL)
+ else if (!remote_process_sp)
{
result.AppendError("could not attach: unknown reason");
result.SetStatus (eReturnStatusFailed);
@@ -1948,45 +1900,38 @@ public:
}
protected:
-
CommandOptions m_options;
};
-
OptionDefinition
CommandObjectPlatformProcessAttach::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "plugin", 'P' , OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
- { LLDB_OPT_SET_1, false, "pid", 'p' , OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."},
- { LLDB_OPT_SET_2, false, "name", 'n' , OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."},
- { LLDB_OPT_SET_2, false, "waitfor", 'w' , OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."},
- { 0, false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "plugin", 'P' , OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
+ { LLDB_OPT_SET_1, false, "pid", 'p' , OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "The process ID of an existing process to attach to."},
+ { LLDB_OPT_SET_2, false, "name", 'n' , OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "The name of the process to attach to."},
+ { LLDB_OPT_SET_2, false, "waitfor", 'w' , OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."},
+ { 0, false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
class CommandObjectPlatformProcess : public CommandObjectMultiword
{
public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- CommandObjectPlatformProcess (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "platform process",
- "A set of commands to query, launch and attach to platform processes",
- "platform process [attach|launch|list] ...")
+ CommandObjectPlatformProcess(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "platform process",
+ "Commands to query, launch and attach to processes on the current platform.",
+ "platform process [attach|launch|list] ...")
{
LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
LoadSubCommand ("info" , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter)));
LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
-
- }
-
- ~CommandObjectPlatformProcess () override
- {
}
-
+
+ ~CommandObjectPlatformProcess() override = default;
+
private:
//------------------------------------------------------------------
// For CommandObjectPlatform only
@@ -2000,21 +1945,17 @@ private:
class CommandObjectPlatformShell : public CommandObjectRaw
{
public:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options(interpreter),
timeout(10)
{
}
-
- ~CommandOptions () override
- {
- }
-
+
+ ~CommandOptions() override = default;
+
virtual uint32_t
GetNumDefinitions ()
{
@@ -2063,21 +2004,16 @@ public:
static OptionDefinition g_option_table[];
uint32_t timeout;
};
-
- CommandObjectPlatformShell (CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "platform shell",
- "Run a shell command on the selected platform.",
- "platform shell <shell-command>",
- 0),
- m_options(interpreter)
- {
- }
-
- ~CommandObjectPlatformShell () override
+
+ CommandObjectPlatformShell(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "platform shell", "Run a shell command on the current platform.",
+ "platform shell <shell-command>", 0),
+ m_options(interpreter)
{
}
-
+
+ ~CommandObjectPlatformShell() override = default;
+
Options *
GetOptions () override
{
@@ -2089,7 +2025,7 @@ public:
{
m_options.NotifyOptionParsingStarting();
- const char* expr = NULL;
+ const char* expr = nullptr;
// Print out an usage syntax on an empty command line.
if (raw_command_line[0] == '\0')
@@ -2101,7 +2037,7 @@ public:
if (raw_command_line[0] == '-')
{
// We have some options and these options MUST end with --.
- const char *end_options = NULL;
+ const char *end_options = nullptr;
const char *s = raw_command_line;
while (s && s[0])
{
@@ -2128,7 +2064,7 @@ public:
}
}
- if (expr == NULL)
+ if (expr == nullptr)
expr = raw_command_line;
PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
@@ -2173,17 +2109,17 @@ public:
}
return true;
}
+
CommandOptions m_options;
};
OptionDefinition
CommandObjectPlatformShell::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "timeout", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeValue, "Seconds to wait for the remote host to finish running the command."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeValue, "Seconds to wait for the remote host to finish running the command."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
//----------------------------------------------------------------------
// "platform install" - install a target to a remote end
//----------------------------------------------------------------------
@@ -2198,11 +2134,9 @@ public:
0)
{
}
-
- ~CommandObjectPlatformInstall () override
- {
- }
-
+
+ ~CommandObjectPlatformInstall() override = default;
+
bool
DoExecute (Args& args, CommandReturnObject &result) override
{
@@ -2215,7 +2149,7 @@ public:
// TODO: move the bulk of this code over to the platform itself
FileSpec src(args.GetArgumentAtIndex(0), true);
FileSpec dst(args.GetArgumentAtIndex(1), false);
- if (src.Exists() == false)
+ if (!src.Exists())
{
result.AppendError("source location does not exist or is not accessible");
result.SetStatus(eReturnStatusFailed);
@@ -2241,18 +2175,11 @@ public:
}
return result.Succeeded();
}
-private:
-
};
-//----------------------------------------------------------------------
-// CommandObjectPlatform constructor
-//----------------------------------------------------------------------
-CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "platform",
- "A set of commands to manage and create platforms.",
- "platform [connect|disconnect|info|list|status|select] ...")
+CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "platform", "Commands to manage and create platforms.",
+ "platform [connect|disconnect|info|list|status|select] ...")
{
LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
@@ -2270,9 +2197,4 @@ CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
LoadSubCommand ("target-install", CommandObjectSP (new CommandObjectPlatformInstall (interpreter)));
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-CommandObjectPlatform::~CommandObjectPlatform()
-{
-}
+CommandObjectPlatform::~CommandObjectPlatform() = default;
diff --git a/source/Commands/CommandObjectPlugin.cpp b/source/Commands/CommandObjectPlugin.cpp
index 4c5a089dbcec..221c9a67d848 100644
--- a/source/Commands/CommandObjectPlugin.cpp
+++ b/source/Commands/CommandObjectPlugin.cpp
@@ -1,4 +1,4 @@
-//===-- CommandObjectPlugin.cpp ----------------------------------*- C++ -*-===//
+//===-- CommandObjectPlugin.cpp ---------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,10 +7,12 @@
//
//===----------------------------------------------------------------------===//
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
#include "CommandObjectPlugin.h"
-
#include "lldb/Host/Host.h"
-
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -19,13 +21,12 @@ using namespace lldb_private;
class CommandObjectPluginLoad : public CommandObjectParsed
{
-private:
public:
CommandObjectPluginLoad (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "plugin load",
- "Import a dylib that implements an LLDB plugin.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "plugin load",
+ "Import a dylib that implements an LLDB plugin.",
+ nullptr)
{
CommandArgumentEntry arg1;
CommandArgumentData cmd_arg;
@@ -40,11 +41,9 @@ public:
// Push the data for the first argument into the m_arguments vector.
m_arguments.push_back (arg1);
}
-
- ~CommandObjectPluginLoad () override
- {
- }
-
+
+ ~CommandObjectPluginLoad() override = default;
+
int
HandleArgumentCompletion (Args &input,
int &cursor_index,
@@ -58,14 +57,14 @@ public:
std::string completion_str (input.GetArgumentAtIndex(cursor_index));
completion_str.erase (cursor_char_position);
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eDiskFileCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -100,15 +99,11 @@ protected:
}
};
-CommandObjectPlugin::CommandObjectPlugin (CommandInterpreter &interpreter) :
-CommandObjectMultiword (interpreter,
- "plugin",
- "A set of commands for managing or customizing plugin commands.",
- "plugin <subcommand> [<subcommand-options>]")
+CommandObjectPlugin::CommandObjectPlugin(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "plugin", "Commands for managing LLDB plugins.",
+ "plugin <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("load", CommandObjectSP (new CommandObjectPluginLoad (interpreter)));
}
-CommandObjectPlugin::~CommandObjectPlugin ()
-{
-}
+CommandObjectPlugin::~CommandObjectPlugin() = default;
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index a85ea179abb8..106e2d86b18c 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -7,12 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectProcess.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "CommandObjectProcess.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
@@ -46,8 +45,9 @@ public:
const char *new_process_action) :
CommandObjectParsed (interpreter, name, help, syntax, flags),
m_new_process_action (new_process_action) {}
-
- ~CommandObjectProcessLaunchOrAttach () override {}
+
+ ~CommandObjectProcessLaunchOrAttach() override = default;
+
protected:
bool
StopProcessIfNecessary (Process *process, StateType &state, CommandReturnObject &result)
@@ -81,7 +81,7 @@ protected:
if (detach_error.Success())
{
result.SetStatus (eReturnStatusSuccessFinishResult);
- process = NULL;
+ process = nullptr;
}
else
{
@@ -95,7 +95,7 @@ protected:
if (destroy_error.Success())
{
result.SetStatus (eReturnStatusSuccessFinishResult);
- process = NULL;
+ process = nullptr;
}
else
{
@@ -108,8 +108,10 @@ protected:
}
return result.Succeeded();
}
+
std::string m_new_process_action;
};
+
//-------------------------------------------------------------------------
// CommandObjectProcessLaunch
//-------------------------------------------------------------------------
@@ -117,14 +119,13 @@ protected:
class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach
{
public:
-
CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
- CommandObjectProcessLaunchOrAttach (interpreter,
- "process launch",
- "Launch the executable in the debugger.",
- NULL,
- eCommandRequiresTarget,
- "restart"),
+ CommandObjectProcessLaunchOrAttach(interpreter,
+ "process launch",
+ "Launch the executable in the debugger.",
+ nullptr,
+ eCommandRequiresTarget,
+ "restart"),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -141,10 +142,7 @@ public:
m_arguments.push_back (arg);
}
-
- ~CommandObjectProcessLaunch () override
- {
- }
+ ~CommandObjectProcessLaunch() override = default;
int
HandleArgumentCompletion (Args &input,
@@ -159,14 +157,14 @@ public:
std::string completion_str (input.GetArgumentAtIndex(cursor_index));
completion_str.erase (cursor_char_position);
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eDiskFileCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -189,10 +187,10 @@ protected:
{
Debugger &debugger = m_interpreter.GetDebugger();
Target *target = debugger.GetSelectedTarget().get();
- // If our listener is NULL, users aren't allows to launch
+ // If our listener is nullptr, users aren't allows to launch
ModuleSP exe_module_sp = target->GetExecutableModule();
- if (exe_module_sp == NULL)
+ if (exe_module_sp == nullptr)
{
result.AppendError ("no file in target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -305,15 +303,15 @@ protected:
//OptionDefinition
//CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
//{
-//{ SET1 | SET2 | SET3, false, "stop-at-entry", 's', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."},
-//{ SET1 , false, "stdin", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName, "Redirect stdin for the process to <path>."},
-//{ SET1 , false, "stdout", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName, "Redirect stdout for the process to <path>."},
-//{ SET1 , false, "stderr", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName, "Redirect stderr for the process to <path>."},
-//{ SET1 | SET2 | SET3, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
-//{ SET2 , false, "tty", 't', OptionParser::eOptionalArgument, NULL, 0, eArgTypeDirectoryName, "Start the process in a terminal. If <path> is specified, look for a terminal whose name contains <path>, else start the process in a new terminal."},
-//{ SET3, false, "no-stdio", 'n', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."},
-//{ SET1 | SET2 | SET3, false, "working-dir", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."},
-//{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+//{ SET1 | SET2 | SET3, false, "stop-at-entry", 's', OptionParser::eNoArgument, nullptr, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."},
+//{ SET1 , false, "stdin", 'i', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Redirect stdin for the process to <path>."},
+//{ SET1 , false, "stdout", 'o', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Redirect stdout for the process to <path>."},
+//{ SET1 , false, "stderr", 'e', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Redirect stderr for the process to <path>."},
+//{ SET1 | SET2 | SET3, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
+//{ SET2 , false, "tty", 't', OptionParser::eOptionalArgument, nullptr, 0, eArgTypeDirectoryName, "Start the process in a terminal. If <path> is specified, look for a terminal whose name contains <path>, else start the process in a new terminal."},
+//{ SET3, false, "no-stdio", 'n', OptionParser::eNoArgument, nullptr, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."},
+//{ SET1 | SET2 | SET3, false, "working-dir", 'w', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."},
+//{ 0, false, nullptr, 0, 0, nullptr, 0, eArgTypeNone, nullptr }
//};
//
//#undef SET1
@@ -327,11 +325,9 @@ protected:
class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach
{
public:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options(interpreter)
{
@@ -339,9 +335,7 @@ public:
OptionParsingStarting ();
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -428,7 +422,7 @@ public:
// Look to see if there is a -P argument provided, and if so use that plugin, otherwise
// use the default plugin.
- const char *partial_name = NULL;
+ const char *partial_name = nullptr;
partial_name = input.GetArgumentAtIndex(opt_arg_pos);
PlatformSP platform_sp (m_interpreter.GetPlatform (true));
@@ -445,7 +439,7 @@ public:
const size_t num_matches = process_infos.GetSize();
if (num_matches > 0)
{
- for (size_t i=0; i<num_matches; ++i)
+ for (size_t i = 0; i < num_matches; ++i)
{
matches.AppendString (process_infos.GetProcessNameAtIndex(i),
process_infos.GetProcessNameLengthAtIndex(i));
@@ -477,9 +471,7 @@ public:
{
}
- ~CommandObjectProcessAttach () override
- {
- }
+ ~CommandObjectProcessAttach() override = default;
Options *
GetOptions () override
@@ -504,20 +496,20 @@ protected:
if (!StopProcessIfNecessary (process, state, result))
return false;
- if (target == NULL)
+ if (target == nullptr)
{
// If there isn't a current target create one.
TargetSP new_target_sp;
Error error;
- error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
- NULL,
- NULL,
- false,
- NULL, // No platform options
- new_target_sp);
+ error = m_interpreter.GetDebugger().GetTargetList().CreateTarget(m_interpreter.GetDebugger(),
+ nullptr,
+ nullptr,
+ false,
+ nullptr, // No platform options
+ new_target_sp);
target = new_target_sp.get();
- if (target == NULL || error.Fail())
+ if (target == nullptr || error.Fail())
{
result.AppendError(error.AsCString("Error creating target"));
return false;
@@ -611,17 +603,16 @@ protected:
CommandOptions m_options;
};
-
OptionDefinition
CommandObjectProcessAttach::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Immediately continue the process once attached."},
-{ LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
-{ LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."},
-{ LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."},
-{ LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Include existing processes when doing attach -w."},
-{ LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."},
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Immediately continue the process once attached."},
+{ LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
+{ LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "The process ID of an existing process to attach to."},
+{ LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "The name of the process to attach to."},
+{ LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Include existing processes when doing attach -w."},
+{ LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."},
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -632,7 +623,6 @@ CommandObjectProcessAttach::CommandOptions::g_option_table[] =
class CommandObjectProcessContinue : public CommandObjectParsed
{
public:
-
CommandObjectProcessContinue (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"process continue",
@@ -646,17 +636,12 @@ public:
{
}
-
- ~CommandObjectProcessContinue () override
- {
- }
+ ~CommandObjectProcessContinue() override = default;
protected:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options(interpreter)
{
@@ -664,9 +649,7 @@ protected:
OptionParsingStarting ();
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -725,7 +708,7 @@ protected:
if (m_options.m_ignore > 0)
{
- ThreadSP sel_thread_sp(process->GetThreadList().GetSelectedThread());
+ ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
if (sel_thread_sp)
{
StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
@@ -750,7 +733,7 @@ protected:
}
{ // Scope for thread list mutex:
- Mutex::Locker locker (process->GetThreadList().GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex());
const uint32_t num_threads = process->GetThreadList().GetSize();
// Set the actions that the threads should each take when resuming
@@ -814,15 +797,14 @@ protected:
}
CommandOptions m_options;
-
};
OptionDefinition
CommandObjectProcessContinue::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger,
+{ LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger,
"Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -836,16 +818,13 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
OptionParsingStarting ();
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -896,21 +875,15 @@ public:
LazyBool m_keep_stopped;
};
- CommandObjectProcessDetach (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process detach",
- "Detach from the current process being debugged.",
- "process detach",
- eCommandRequiresProcess |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched),
- m_options(interpreter)
+ CommandObjectProcessDetach(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process detach", "Detach from the current target process.",
+ "process detach",
+ eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched),
+ m_options(interpreter)
{
}
- ~CommandObjectProcessDetach () override
- {
- }
+ ~CommandObjectProcessDetach() override = default;
Options *
GetOptions () override
@@ -918,7 +891,6 @@ public:
return &m_options;
}
-
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -929,10 +901,7 @@ protected:
if (m_options.m_keep_stopped == eLazyBoolCalculate)
{
// Check the process default:
- if (process->GetDetachKeepsStopped())
- keep_stopped = true;
- else
- keep_stopped = false;
+ keep_stopped = process->GetDetachKeepsStopped();
}
else if (m_options.m_keep_stopped == eLazyBoolYes)
keep_stopped = true;
@@ -959,8 +928,8 @@ protected:
OptionDefinition
CommandObjectProcessDetach::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." },
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." },
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -971,22 +940,18 @@ CommandObjectProcessDetach::CommandOptions::g_option_table[] =
class CommandObjectProcessConnect : public CommandObjectParsed
{
public:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options(interpreter)
{
// Keep default values of all options in one place: OptionParsingStarting ()
OptionParsingStarting ();
}
-
- ~CommandOptions () override
- {
- }
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -1036,12 +1001,9 @@ public:
m_options (interpreter)
{
}
-
- ~CommandObjectProcessConnect () override
- {
- }
-
+ ~CommandObjectProcessConnect() override = default;
+
Options *
GetOptions () override
{
@@ -1061,7 +1023,6 @@ protected:
return false;
}
-
Process *process = m_exe_ctx.GetProcessPtr();
if (process && process->IsAlive())
{
@@ -1098,8 +1059,8 @@ protected:
OptionDefinition
CommandObjectProcessConnect::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
- { 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
+ { 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -1110,31 +1071,24 @@ CommandObjectProcessConnect::CommandOptions::g_option_table[] =
class CommandObjectProcessPlugin : public CommandObjectProxy
{
public:
-
- CommandObjectProcessPlugin (CommandInterpreter &interpreter) :
- CommandObjectProxy (interpreter,
- "process plugin",
- "Send a custom command to the current process plug-in.",
- "process plugin <args>",
- 0)
- {
- }
-
- ~CommandObjectProcessPlugin () override
+ CommandObjectProcessPlugin(CommandInterpreter &interpreter)
+ : CommandObjectProxy(interpreter, "process plugin",
+ "Send a custom command to the current target process plug-in.", "process plugin <args>", 0)
{
}
+ ~CommandObjectProcessPlugin() override = default;
+
CommandObject *
GetProxyCommandObject() override
{
Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
if (process)
return process->GetPluginCommandObject();
- return NULL;
+ return nullptr;
}
};
-
//-------------------------------------------------------------------------
// CommandObjectProcessLoad
//-------------------------------------------------------------------------
@@ -1153,7 +1107,7 @@ public:
OptionParsingStarting ();
}
- ~CommandOptions () override = default;
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -1208,7 +1162,7 @@ public:
{
}
- ~CommandObjectProcessLoad () override = default;
+ ~CommandObjectProcessLoad() override = default;
Options *
GetOptions () override
@@ -1223,7 +1177,7 @@ protected:
Process *process = m_exe_ctx.GetProcessPtr();
const size_t argc = command.GetArgumentCount();
- for (uint32_t i=0; i<argc; ++i)
+ for (uint32_t i = 0; i < argc; ++i)
{
Error error;
PlatformSP platform = process->GetTarget().GetPlatform();
@@ -1293,9 +1247,7 @@ public:
{
}
- ~CommandObjectProcessUnload () override
- {
- }
+ ~CommandObjectProcessUnload() override = default;
protected:
bool
@@ -1305,7 +1257,7 @@ protected:
const size_t argc = command.GetArgumentCount();
- for (uint32_t i=0; i<argc; ++i)
+ for (uint32_t i = 0; i < argc; ++i)
{
const char *image_token_cstr = command.GetArgumentAtIndex(i);
uint32_t image_token = StringConvert::ToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
@@ -1343,13 +1295,9 @@ protected:
class CommandObjectProcessSignal : public CommandObjectParsed
{
public:
-
- CommandObjectProcessSignal (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process signal",
- "Send a UNIX signal to the current process being debugged.",
- NULL,
- eCommandRequiresProcess | eCommandTryTargetAPILock)
+ CommandObjectProcessSignal(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process signal", "Send a UNIX signal to the current target process.",
+ nullptr, eCommandRequiresProcess | eCommandTryTargetAPILock)
{
CommandArgumentEntry arg;
CommandArgumentData signal_arg;
@@ -1365,9 +1313,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectProcessSignal () override
- {
- }
+ ~CommandObjectProcessSignal() override = default;
protected:
bool
@@ -1414,7 +1360,6 @@ protected:
}
};
-
//-------------------------------------------------------------------------
// CommandObjectProcessInterrupt
//-------------------------------------------------------------------------
@@ -1423,29 +1368,21 @@ protected:
class CommandObjectProcessInterrupt : public CommandObjectParsed
{
public:
-
-
- CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process interrupt",
- "Interrupt the current process being debugged.",
- "process interrupt",
- eCommandRequiresProcess |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched)
+ CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process interrupt", "Interrupt the current target process.",
+ "process interrupt",
+ eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched)
{
}
- ~CommandObjectProcessInterrupt () override
- {
- }
+ ~CommandObjectProcessInterrupt() override = default;
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
Process *process = m_exe_ctx.GetProcessPtr();
- if (process == NULL)
+ if (process == nullptr)
{
result.AppendError ("no process to halt");
result.SetStatus (eReturnStatusFailed);
@@ -1485,28 +1422,20 @@ protected:
class CommandObjectProcessKill : public CommandObjectParsed
{
public:
-
- CommandObjectProcessKill (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process kill",
- "Terminate the current process being debugged.",
- "process kill",
- eCommandRequiresProcess |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched)
+ CommandObjectProcessKill(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process kill", "Terminate the current target process.", "process kill",
+ eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched)
{
}
- ~CommandObjectProcessKill () override
- {
- }
+ ~CommandObjectProcessKill() override = default;
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
Process *process = m_exe_ctx.GetProcessPtr();
- if (process == NULL)
+ if (process == nullptr)
{
result.AppendError ("no process to kill");
result.SetStatus (eReturnStatusFailed);
@@ -1545,7 +1474,6 @@ protected:
class CommandObjectProcessSaveCore : public CommandObjectParsed
{
public:
-
CommandObjectProcessSaveCore (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"process save-core",
@@ -1556,11 +1484,9 @@ public:
eCommandProcessMustBeLaunched)
{
}
-
- ~CommandObjectProcessSaveCore () override
- {
- }
-
+
+ ~CommandObjectProcessSaveCore() override = default;
+
protected:
bool
DoExecute (Args& command,
@@ -1610,19 +1536,14 @@ protected:
class CommandObjectProcessStatus : public CommandObjectParsed
{
public:
- CommandObjectProcessStatus (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process status",
- "Show the current status and location of executing process.",
- "process status",
- eCommandRequiresProcess | eCommandTryTargetAPILock)
- {
- }
-
- ~CommandObjectProcessStatus() override
+ CommandObjectProcessStatus(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process status",
+ "Show status and stop location for the current target process.", "process status",
+ eCommandRequiresProcess | eCommandTryTargetAPILock)
{
}
+ ~CommandObjectProcessStatus() override = default;
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -1653,20 +1574,16 @@ public:
class CommandObjectProcessHandle : public CommandObjectParsed
{
public:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
OptionParsingStarting ();
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -1717,13 +1634,12 @@ public:
std::string pass;
};
-
- CommandObjectProcessHandle (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process handle",
- "Show or update what the process and debugger should do with various signals received from the OS.",
- NULL),
- m_options (interpreter)
+ CommandObjectProcessHandle(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "process handle",
+ "Manage LLDB handling of OS signals for the current target process. Defaults to showing current policy.",
+ nullptr),
+ m_options(interpreter)
{
SetHelpLong ("\nIf no signals are specified, update them all. If no update "
"option is specified, list the current values.");
@@ -1738,9 +1654,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectProcessHandle () override
- {
- }
+ ~CommandObjectProcessHandle() override = default;
Options *
GetOptions () override
@@ -1752,7 +1666,6 @@ public:
VerifyCommandOptionValue (const std::string &option, int &real_value)
{
bool okay = true;
-
bool success = false;
bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
@@ -1945,21 +1858,19 @@ protected:
OptionDefinition
CommandObjectProcessHandle::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
-{ LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
-{ LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
+{ LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
+{ LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
// CommandObjectMultiwordProcess
//-------------------------------------------------------------------------
-CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "process",
- "A set of commands for operating on a process.",
- "process <subcommand> [<subcommand-options>]")
+CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "process", "Commands for interacting with processes on the current platform.",
+ "process <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter)));
LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
@@ -1977,7 +1888,4 @@ CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter
LoadSubCommand ("save-core", CommandObjectSP (new CommandObjectProcessSaveCore (interpreter)));
}
-CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
-{
-}
-
+CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;
diff --git a/source/Commands/CommandObjectQuit.cpp b/source/Commands/CommandObjectQuit.cpp
index 31f82b987c1c..a650398724fe 100644
--- a/source/Commands/CommandObjectQuit.cpp
+++ b/source/Commands/CommandObjectQuit.cpp
@@ -24,8 +24,8 @@ using namespace lldb_private;
// CommandObjectQuit
//-------------------------------------------------------------------------
-CommandObjectQuit::CommandObjectQuit (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter, "quit", "Quit out of the LLDB debugger.", "quit")
+CommandObjectQuit::CommandObjectQuit(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "quit", "Quit the LLDB debugger.", "quit")
{
}
diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp
index 23a215763738..ff8df2a6acaa 100644
--- a/source/Commands/CommandObjectRegister.cpp
+++ b/source/Commands/CommandObjectRegister.cpp
@@ -7,12 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectRegister.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+
// Project includes
+#include "CommandObjectRegister.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
@@ -30,7 +31,6 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
using namespace lldb;
using namespace lldb_private;
@@ -42,14 +42,14 @@ class CommandObjectRegisterRead : public CommandObjectParsed
{
public:
CommandObjectRegisterRead (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "register read",
- "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.",
- NULL,
- eCommandRequiresFrame |
- eCommandRequiresRegContext |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
+ CommandObjectParsed(interpreter,
+ "register read",
+ "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.",
+ nullptr,
+ eCommandRequiresFrame |
+ eCommandRequiresRegContext |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_option_group (interpreter),
m_format_options (eFormatDefault),
m_command_options ()
@@ -71,12 +71,9 @@ public:
m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_ALL);
m_option_group.Append (&m_command_options);
m_option_group.Finalize();
-
}
- ~CommandObjectRegisterRead () override
- {
- }
+ ~CommandObjectRegisterRead() override = default;
Options *
GetOptions () override
@@ -175,7 +172,7 @@ protected:
Stream &strm = result.GetOutputStream();
RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext ();
- const RegisterInfo *reg_info = NULL;
+ const RegisterInfo *reg_info = nullptr;
if (command.GetArgumentCount() == 0)
{
size_t set_idx;
@@ -184,9 +181,9 @@ protected:
const size_t set_array_size = m_command_options.set_indexes.GetSize();
if (set_array_size > 0)
{
- for (size_t i=0; i<set_array_size; ++i)
+ for (size_t i = 0; i < set_array_size; ++i)
{
- set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL);
+ set_idx = m_command_options.set_indexes[i]->GetUInt64Value(UINT32_MAX, nullptr);
if (set_idx < reg_ctx->GetRegisterSetCount())
{
if (!DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx))
@@ -234,7 +231,7 @@ protected:
else
{
const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
+ for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
{
// in most LLDB commands we accept $rbx as the name for register RBX - and here we would
// reject it and non-existant. we should be more consistent towards the user and allow them
@@ -269,12 +266,9 @@ protected:
alternate_name (false, false)
{
}
-
- ~CommandOptions () override
- {
- }
-
-
+
+ ~CommandOptions() override = default;
+
uint32_t
GetNumDefinitions () override;
@@ -350,9 +344,9 @@ protected:
const OptionDefinition
CommandObjectRegisterRead::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone , "Display register names using the alternate register name if there is one."},
- { LLDB_OPT_SET_1 , false, "set" , 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."},
- { LLDB_OPT_SET_2 , false, "all" , 'a', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone , "Show all register sets."},
+ { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone , "Display register names using the alternate register name if there is one."},
+ { LLDB_OPT_SET_1 , false, "set" , 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex , "Specify which register sets to dump by index."},
+ { LLDB_OPT_SET_2 , false, "all" , 'a', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone , "Show all register sets."},
};
uint32_t
@@ -361,7 +355,6 @@ CommandObjectRegisterRead::CommandOptions::GetNumDefinitions ()
return llvm::array_lengthof(g_option_table);
}
-
//----------------------------------------------------------------------
// "register write"
//----------------------------------------------------------------------
@@ -369,14 +362,14 @@ class CommandObjectRegisterWrite : public CommandObjectParsed
{
public:
CommandObjectRegisterWrite (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "register write",
- "Modify a single register value.",
- NULL,
- eCommandRequiresFrame |
- eCommandRequiresRegContext |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused)
+ CommandObjectParsed(interpreter,
+ "register write",
+ "Modify a single register value.",
+ nullptr,
+ eCommandRequiresFrame |
+ eCommandRequiresRegContext |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused)
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -402,9 +395,7 @@ public:
m_arguments.push_back (arg2);
}
- ~CommandObjectRegisterWrite () override
- {
- }
+ ~CommandObjectRegisterWrite() override = default;
protected:
bool
@@ -422,8 +413,7 @@ protected:
{
const char *reg_name = command.GetArgumentAtIndex(0);
const char *value_str = command.GetArgumentAtIndex(1);
-
-
+
// in most LLDB commands we accept $rbx as the name for register RBX - and here we would
// reject it and non-existant. we should be more consistent towards the user and allow them
// to say reg write $rbx - internally, however, we should be strict and not allow ourselves
@@ -474,24 +464,16 @@ protected:
}
};
-
//----------------------------------------------------------------------
// CommandObjectRegister constructor
//----------------------------------------------------------------------
-CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "register",
- "A set of commands to access thread registers.",
- "register [read|write] ...")
+CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "register",
+ "Commands to access registers for the current thread and stack frame.",
+ "register [read|write] ...")
{
LoadSubCommand ("read", CommandObjectSP (new CommandObjectRegisterRead (interpreter)));
LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter)));
}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-CommandObjectRegister::~CommandObjectRegister()
-{
-}
+CommandObjectRegister::~CommandObjectRegister() = default;
diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp
index 890d77028a99..b76af2075255 100644
--- a/source/Commands/CommandObjectSettings.cpp
+++ b/source/Commands/CommandObjectSettings.cpp
@@ -12,6 +12,8 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
+#include "llvm/ADT/StringRef.h"
+
// Project includes
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -20,7 +22,6 @@
using namespace lldb;
using namespace lldb_private;
-#include "llvm/ADT/StringRef.h"
//-------------------------------------------------------------------------
// CommandObjectSettingsSet
@@ -29,12 +30,9 @@ using namespace lldb_private;
class CommandObjectSettingsSet : public CommandObjectRaw
{
public:
- CommandObjectSettingsSet (CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "settings set",
- "Set or change the value of a single debugger setting variable.",
- NULL),
- m_options (interpreter)
+ CommandObjectSettingsSet(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings set", "Set the value of the specified debugger setting.", nullptr),
+ m_options(interpreter)
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -82,8 +80,7 @@ insert-before or insert-after."
}
-
- ~CommandObjectSettingsSet () override {}
+ ~CommandObjectSettingsSet() override = default;
// Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
bool
@@ -98,14 +95,13 @@ insert-before or insert-after."
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_global (false)
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -160,7 +156,7 @@ insert-before or insert-after."
std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
const size_t argc = input.GetArgumentCount();
- const char *arg = NULL;
+ const char *arg = nullptr;
int setting_var_idx;
for (setting_var_idx = 1; setting_var_idx < static_cast<int>(argc);
++setting_var_idx)
@@ -172,14 +168,14 @@ insert-before or insert-after."
if (cursor_index == setting_var_idx)
{
// Attempting to complete setting variable name
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
}
else
{
@@ -231,7 +227,7 @@ protected:
}
const char *var_name = cmd_args.GetArgumentAtIndex (0);
- if ((var_name == NULL) || (var_name[0] == '\0'))
+ if ((var_name == nullptr) || (var_name[0] == '\0'))
{
result.AppendError ("'settings set' command requires a valid variable name");
result.SetStatus (eReturnStatusFailed);
@@ -246,10 +242,10 @@ protected:
Error error;
if (m_options.m_global)
{
- error = m_interpreter.GetDebugger().SetPropertyValue (NULL,
- eVarSetOperationAssign,
- var_name,
- var_value_cstr);
+ error = m_interpreter.GetDebugger().SetPropertyValue(nullptr,
+ eVarSetOperationAssign,
+ var_name,
+ var_value_cstr);
}
if (error.Success())
@@ -280,6 +276,7 @@ protected:
return result.Succeeded();
}
+
private:
CommandOptions m_options;
};
@@ -287,11 +284,10 @@ private:
OptionDefinition
CommandObjectSettingsSet::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Apply the new value to the global default value." },
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Apply the new value to the global default value." },
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
//-------------------------------------------------------------------------
// CommandObjectSettingsShow -- Show current values
//-------------------------------------------------------------------------
@@ -299,11 +295,10 @@ CommandObjectSettingsSet::CommandOptions::g_option_table[] =
class CommandObjectSettingsShow : public CommandObjectParsed
{
public:
- CommandObjectSettingsShow (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "settings show",
- "Show the specified internal debugger setting variable and its value, or show all the currently set variables and their values, if nothing is specified.",
- NULL)
+ CommandObjectSettingsShow(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "settings show",
+ "Show matching debugger settings and their current values. Defaults to showing all settings.", nullptr)
{
CommandArgumentEntry arg1;
CommandArgumentData var_name_arg;
@@ -319,8 +314,7 @@ public:
m_arguments.push_back (arg1);
}
- ~CommandObjectSettingsShow () override {}
-
+ ~CommandObjectSettingsShow() override = default;
int
HandleArgumentCompletion (Args &input,
@@ -334,14 +328,14 @@ public:
{
std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -354,7 +348,7 @@ protected:
const size_t argc = args.GetArgumentCount ();
if (argc > 0)
{
- for (size_t i=0; i<argc; ++i)
+ for (size_t i = 0; i < argc; ++i)
{
const char *property_path = args.GetArgumentAtIndex (i);
@@ -385,12 +379,11 @@ protected:
class CommandObjectSettingsList : public CommandObjectParsed
{
-public:
- CommandObjectSettingsList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "settings list",
- "List and describe all the internal debugger settings variables that are available to the user to 'set' or 'show', or describe a particular variable or set of variables (by specifying the variable name or a common prefix).",
- NULL)
+public:
+ CommandObjectSettingsList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "settings list",
+ "List and describe matching debugger settings. Defaults to all listing all settings.",
+ nullptr)
{
CommandArgumentEntry arg;
CommandArgumentData var_name_arg;
@@ -411,7 +404,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectSettingsList () override {}
+ ~CommandObjectSettingsList() override = default;
int
HandleArgumentCompletion (Args &input,
@@ -425,14 +418,14 @@ public:
{
std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -448,7 +441,7 @@ protected:
{
const bool dump_qualified_name = true;
- for (size_t i=0; i<argc; ++i)
+ for (size_t i = 0; i < argc; ++i)
{
const char *property_path = args.GetArgumentAtIndex (i);
@@ -481,11 +474,9 @@ protected:
class CommandObjectSettingsRemove : public CommandObjectRaw
{
public:
- CommandObjectSettingsRemove (CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "settings remove",
- "Remove the specified element from an array or dictionary settings variable.",
- NULL)
+ CommandObjectSettingsRemove(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings remove",
+ "Remove a value from a setting, specified by array index or dictionary key.", nullptr)
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -517,7 +508,7 @@ public:
m_arguments.push_back (arg2);
}
- ~CommandObjectSettingsRemove () override {}
+ ~CommandObjectSettingsRemove() override = default;
int
HandleArgumentCompletion (Args &input,
@@ -533,14 +524,14 @@ public:
// Attempting to complete variable name
if (cursor_index < 2)
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -566,7 +557,7 @@ protected:
}
const char *var_name = cmd_args.GetArgumentAtIndex (0);
- if ((var_name == NULL) || (var_name[0] == '\0'))
+ if ((var_name == nullptr) || (var_name[0] == '\0'))
{
result.AppendError ("'settings set' command requires a valid variable name");
result.SetStatus (eReturnStatusFailed);
@@ -600,11 +591,9 @@ protected:
class CommandObjectSettingsReplace : public CommandObjectRaw
{
public:
- CommandObjectSettingsReplace (CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "settings replace",
- "Replace the specified element from an internal debugger settings array or dictionary variable with the specified new value.",
- NULL)
+ CommandObjectSettingsReplace(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings replace",
+ "Replace the debugger setting value specified by array index or dictionary key.", nullptr)
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -646,8 +635,7 @@ public:
m_arguments.push_back (arg3);
}
-
- ~CommandObjectSettingsReplace () override {}
+ ~CommandObjectSettingsReplace() override = default;
// Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
bool
@@ -667,14 +655,14 @@ public:
// Attempting to complete variable name
if (cursor_index < 2)
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -687,14 +675,13 @@ protected:
Args cmd_args(command);
const char *var_name = cmd_args.GetArgumentAtIndex (0);
- if ((var_name == NULL) || (var_name[0] == '\0'))
+ if ((var_name == nullptr) || (var_name[0] == '\0'))
{
result.AppendError ("'settings replace' command requires a valid variable name; No value supplied");
result.SetStatus (eReturnStatusFailed);
return false;
}
-
// Split the raw command into var_name, index_value, and value triple.
llvm::StringRef raw_str(command);
std::string var_value_string = raw_str.split(var_name).second.str();
@@ -727,11 +714,11 @@ protected:
class CommandObjectSettingsInsertBefore : public CommandObjectRaw
{
public:
- CommandObjectSettingsInsertBefore (CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "settings insert-before",
- "Insert value(s) into an internal debugger settings array variable, immediately before the specified element.",
- NULL)
+ CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings insert-before", "Insert one or more values into an debugger array "
+ "setting immediately before the specified element "
+ "index.",
+ nullptr)
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -767,7 +754,7 @@ public:
m_arguments.push_back (arg3);
}
- ~CommandObjectSettingsInsertBefore () override {}
+ ~CommandObjectSettingsInsertBefore() override = default;
// Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
bool
@@ -787,14 +774,14 @@ public:
// Attempting to complete variable name
if (cursor_index < 2)
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -816,7 +803,7 @@ protected:
}
const char *var_name = cmd_args.GetArgumentAtIndex (0);
- if ((var_name == NULL) || (var_name[0] == '\0'))
+ if ((var_name == nullptr) || (var_name[0] == '\0'))
{
result.AppendError ("'settings insert-before' command requires a valid variable name; No value supplied");
result.SetStatus (eReturnStatusFailed);
@@ -850,11 +837,10 @@ protected:
class CommandObjectSettingsInsertAfter : public CommandObjectRaw
{
public:
- CommandObjectSettingsInsertAfter (CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "settings insert-after",
- "Insert value(s) into an internal debugger settings array variable, immediately after the specified element.",
- NULL)
+ CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
+ : CommandObjectRaw(
+ interpreter, "settings insert-after",
+ "Insert one or more values into a debugger array settings after the specified element index.", nullptr)
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -890,7 +876,7 @@ public:
m_arguments.push_back (arg3);
}
- ~CommandObjectSettingsInsertAfter () override {}
+ ~CommandObjectSettingsInsertAfter() override = default;
// Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
bool
@@ -910,14 +896,14 @@ public:
// Attempting to complete variable name
if (cursor_index < 2)
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -939,7 +925,7 @@ protected:
}
const char *var_name = cmd_args.GetArgumentAtIndex (0);
- if ((var_name == NULL) || (var_name[0] == '\0'))
+ if ((var_name == nullptr) || (var_name[0] == '\0'))
{
result.AppendError ("'settings insert-after' command requires a valid variable name; No value supplied");
result.SetStatus (eReturnStatusFailed);
@@ -973,11 +959,9 @@ protected:
class CommandObjectSettingsAppend : public CommandObjectRaw
{
public:
- CommandObjectSettingsAppend (CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "settings append",
- "Append a new value to the end of an internal debugger settings array, dictionary or string variable.",
- NULL)
+ CommandObjectSettingsAppend(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings append",
+ "Append one or more values to a debugger array, dictionary, or string setting.", nullptr)
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -1003,7 +987,7 @@ public:
m_arguments.push_back (arg2);
}
- ~CommandObjectSettingsAppend () override {}
+ ~CommandObjectSettingsAppend() override = default;
// Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
bool
@@ -1023,14 +1007,14 @@ public:
// Attempting to complete variable name
if (cursor_index < 2)
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -1051,7 +1035,7 @@ protected:
}
const char *var_name = cmd_args.GetArgumentAtIndex (0);
- if ((var_name == NULL) || (var_name[0] == '\0'))
+ if ((var_name == nullptr) || (var_name[0] == '\0'))
{
result.AppendError ("'settings append' command requires a valid variable name; No value supplied");
result.SetStatus (eReturnStatusFailed);
@@ -1088,11 +1072,9 @@ protected:
class CommandObjectSettingsClear : public CommandObjectParsed
{
public:
- CommandObjectSettingsClear (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "settings clear",
- "Erase all the contents of an internal debugger settings variables; this is only valid for variables with clearable types, i.e. strings, arrays or dictionaries.",
- NULL)
+ CommandObjectSettingsClear(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "settings clear", "Clear a debugger setting array, dictionary, or string.",
+ nullptr)
{
CommandArgumentEntry arg;
CommandArgumentData var_name_arg;
@@ -1108,7 +1090,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectSettingsClear () override {}
+ ~CommandObjectSettingsClear() override = default;
int
HandleArgumentCompletion (Args &input,
@@ -1124,14 +1106,14 @@ public:
// Attempting to complete variable name
if (cursor_index < 2)
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -1151,17 +1133,17 @@ protected:
}
const char *var_name = command.GetArgumentAtIndex (0);
- if ((var_name == NULL) || (var_name[0] == '\0'))
+ if ((var_name == nullptr) || (var_name[0] == '\0'))
{
result.AppendError ("'settings clear' command requires a valid variable name; No value supplied");
result.SetStatus (eReturnStatusFailed);
return false;
}
- Error error (m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
- eVarSetOperationClear,
- var_name,
- NULL));
+ Error error(m_interpreter.GetDebugger().SetPropertyValue(&m_exe_ctx,
+ eVarSetOperationClear,
+ var_name,
+ nullptr));
if (error.Fail())
{
result.AppendError (error.AsCString());
@@ -1177,11 +1159,9 @@ protected:
// CommandObjectMultiwordSettings
//-------------------------------------------------------------------------
-CommandObjectMultiwordSettings::CommandObjectMultiwordSettings (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "settings",
- "A set of commands for manipulating internal settable debugger variables.",
- "settings <command> [<command-options>]")
+CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "settings", "Commands for managing LLDB settings.",
+ "settings <subcommand> [<command-options>]")
{
LoadSubCommand ("set", CommandObjectSP (new CommandObjectSettingsSet (interpreter)));
LoadSubCommand ("show", CommandObjectSP (new CommandObjectSettingsShow (interpreter)));
@@ -1194,6 +1174,4 @@ CommandObjectMultiwordSettings::CommandObjectMultiwordSettings (CommandInterpret
LoadSubCommand ("clear", CommandObjectSP (new CommandObjectSettingsClear (interpreter)));
}
-CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings ()
-{
-}
+CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;
diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp
index a9e52d1a76f3..cef9d09d0e55 100644
--- a/source/Commands/CommandObjectSource.cpp
+++ b/source/Commands/CommandObjectSource.cpp
@@ -35,7 +35,6 @@
using namespace lldb;
using namespace lldb_private;
-
#pragma mark CommandObjectSourceInfo
//----------------------------------------------------------------------
// CommandObjectSourceInfo - debug line entries dumping command
@@ -43,13 +42,12 @@ using namespace lldb_private;
class CommandObjectSourceInfo : public CommandObjectParsed
{
-
class CommandOptions : public Options
{
public:
CommandOptions (CommandInterpreter &interpreter) : Options(interpreter) {}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -119,6 +117,7 @@ class CommandObjectSourceInfo : public CommandObjectParsed
{
return g_option_table;
}
+
static OptionDefinition g_option_table[];
// Instance variables to hold the values for command options.
@@ -133,15 +132,16 @@ class CommandObjectSourceInfo : public CommandObjectParsed
};
public:
- CommandObjectSourceInfo (CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "source info", "Display source line information (as specified) based "
- "on the current executable's debug info.",
- NULL, eCommandRequiresTarget),
+ CommandObjectSourceInfo(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "source info", "Display source line information for the current target "
+ "process. Defaults to instruction pointer in current stack "
+ "frame.",
+ nullptr, eCommandRequiresTarget),
m_options(interpreter)
{
}
- ~CommandObjectSourceInfo () override {}
+ ~CommandObjectSourceInfo() override = default;
Options *
GetOptions () override
@@ -150,7 +150,6 @@ public:
}
protected:
-
// Dump the line entries in each symbol context.
// Return the number of entries found.
// If module_list is set, only dump lines contained in one of the modules.
@@ -172,7 +171,7 @@ protected:
if (file_spec)
{
assert(file_spec.GetFilename().AsCString());
- has_path = (file_spec.GetDirectory().AsCString() != 0);
+ has_path = (file_spec.GetDirectory().AsCString() != nullptr);
}
// Dump all the line entries for the file in the list.
@@ -240,7 +239,7 @@ protected:
if (cu)
{
assert(file_spec.GetFilename().AsCString());
- bool has_path = (file_spec.GetDirectory().AsCString() != 0);
+ bool has_path = (file_spec.GetDirectory().AsCString() != nullptr);
const FileSpecList &cu_file_list = cu->GetSupportFiles();
size_t file_idx = cu_file_list.FindFileIndex(0, file_spec, has_path);
if (file_idx != UINT32_MAX)
@@ -390,7 +389,7 @@ protected:
else
{
StreamString addr_strm;
- so_addr.Dump(&addr_strm, NULL, Address::DumpStyleModuleWithFileAddress);
+ so_addr.Dump(&addr_strm, nullptr, Address::DumpStyleModuleWithFileAddress);
error_strm.Printf("Address 0x%" PRIx64 " resolves to %s, but there is"
" no source information available for this address.\n",
addr, addr_strm.GetData());
@@ -399,7 +398,7 @@ protected:
else
{
StreamString addr_strm;
- so_addr.Dump(&addr_strm, NULL, Address::DumpStyleModuleWithFileAddress);
+ so_addr.Dump(&addr_strm, nullptr, Address::DumpStyleModuleWithFileAddress);
error_strm.Printf("Address 0x%" PRIx64 " resolves to %s, but it cannot"
" be found in any modules.\n",
addr, addr_strm.GetData());
@@ -573,7 +572,7 @@ protected:
DumpLinesForFrame (CommandReturnObject &result)
{
StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
- if (cur_frame == NULL)
+ if (cur_frame == nullptr)
{
result.AppendError("No selected frame to use to find the default source.");
return false;
@@ -613,10 +612,10 @@ protected:
}
Target *target = m_exe_ctx.GetTargetPtr();
- if (target == NULL)
+ if (target == nullptr)
{
target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError("invalid target, create a debug target using the "
"'target create' command.");
@@ -631,7 +630,7 @@ protected:
// Collect the list of modules to search.
m_module_list.Clear();
- if (m_options.modules.size() > 0)
+ if (!m_options.modules.empty())
{
for (size_t i = 0, e = m_options.modules.size(); i < e; ++i)
{
@@ -699,27 +698,26 @@ protected:
};
OptionDefinition CommandObjectSourceInfo::CommandOptions::g_option_table[] = {
- {LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount,
+ {LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount,
"The number of line entries to display."},
- {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL,
+ {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr,
CommandCompletions::eModuleCompletion, eArgTypeShlibName,
"Look up the source in the given module or shared library (can be "
"specified more than once)."},
- {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL,
+ {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr,
CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."},
- {LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
+ {LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
"The line number at which to start the displaying lines."},
- {LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
+ {LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
"The line number at which to stop displaying lines."},
- {LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL,
+ {LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr,
CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."},
- {LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
+ {LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression,
"Lookup the address and display the source information for the "
"corresponding file and line."},
- {0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL}
+ {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
};
-
#pragma mark CommandObjectSourceList
//-------------------------------------------------------------------------
// CommandObjectSourceList
@@ -727,7 +725,6 @@ OptionDefinition CommandObjectSourceInfo::CommandOptions::g_option_table[] = {
class CommandObjectSourceList : public CommandObjectParsed
{
-
class CommandOptions : public Options
{
public:
@@ -736,9 +733,7 @@ class CommandObjectSourceList : public CommandObjectParsed
{
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -810,6 +805,7 @@ class CommandObjectSourceList : public CommandObjectParsed
{
return g_option_table;
}
+
static OptionDefinition g_option_table[];
// Instance variables to hold the values for command options.
@@ -823,22 +819,17 @@ class CommandObjectSourceList : public CommandObjectParsed
bool show_bp_locs;
bool reverse;
};
-
-public:
- CommandObjectSourceList(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "source list",
- "Display source code (as specified) based on the current executable's debug info.",
- NULL,
- eCommandRequiresTarget),
- m_options (interpreter)
- {
- }
- ~CommandObjectSourceList () override
+public:
+ CommandObjectSourceList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "source list",
+ "Display source code for the current target process as specified by options.", nullptr,
+ eCommandRequiresTarget),
+ m_options(interpreter)
{
}
+ ~CommandObjectSourceList() override = default;
Options *
GetOptions () override
@@ -853,7 +844,7 @@ public:
// values for this invocation... I have to scan the arguments directly.
size_t num_args = current_command_args.GetArgumentCount();
bool is_reverse = false;
- for (size_t i = 0 ; i < num_args; i++)
+ for (size_t i = 0; i < num_args; i++)
{
const char *arg = current_command_args.GetArgumentAtIndex(i);
if (arg && (strcmp(arg, "-r") == 0 || strcmp(arg, "--reverse") == 0))
@@ -875,7 +866,6 @@ public:
}
protected:
-
struct SourceInfo
{
ConstString function;
@@ -903,7 +893,7 @@ protected:
operator == (const SourceInfo &rhs) const
{
return function == rhs.function &&
- line_entry.file == rhs.line_entry.file &&
+ line_entry.original_file == rhs.line_entry.original_file &&
line_entry.line == rhs.line_entry.line;
}
@@ -911,7 +901,7 @@ protected:
operator != (const SourceInfo &rhs) const
{
return function != rhs.function ||
- line_entry.file != rhs.line_entry.file ||
+ line_entry.original_file != rhs.line_entry.original_file ||
line_entry.line != rhs.line_entry.line;
}
@@ -950,7 +940,7 @@ protected:
uint32_t end_line;
FileSpec end_file;
- if (sc.block == NULL)
+ if (sc.block == nullptr)
{
// Not an inlined function
sc.function->GetStartLineSourceInfo (start_file, start_line);
@@ -1194,7 +1184,7 @@ protected:
// in all modules
const ModuleList &module_list = target->GetImages();
const size_t num_modules = module_list.GetSize();
- for (size_t i=0; i<num_modules; ++i)
+ for (size_t i = 0; i < num_modules; ++i)
{
ModuleSP module_sp (module_list.GetModuleAtIndex(i));
if (module_sp && module_sp->ResolveFileAddress(m_options.address, so_addr))
@@ -1231,7 +1221,7 @@ protected:
}
else
{
- so_addr.Dump(&error_strm, NULL, Address::DumpStyleModuleWithFileAddress);
+ so_addr.Dump(&error_strm, nullptr, Address::DumpStyleModuleWithFileAddress);
result.AppendErrorWithFormat("address resolves to %s, but there is no line table information available for this address.\n",
error_strm.GetData());
result.SetStatus (eReturnStatusFailed);
@@ -1248,7 +1238,7 @@ protected:
}
}
uint32_t num_matches = sc_list.GetSize();
- for (uint32_t i=0; i<num_matches; ++i)
+ for (uint32_t i = 0; i < num_matches; ++i)
{
SymbolContext sc;
sc_list.GetContextAtIndex(i, sc);
@@ -1339,7 +1329,6 @@ protected:
{
result.SetStatus (eReturnStatusSuccessFinishResult);
}
-
}
}
else
@@ -1350,7 +1339,7 @@ protected:
SymbolContextList sc_list;
size_t num_matches = 0;
- if (m_options.modules.size() > 0)
+ if (!m_options.modules.empty())
{
ModuleList matching_modules;
for (size_t i = 0, e = m_options.modules.size(); i < e; ++i)
@@ -1389,7 +1378,7 @@ protected:
if (num_matches > 1)
{
bool got_multiple = false;
- FileSpec *test_cu_spec = NULL;
+ FileSpec *test_cu_spec = nullptr;
for (unsigned i = 0; i < num_matches; i++)
{
@@ -1461,27 +1450,27 @@ protected:
{
if (m_breakpoint_locations.GetFileLineMatches().GetSize() > 0)
return &m_breakpoint_locations.GetFileLineMatches();
- return NULL;
+ return nullptr;
}
+
CommandOptions m_options;
FileLineResolver m_breakpoint_locations;
std::string m_reverse_name;
-
};
OptionDefinition
CommandObjectSourceList::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "The number of source lines to display."},
+{ LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "The number of source lines to display."},
{ LLDB_OPT_SET_1 |
- LLDB_OPT_SET_2 , false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library."},
-{ LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints."},
-{ LLDB_OPT_SET_1 , false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."},
-{ LLDB_OPT_SET_1 , false, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, "The line number at which to start the display source."},
-{ LLDB_OPT_SET_2 , false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."},
-{ LLDB_OPT_SET_3 , false, "address",'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line."},
-{ LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source."},
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ LLDB_OPT_SET_2 , false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library."},
+{ LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints."},
+{ LLDB_OPT_SET_1 , false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."},
+{ LLDB_OPT_SET_1 , false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "The line number at which to start the display source."},
+{ LLDB_OPT_SET_2 , false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."},
+{ LLDB_OPT_SET_3 , false, "address",'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line."},
+{ LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source."},
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
#pragma mark CommandObjectMultiwordSource
@@ -1489,17 +1478,14 @@ CommandObjectSourceList::CommandOptions::g_option_table[] =
// CommandObjectMultiwordSource
//-------------------------------------------------------------------------
-CommandObjectMultiwordSource::CommandObjectMultiwordSource (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "source",
- "A set of commands for accessing source file information",
- "source <subcommand> [<subcommand-options>]")
+CommandObjectMultiwordSource::CommandObjectMultiwordSource(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "source",
+ "Commands for examining source code described by debug information for the current target process.",
+ "source <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("info", CommandObjectSP (new CommandObjectSourceInfo (interpreter)));
LoadSubCommand ("list", CommandObjectSP (new CommandObjectSourceList (interpreter)));
}
-CommandObjectMultiwordSource::~CommandObjectMultiwordSource ()
-{
-}
-
+CommandObjectMultiwordSource::~CommandObjectMultiwordSource() = default;
diff --git a/source/Commands/CommandObjectSyntax.cpp b/source/Commands/CommandObjectSyntax.cpp
index e9fa084fc0b5..c238bccfb5dd 100644
--- a/source/Commands/CommandObjectSyntax.cpp
+++ b/source/Commands/CommandObjectSyntax.cpp
@@ -7,15 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#include "CommandObjectSyntax.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "CommandObjectSyntax.h"
+#include "CommandObjectHelp.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/Options.h"
-
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
@@ -47,10 +46,7 @@ CommandObjectSyntax::CommandObjectSyntax (CommandInterpreter &interpreter) :
m_arguments.push_back (arg);
}
-CommandObjectSyntax::~CommandObjectSyntax()
-{
-}
-
+CommandObjectSyntax::~CommandObjectSyntax() = default;
bool
CommandObjectSyntax::DoExecute (Args& command, CommandReturnObject &result)
@@ -82,10 +78,10 @@ CommandObjectSyntax::DoExecute (Args& command, CommandReturnObject &result)
}
}
- if (all_okay && (cmd_obj != NULL))
+ if (all_okay && (cmd_obj != nullptr))
{
Stream &output_strm = result.GetOutputStream();
- if (cmd_obj->GetOptions() != NULL)
+ if (cmd_obj->GetOptions() != nullptr)
{
output_strm.Printf ("\nSyntax: %s\n", cmd_obj->GetSyntax());
output_strm.Printf ("(Try 'help %s' for more information on command options syntax.)\n",
@@ -102,8 +98,17 @@ CommandObjectSyntax::DoExecute (Args& command, CommandReturnObject &result)
{
std::string cmd_string;
command.GetCommandString (cmd_string);
- result.AppendErrorWithFormat ("'%s' is not a known command.\n", cmd_string.c_str());
- result.AppendError ("Try 'help' to see a current list of commands.");
+
+ StreamString error_msg_stream;
+ const bool generate_apropos = true;
+ const bool generate_type_lookup = false;
+ CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
+ cmd_string.c_str(),
+ nullptr,
+ nullptr,
+ generate_apropos,
+ generate_type_lookup);
+ result.AppendErrorWithFormat ("%s", error_msg_stream.GetData());
result.SetStatus (eReturnStatusFailed);
}
}
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index 57ec1c953fcf..9e535ba8ebd8 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -10,9 +10,9 @@
#include "CommandObjectTarget.h"
// C Includes
-#include <errno.h>
-
// C++ Includes
+#include <cerrno>
+
// Other libraries and framework includes
// Project includes
#include "lldb/Interpreter/Args.h"
@@ -58,8 +58,6 @@
using namespace lldb;
using namespace lldb_private;
-
-
static void
DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
{
@@ -128,7 +126,7 @@ DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Strea
{
TargetSP selected_target_sp (target_list.GetSelectedTarget());
strm.PutCString ("Current targets:\n");
- for (uint32_t i=0; i<num_targets; ++i)
+ for (uint32_t i = 0; i < num_targets; ++i)
{
TargetSP target_sp (target_list.GetTargetAtIndex (i));
if (target_sp)
@@ -144,6 +142,7 @@ DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Strea
}
return num_targets;
}
+
#pragma mark CommandObjectTargetCreate
//-------------------------------------------------------------------------
@@ -154,10 +153,10 @@ class CommandObjectTargetCreate : public CommandObjectParsed
{
public:
CommandObjectTargetCreate(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target create",
- "Create a target using the argument as the main executable.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "target create",
+ "Create a target using the argument as the main executable.",
+ nullptr),
m_option_group (interpreter),
m_arch_option (),
m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename, "Fullpath to a core file to use for this target."),
@@ -188,9 +187,7 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectTargetCreate () override
- {
- }
+ ~CommandObjectTargetCreate() override = default;
Options *
GetOptions () override
@@ -211,14 +208,14 @@ public:
std::string completion_str (input.GetArgumentAtIndex(cursor_index));
completion_str.erase (cursor_char_position);
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eDiskFileCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -285,12 +282,12 @@ protected:
TargetSP target_sp;
const char *arch_cstr = m_arch_option.GetArchitectureName();
const bool get_dependent_files = m_add_dependents.GetOptionValue().GetCurrentValue();
- Error error (debugger.GetTargetList().CreateTarget (debugger,
- file_path,
- arch_cstr,
- get_dependent_files,
- NULL,
- target_sp));
+ Error error(debugger.GetTargetList().CreateTarget(debugger,
+ file_path,
+ arch_cstr,
+ get_dependent_files,
+ nullptr,
+ target_sp));
if (target_sp)
{
@@ -398,7 +395,7 @@ protected:
core_file_dir.GetDirectory() = core_file.GetDirectory();
target_sp->GetExecutableSearchPaths ().Append (core_file_dir);
- ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file));
+ ProcessSP process_sp(target_sp->CreateProcess(m_interpreter.GetDebugger().GetListener(), nullptr, &core_file));
if (process_sp)
{
@@ -470,17 +467,14 @@ class CommandObjectTargetList : public CommandObjectParsed
{
public:
CommandObjectTargetList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target list",
- "List all current targets in the current debug session.",
- NULL,
- 0)
+ CommandObjectParsed(interpreter,
+ "target list",
+ "List all current targets in the current debug session.",
+ nullptr)
{
}
- ~CommandObjectTargetList () override
- {
- }
+ ~CommandObjectTargetList() override = default;
protected:
bool
@@ -506,7 +500,6 @@ protected:
}
};
-
#pragma mark CommandObjectTargetSelect
//----------------------------------------------------------------------
@@ -517,17 +510,14 @@ class CommandObjectTargetSelect : public CommandObjectParsed
{
public:
CommandObjectTargetSelect (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target select",
- "Select a target as the current target by target index.",
- NULL,
- 0)
+ CommandObjectParsed(interpreter,
+ "target select",
+ "Select a target as the current target by target index.",
+ nullptr)
{
}
- ~CommandObjectTargetSelect () override
- {
- }
+ ~CommandObjectTargetSelect() override = default;
protected:
bool
@@ -566,7 +556,8 @@ protected:
result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
target_idx,
num_targets - 1);
- } else
+ }
+ else
{
result.AppendErrorWithFormat ("index %u is out of range since there are no active targets\n",
target_idx);
@@ -599,11 +590,10 @@ class CommandObjectTargetDelete : public CommandObjectParsed
{
public:
CommandObjectTargetDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target delete",
- "Delete one or more targets by target index.",
- NULL,
- 0),
+ CommandObjectParsed(interpreter,
+ "target delete",
+ "Delete one or more targets by target index.",
+ nullptr),
m_option_group(interpreter),
m_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.", false, true),
m_cleanup_option(
@@ -621,9 +611,7 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectTargetDelete () override
- {
- }
+ ~CommandObjectTargetDelete() override = default;
Options *
GetOptions () override
@@ -724,7 +712,6 @@ protected:
OptionGroupBoolean m_cleanup_option;
};
-
#pragma mark CommandObjectTargetVariable
//----------------------------------------------------------------------
@@ -737,22 +724,20 @@ class CommandObjectTargetVariable : public CommandObjectParsed
static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
public:
- CommandObjectTargetVariable (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target variable",
- "Read global variable(s) prior to, or while running your binary.",
- NULL,
- eCommandRequiresTarget),
- m_option_group (interpreter),
- m_option_variable (false), // Don't include frame options
- m_option_format (eFormatDefault),
- m_option_compile_units (LLDB_OPT_SET_1, false, "file",
- SHORT_OPTION_FILE, 0, eArgTypeFilename,
- "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."),
- m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib",
- SHORT_OPTION_SHLB, 0, eArgTypeFilename,
- "A basename or fullpath to a shared library to use in the search for global variables. This option can be specified multiple times."),
- m_varobj_options()
+ CommandObjectTargetVariable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "target variable",
+ "Read global variables for the current target, before or while running a process.",
+ nullptr, eCommandRequiresTarget),
+ m_option_group(interpreter),
+ m_option_variable(false), // Don't include frame options
+ m_option_format(eFormatDefault),
+ m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE, 0, eArgTypeFilename,
+ "A basename or fullpath to a file that contains global variables. This option can be "
+ "specified multiple times."),
+ m_option_shared_libraries(LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0, eArgTypeFilename,
+ "A basename or fullpath to a shared library to use in the search for global "
+ "variables. This option can be specified multiple times."),
+ m_varobj_options()
{
CommandArgumentEntry arg;
CommandArgumentData var_name_arg;
@@ -775,17 +760,15 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectTargetVariable () override
- {
- }
+ ~CommandObjectTargetVariable() override = default;
void
DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
{
DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
- if (false == valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
- true == valobj_sp->IsRuntimeSupportValue())
+ if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
+ valobj_sp->IsRuntimeSupportValue())
return;
switch (var_sp->GetScope())
@@ -810,6 +793,11 @@ public:
s.PutCString(" LOCAL: ");
break;
+ case eValueTypeVariableThreadLocal:
+ if (m_option_variable.show_scope)
+ s.PutCString("THREAD: ");
+ break;
+
default:
break;
}
@@ -879,7 +867,7 @@ protected:
sc.comp_unit->GetPath().c_str());
}
- for (uint32_t i=0; i<count; ++i)
+ for (uint32_t i = 0; i < count; ++i)
{
VariableSP var_sp (variable_list.GetVariableAtIndex(i));
if (var_sp)
@@ -891,8 +879,8 @@ protected:
}
}
}
-
}
+
bool
DoExecute (Args& args, CommandReturnObject &result) override
{
@@ -972,7 +960,7 @@ protected:
{
bool success = false;
StackFrame *frame = m_exe_ctx.GetFramePtr();
- CompileUnit *comp_unit = NULL;
+ CompileUnit *comp_unit = nullptr;
if (frame)
{
SymbolContext sc = frame->GetSymbolContext (eSymbolContextCompUnit);
@@ -1093,21 +1081,18 @@ protected:
OptionGroupFileList m_option_compile_units;
OptionGroupFileList m_option_shared_libraries;
OptionGroupValueObjectDisplay m_varobj_options;
-
};
-
#pragma mark CommandObjectTargetModulesSearchPathsAdd
class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed
{
public:
-
CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target modules search-paths add",
- "Add new image search paths substitution pairs to the current target.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "target modules search-paths add",
+ "Add new image search paths substitution pairs to the current target.",
+ nullptr)
{
CommandArgumentEntry arg;
CommandArgumentData old_prefix_arg;
@@ -1131,9 +1116,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectTargetModulesSearchPathsAdd () override
- {
- }
+ ~CommandObjectTargetModulesSearchPathsAdd() override = default;
protected:
bool
@@ -1150,7 +1133,7 @@ protected:
}
else
{
- for (size_t i=0; i<argc; i+=2)
+ for (size_t i = 0; i < argc; i+=2)
{
const char *from = command.GetArgumentAtIndex(i);
const char *to = command.GetArgumentAtIndex(i+1);
@@ -1194,7 +1177,6 @@ protected:
class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed
{
public:
-
CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"target modules search-paths clear",
@@ -1203,9 +1185,7 @@ public:
{
}
- ~CommandObjectTargetModulesSearchPathsClear () override
- {
- }
+ ~CommandObjectTargetModulesSearchPathsClear() override = default;
protected:
bool
@@ -1232,12 +1212,11 @@ protected:
class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed
{
public:
-
CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target modules search-paths insert",
- "Insert a new image search path substitution pair into the current target at the specified index.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "target modules search-paths insert",
+ "Insert a new image search path substitution pair into the current target at the specified index.",
+ nullptr)
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -1272,9 +1251,7 @@ public:
m_arguments.push_back (arg2);
}
- ~CommandObjectTargetModulesSearchPathsInsert () override
- {
- }
+ ~CommandObjectTargetModulesSearchPathsInsert() override = default;
protected:
bool
@@ -1302,7 +1279,7 @@ protected:
command.Shift();
argc = command.GetArgumentCount();
- for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
+ for (uint32_t i = 0; i < argc; i += 2, ++insert_idx)
{
const char *from = command.GetArgumentAtIndex(i);
const char *to = command.GetArgumentAtIndex(i+1);
@@ -1344,14 +1321,11 @@ protected:
}
};
-
#pragma mark CommandObjectTargetModulesSearchPathsList
-
class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed
{
public:
-
CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"target modules search-paths list",
@@ -1360,9 +1334,7 @@ public:
{
}
- ~CommandObjectTargetModulesSearchPathsList () override
- {
- }
+ ~CommandObjectTargetModulesSearchPathsList() override = default;
protected:
bool
@@ -1395,12 +1367,11 @@ protected:
class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed
{
public:
-
CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target modules search-paths query",
- "Transform a path using the first applicable image search path.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "target modules search-paths query",
+ "Transform a path using the first applicable image search path.",
+ nullptr)
{
CommandArgumentEntry arg;
CommandArgumentData path_arg;
@@ -1416,9 +1387,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectTargetModulesSearchPathsQuery () override
- {
- }
+ ~CommandObjectTargetModulesSearchPathsQuery() override = default;
protected:
bool
@@ -1501,7 +1470,7 @@ DumpCompileUnitLineTable (CommandInterpreter &interpreter,
eSymbolContextCompUnit,
sc_list);
- for (uint32_t i=0; i<num_matches; ++i)
+ for (uint32_t i = 0; i < num_matches; ++i)
{
SymbolContext sc;
if (sc_list.GetContextAtIndex(i, sc))
@@ -1578,6 +1547,34 @@ DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
strm.Printf("%-*s", width, "");
}
+static size_t
+DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list)
+{
+ size_t num_dumped = 0;
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
+ const size_t num_modules = module_list.GetSize();
+ if (num_modules > 0)
+ {
+ strm.Printf("Dumping headers for %" PRIu64 " module(s).\n", static_cast<uint64_t>(num_modules));
+ strm.IndentMore();
+ for (size_t image_idx = 0; image_idx < num_modules; ++image_idx)
+ {
+ Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
+ if (module)
+ {
+ if (num_dumped++ > 0)
+ {
+ strm.EOL();
+ strm.EOL();
+ }
+ ObjectFile *objfile = module->GetObjectFile();
+ objfile->Dump(&strm);
+ }
+ }
+ strm.IndentLess();
+ }
+ return num_dumped;
+}
static void
DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
@@ -1717,7 +1714,6 @@ LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *mod
Symtab *symtab = sym_vendor->GetSymtab();
if (symtab)
{
- uint32_t i;
std::vector<uint32_t> match_indexes;
ConstString symbol_name (name);
uint32_t num_matches = 0;
@@ -1741,7 +1737,7 @@ LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *mod
DumpFullpath (strm, &module->GetFileSpec(), 0);
strm.PutCString(":\n");
strm.IndentMore ();
- for (i=0; i < num_matches; ++i)
+ for (uint32_t i = 0; i < num_matches; ++i)
{
Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
if (symbol && symbol->ValueIsAddress())
@@ -1761,15 +1757,14 @@ LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *mod
return 0;
}
-
static void
DumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose)
{
strm.IndentMore ();
- uint32_t i;
+
const uint32_t num_matches = sc_list.GetSize();
- for (i=0; i<num_matches; ++i)
+ for (uint32_t i = 0; i < num_matches; ++i)
{
SymbolContext sc;
if (sc_list.GetContextAtIndex(i, sc))
@@ -1814,13 +1809,13 @@ LookupFunctionInModule (CommandInterpreter &interpreter,
else
{
ConstString function_name (name);
- num_matches = module->FindFunctions (function_name,
- NULL,
- eFunctionNameTypeAuto,
- include_symbols,
- include_inlines,
- append,
- sc_list);
+ num_matches = module->FindFunctions(function_name,
+ nullptr,
+ eFunctionNameTypeAuto,
+ include_symbols,
+ include_inlines,
+ append,
+ sc_list);
}
if (num_matches)
@@ -1852,7 +1847,8 @@ LookupTypeInModule (CommandInterpreter &interpreter,
SymbolContext sc;
ConstString name(name_cstr);
- num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, type_list);
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+ num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, searched_symbol_files, type_list);
if (num_matches)
{
@@ -1905,7 +1901,8 @@ LookupTypeHere (CommandInterpreter &interpreter,
bool name_is_fully_qualified = false;
ConstString name(name_cstr);
- num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, type_list);
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, searched_symbol_files, type_list);
if (num_matches)
{
@@ -1970,14 +1967,12 @@ LookupFileAndLineInModule (CommandInterpreter &interpreter,
return 0;
}
-
static size_t
FindModulesByName (Target *target,
const char *module_name,
ModuleList &module_list,
bool check_global_list)
{
-// Dump specified images (by basename or fullpath)
FileSpec module_file_spec(module_name, false);
ModuleSpec module_spec (module_file_spec);
@@ -1986,7 +1981,7 @@ FindModulesByName (Target *target,
if (check_global_list)
{
// Check the global list
- Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
+ std::lock_guard<std::recursive_mutex> guard(Module::GetAllocationModuleCollectionMutex());
const size_t num_modules = Module::GetNumberAllocatedModules();
ModuleSP module_sp;
for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
@@ -2057,9 +2052,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectTargetModulesModuleAutoComplete () override
- {
- }
+ ~CommandObjectTargetModulesModuleAutoComplete() override = default;
int
HandleArgumentCompletion (Args &input,
@@ -2075,14 +2068,14 @@ public:
std::string completion_str (input.GetArgumentAtIndex(cursor_index));
completion_str.erase (cursor_char_position);
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eModuleCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eModuleCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
};
@@ -2118,9 +2111,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectTargetModulesSourceFileAutoComplete () override
- {
- }
+ ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
int
HandleArgumentCompletion (Args &input,
@@ -2136,37 +2127,104 @@ public:
std::string completion_str (input.GetArgumentAtIndex(cursor_index));
completion_str.erase (cursor_char_position);
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eSourceFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eSourceFileCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
};
+#pragma mark CommandObjectTargetModulesDumpObjfile
-#pragma mark CommandObjectTargetModulesDumpSymtab
+class CommandObjectTargetModulesDumpObjfile : public CommandObjectTargetModulesModuleAutoComplete
+{
+public:
+ CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
+ : CommandObjectTargetModulesModuleAutoComplete(interpreter, "target modules dump objfile",
+ "Dump the object file headers from one or more target modules.",
+ nullptr)
+ {
+ }
+ ~CommandObjectTargetModulesDumpObjfile() override = default;
+
+protected:
+ bool
+ DoExecute(Args &command, CommandReturnObject &result) override
+ {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == nullptr)
+ {
+ result.AppendError("invalid target, create a debug target using the 'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+
+ size_t num_dumped = 0;
+ if (command.GetArgumentCount() == 0)
+ {
+ // Dump all headers for all modules images
+ num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(), target->GetImages());
+ if (num_dumped == 0)
+ {
+ result.AppendError("the target has no associated executable images");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+ else
+ {
+ // Find the modules that match the basename or full path.
+ ModuleList module_list;
+ const char *arg_cstr;
+ for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
+ {
+ size_t num_matched = FindModulesByName(target, arg_cstr, module_list, true);
+ if (num_matched == 0)
+ {
+ result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
+ }
+ }
+ // Dump all the modules we found.
+ num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
+ }
+
+ if (num_dumped > 0)
+ {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ result.AppendError("no matching executable images found");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
+};
+
+#pragma mark CommandObjectTargetModulesDumpSymtab
class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
{
public:
CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
- CommandObjectTargetModulesModuleAutoComplete (interpreter,
- "target modules dump symtab",
- "Dump the symbol table from one or more target modules.",
- NULL),
- m_options (interpreter)
+ CommandObjectTargetModulesModuleAutoComplete(interpreter,
+ "target modules dump symtab",
+ "Dump the symbol table from one or more target modules.",
+ nullptr),
+ m_options(interpreter)
{
}
- ~CommandObjectTargetModulesDumpSymtab () override
- {
- }
+ ~CommandObjectTargetModulesDumpSymtab() override = default;
Options *
GetOptions () override
@@ -2183,9 +2241,7 @@ public:
{
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -2205,7 +2261,6 @@ public:
default:
error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
break;
-
}
return error;
}
@@ -2233,7 +2288,7 @@ protected:
DoExecute (Args& command, CommandReturnObject &result) override
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("invalid target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -2250,7 +2305,7 @@ protected:
if (command.GetArgumentCount() == 0)
{
// Dump all sections for all modules images
- Mutex::Locker modules_locker(target->GetImages().GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(target->GetImages().GetMutex());
const size_t num_modules = target->GetImages().GetSize();
if (num_modules > 0)
{
@@ -2280,13 +2335,13 @@ protected:
{
// Dump specified images (by basename or fullpath)
const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
+ for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
{
ModuleList module_list;
const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
if (num_matches > 0)
{
- for (size_t i=0; i<num_matches; ++i)
+ for (size_t i = 0; i < num_matches; ++i)
{
Module *module = module_list.GetModulePointerAtIndex(i);
if (module)
@@ -2326,15 +2381,14 @@ g_sort_option_enumeration[4] =
{ eSortOrderNone, "none", "No sorting, use the original symbol table order."},
{ eSortOrderByAddress, "address", "Sort output by symbol address."},
{ eSortOrderByName, "name", "Sort output by symbol name."},
- { 0, NULL, NULL }
+ { 0, nullptr, nullptr }
};
-
OptionDefinition
CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, NULL, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, nullptr, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
#pragma mark CommandObjectTargetModulesDumpSections
@@ -2347,24 +2401,22 @@ class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModules
{
public:
CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
- CommandObjectTargetModulesModuleAutoComplete (interpreter,
- "target modules dump sections",
- "Dump the sections from one or more target modules.",
- //"target modules dump sections [<file1> ...]")
- NULL)
+ CommandObjectTargetModulesModuleAutoComplete(interpreter,
+ "target modules dump sections",
+ "Dump the sections from one or more target modules.",
+ //"target modules dump sections [<file1> ...]")
+ nullptr)
{
}
- ~CommandObjectTargetModulesDumpSections () override
- {
- }
+ ~CommandObjectTargetModulesDumpSections() override = default;
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("invalid target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -2402,13 +2454,13 @@ protected:
{
// Dump specified images (by basename or fullpath)
const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
+ for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
{
ModuleList module_list;
const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
if (num_matches > 0)
{
- for (size_t i=0; i<num_matches; ++i)
+ for (size_t i = 0; i < num_matches; ++i)
{
Module *module = module_list.GetModulePointerAtIndex(i);
if (module)
@@ -2421,7 +2473,7 @@ protected:
else
{
// Check the global list
- Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
+ std::lock_guard<std::recursive_mutex> guard(Module::GetAllocationModuleCollectionMutex());
result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
}
@@ -2440,7 +2492,6 @@ protected:
}
};
-
#pragma mark CommandObjectTargetModulesDumpSymfile
//----------------------------------------------------------------------
@@ -2451,24 +2502,22 @@ class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesM
{
public:
CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
- CommandObjectTargetModulesModuleAutoComplete (interpreter,
- "target modules dump symfile",
- "Dump the debug symbol file for one or more target modules.",
- //"target modules dump symfile [<file1> ...]")
- NULL)
+ CommandObjectTargetModulesModuleAutoComplete(interpreter,
+ "target modules dump symfile",
+ "Dump the debug symbol file for one or more target modules.",
+ //"target modules dump symfile [<file1> ...]")
+ nullptr)
{
}
- ~CommandObjectTargetModulesDumpSymfile () override
- {
- }
+ ~CommandObjectTargetModulesDumpSymfile() override = default;
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("invalid target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -2486,7 +2535,7 @@ protected:
{
// Dump all sections for all modules images
const ModuleList &target_modules = target->GetImages();
- Mutex::Locker modules_locker (target_modules.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
const size_t num_modules = target_modules.GetSize();
if (num_modules > 0)
{
@@ -2508,13 +2557,13 @@ protected:
{
// Dump specified images (by basename or fullpath)
const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
+ for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
{
ModuleList module_list;
const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
if (num_matches > 0)
{
- for (size_t i=0; i<num_matches; ++i)
+ for (size_t i = 0; i < num_matches; ++i)
{
Module *module = module_list.GetModulePointerAtIndex(i);
if (module)
@@ -2541,7 +2590,6 @@ protected:
}
};
-
#pragma mark CommandObjectTargetModulesDumpLineTable
//----------------------------------------------------------------------
@@ -2552,17 +2600,15 @@ class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModule
{
public:
CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
- CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
- "target modules dump line-table",
- "Dump the line table for one or more compilation units.",
- NULL,
- eCommandRequiresTarget)
+ CommandObjectTargetModulesSourceFileAutoComplete(interpreter,
+ "target modules dump line-table",
+ "Dump the line table for one or more compilation units.",
+ nullptr,
+ eCommandRequiresTarget)
{
}
- ~CommandObjectTargetModulesDumpLineTable () override
- {
- }
+ ~CommandObjectTargetModulesDumpLineTable() override = default;
protected:
bool
@@ -2585,12 +2631,12 @@ protected:
{
// Dump specified images (by basename or fullpath)
const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
+ for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
{
FileSpec file_spec(arg_cstr, false);
const ModuleList &target_modules = target->GetImages();
- Mutex::Locker modules_locker(target_modules.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
const size_t num_modules = target_modules.GetSize();
if (num_modules > 0)
{
@@ -2623,7 +2669,6 @@ protected:
}
};
-
#pragma mark CommandObjectTargetModulesDump
//----------------------------------------------------------------------
@@ -2636,21 +2681,19 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "target modules dump",
- "A set of commands for dumping information about one or more target modules.",
- "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
+ CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "target modules dump", "Commands for dumping information about one or more target modules.",
+ "target modules dump [headers|symtab|sections|symfile|line-table] [<file1> <file2> ...]")
{
+ LoadSubCommand("objfile", CommandObjectSP(new CommandObjectTargetModulesDumpObjfile(interpreter)));
LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
}
- ~CommandObjectTargetModulesDump() override
- {
- }
+ ~CommandObjectTargetModulesDump() override = default;
};
class CommandObjectTargetModulesAdd : public CommandObjectParsed
@@ -2669,9 +2712,7 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectTargetModulesAdd () override
- {
- }
+ ~CommandObjectTargetModulesAdd() override = default;
Options *
GetOptions () override
@@ -2692,14 +2733,14 @@ public:
std::string completion_str (input.GetArgumentAtIndex(cursor_index));
completion_str.erase (cursor_char_position);
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eDiskFileCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -2712,7 +2753,7 @@ protected:
DoExecute (Args& args, CommandReturnObject &result) override
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("invalid target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -2787,7 +2828,7 @@ protected:
}
else
{
- for (size_t i=0; i<argc; ++i)
+ for (size_t i = 0; i < argc; ++i)
{
const char *path = args.GetArgumentAtIndex(i);
if (path)
@@ -2849,7 +2890,6 @@ protected:
return result.Succeeded();
}
-
};
class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
@@ -2870,9 +2910,7 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectTargetModulesLoad () override
- {
- }
+ ~CommandObjectTargetModulesLoad() override = default;
Options *
GetOptions () override
@@ -2885,7 +2923,7 @@ protected:
DoExecute (Args& args, CommandReturnObject &result) override
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("invalid target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -2969,7 +3007,7 @@ protected:
return false;
}
- for (size_t i=0; i<argc; i += 2)
+ for (size_t i = 0; i < argc; i += 2)
{
const char *sect_name = args.GetArgumentAtIndex(i);
const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
@@ -3075,7 +3113,7 @@ protected:
path,
!uuid_str.empty() ? " uuid=" : "",
uuid_str.c_str());
- for (size_t i=0; i<num_matches; ++i)
+ for (size_t i = 0; i < num_matches; ++i)
{
if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
result.AppendMessageWithFormat("%s\n", path);
@@ -3125,9 +3163,7 @@ public:
{
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -3148,7 +3184,7 @@ public:
{
unsigned long width = 0;
if (option_arg)
- width = strtoul (option_arg, NULL, 0);
+ width = strtoul(option_arg, nullptr, 0);
m_format_array.push_back(std::make_pair(short_option, width));
}
return error;
@@ -3188,9 +3224,7 @@ public:
{
}
- ~CommandObjectTargetModulesList () override
- {
- }
+ ~CommandObjectTargetModulesList() override = default;
Options *
GetOptions () override
@@ -3208,7 +3242,7 @@ protected:
// object which might lock its contents below (through the "module_list_ptr"
// variable).
ModuleList module_list;
- if (target == NULL && use_global_module_list == false)
+ if (target == nullptr && !use_global_module_list)
{
result.AppendError ("invalid target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -3259,16 +3293,19 @@ protected:
}
size_t num_modules = 0;
- Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL.
- // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
- // the global module list directly.
- const ModuleList *module_list_ptr = NULL;
+
+ // This locker will be locked on the mutex in module_list_ptr if it is non-nullptr.
+ // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
+ // the global module list directly.
+ std::unique_lock<std::recursive_mutex> guard(Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
+
+ const ModuleList *module_list_ptr = nullptr;
const size_t argc = command.GetArgumentCount();
if (argc == 0)
{
if (use_global_module_list)
{
- locker.Lock (Module::GetAllocationModuleCollectionMutex());
+ guard.lock();
num_modules = Module::GetNumberAllocatedModules();
}
else
@@ -3278,7 +3315,7 @@ protected:
}
else
{
- for (size_t i=0; i<argc; ++i)
+ for (size_t i = 0; i < argc; ++i)
{
// Dump specified images (by basename or fullpath)
const char *arg_cstr = command.GetArgumentAtIndex(i);
@@ -3297,9 +3334,11 @@ protected:
module_list_ptr = &module_list;
}
- if (module_list_ptr != NULL)
+ std::unique_lock<std::recursive_mutex> lock;
+ if (module_list_ptr != nullptr)
{
- locker.Lock(module_list_ptr->GetMutex());
+ lock = std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
+
num_modules = module_list_ptr->GetSize();
}
@@ -3352,8 +3391,7 @@ protected:
void
PrintModule (Target *target, Module *module, int indent, Stream &strm)
{
-
- if (module == NULL)
+ if (module == nullptr)
{
strm.PutCString("Null module");
return;
@@ -3369,7 +3407,7 @@ protected:
}
const size_t num_entries = m_options.m_format_array.size();
bool print_space = false;
- for (size_t i=0; i<num_entries; ++i)
+ for (size_t i = 0; i < num_entries; ++i)
{
if (print_space)
strm.PutChar(' ');
@@ -3442,6 +3480,7 @@ protected:
strm.Printf ("%*s", addr_nibble_width + 2, "");
}
break;
+
case 'r':
{
size_t ref_count = 0;
@@ -3499,7 +3538,6 @@ protected:
default:
break;
}
-
}
if (dump_object_name)
{
@@ -3516,22 +3554,22 @@ protected:
OptionDefinition
CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."},
- { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
- { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the triple when listing images."},
- { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."},
- { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)."},
- { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
- { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
- { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
- { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
- { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
- { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file."},
- { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."},
- { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache."},
- { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeNone, "Display the module pointer."},
- { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address."},
+ { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the architecture when listing images."},
+ { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the triple when listing images."},
+ { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."},
+ { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)."},
+ { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the UUID when listing images."},
+ { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
+ { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
+ { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
+ { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
+ { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file."},
+ { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the modification time with optional width of the module."},
+ { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache."},
+ { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the module pointer."},
+ { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
#pragma mark CommandObjectTargetModulesShowUnwind
@@ -3543,7 +3581,6 @@ CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed
{
public:
-
enum
{
eLookupTypeInvalid = -1,
@@ -3557,7 +3594,6 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options(interpreter),
m_type(eLookupTypeInvalid),
@@ -3566,9 +3602,7 @@ public:
{
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -3591,11 +3625,9 @@ public:
}
case 'n':
- {
m_str = option_arg;
m_type = eLookupTypeFunctionOrSymbol;
break;
- }
default:
error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
@@ -3631,21 +3663,19 @@ public:
};
CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target modules show-unwind",
- "Show synthesized unwind instructions for a function.",
- NULL,
- eCommandRequiresTarget |
- eCommandRequiresProcess |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
+ CommandObjectParsed(interpreter,
+ "target modules show-unwind",
+ "Show synthesized unwind instructions for a function.",
+ nullptr,
+ eCommandRequiresTarget |
+ eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_options (interpreter)
{
}
- ~CommandObjectTargetModulesShowUnwind () override
- {
- }
+ ~CommandObjectTargetModulesShowUnwind() override = default;
Options *
GetOptions () override
@@ -3659,11 +3689,11 @@ protected:
{
Target *target = m_exe_ctx.GetTargetPtr();
Process *process = m_exe_ctx.GetProcessPtr();
- ABI *abi = NULL;
+ ABI *abi = nullptr;
if (process)
abi = process->GetABI().get();
- if (process == NULL)
+ if (process == nullptr)
{
result.AppendError ("You must have a process running to use this command.");
result.SetStatus (eReturnStatusFailed);
@@ -3679,7 +3709,7 @@ protected:
}
ThreadSP thread(threads.GetThreadAtIndex(0));
- if (thread.get() == NULL)
+ if (!thread)
{
result.AppendError ("The process must be paused to use this command.");
result.SetStatus (eReturnStatusFailed);
@@ -3726,9 +3756,9 @@ protected:
{
SymbolContext sc;
sc_list.GetContextAtIndex(idx, sc);
- if (sc.symbol == NULL && sc.function == NULL)
+ if (sc.symbol == nullptr && sc.function == nullptr)
continue;
- if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL)
+ if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
continue;
AddressRange range;
if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range))
@@ -3743,37 +3773,36 @@ protected:
start_addr = abi->FixCodeAddress(start_addr);
FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
- if (func_unwinders_sp.get() == NULL)
+ if (!func_unwinders_sp)
continue;
result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
- UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread.get(), -1);
- if (non_callsite_unwind_plan.get())
+ UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
+ if (non_callsite_unwind_plan)
{
result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString());
}
UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
- if (callsite_unwind_plan.get())
+ if (callsite_unwind_plan)
{
result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString());
}
- UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread.get());
- if (fast_unwind_plan.get())
+ UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
+ if (fast_unwind_plan)
{
result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString());
}
result.GetOutputStream().Printf("\n");
- UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread.get(), 0);
+ UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
if (assembly_sp)
{
result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n");
assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf("\n");
}
-
UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
if (ehframe_sp)
@@ -3783,7 +3812,7 @@ protected:
result.GetOutputStream().Printf("\n");
}
- UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread.get(), 0);
+ UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
if (ehframe_augmented_sp)
{
result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
@@ -3845,9 +3874,9 @@ protected:
OptionDefinition
CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."},
- { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."},
+ { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//----------------------------------------------------------------------
@@ -3877,9 +3906,7 @@ public:
OptionParsingStarting();
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -3995,11 +4022,11 @@ public:
};
CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target modules lookup",
- "Look up information within executable and dependent shared library images.",
- NULL,
- eCommandRequiresTarget),
+ CommandObjectParsed(interpreter,
+ "target modules lookup",
+ "Look up information within executable and dependent shared library images.",
+ nullptr,
+ eCommandRequiresTarget),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -4016,9 +4043,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectTargetModulesLookup () override
- {
- }
+ ~CommandObjectTargetModulesLookup() override = default;
Options *
GetOptions () override
@@ -4083,11 +4108,11 @@ public:
case eLookupTypeAddress:
if (m_options.m_addr != LLDB_INVALID_ADDRESS)
{
- if (LookupAddressInModule (m_interpreter,
- result.GetOutputStream(),
- module,
- eSymbolContextEverything | (m_options.m_verbose ? eSymbolContextVariable : 0),
- m_options.m_addr,
+ if (LookupAddressInModule (m_interpreter,
+ result.GetOutputStream(),
+ module,
+ eSymbolContextEverything | (m_options.m_verbose ? static_cast<int>(eSymbolContextVariable) : 0),
+ m_options.m_addr,
m_options.m_offset,
m_options.m_verbose))
{
@@ -4179,7 +4204,7 @@ protected:
DoExecute (Args& command, CommandReturnObject &result) override
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("invalid target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -4216,11 +4241,11 @@ protected:
// Dump all sections for all other modules
const ModuleList &target_modules = target->GetImages();
- Mutex::Locker modules_locker(target_modules.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
const size_t num_modules = target_modules.GetSize();
if (num_modules > 0)
{
- for (i = 0; i<num_modules && syntax_error == false; ++i)
+ for (i = 0; i < num_modules && !syntax_error; ++i)
{
Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
@@ -4243,7 +4268,7 @@ protected:
{
// Dump specified images (by basename or fullpath)
const char *arg_cstr;
- for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
+ for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr && !syntax_error; ++i)
{
ModuleList module_list;
const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
@@ -4281,25 +4306,24 @@ protected:
OptionDefinition
CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."},
- { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup."},
+ { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."},
+ { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup."},
{ LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
/* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
- false, "regex", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
- { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules."},
- { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules."},
- { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)."},
+ false, "regex", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
+ { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules."},
+ { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules."},
+ { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)."},
{ LLDB_OPT_SET_FROM_TO(3,5),
- false, "no-inlines", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."},
- { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."},
- { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules."},
- { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."},
- { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
- { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ false, "no-inlines", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."},
+ { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."},
+ { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules."},
+ { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."},
+ { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose lookup information."},
+ { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
#pragma mark CommandObjectMultiwordImageSearchPaths
//-------------------------------------------------------------------------
@@ -4309,11 +4333,10 @@ CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
{
public:
- CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "target modules search-paths",
- "A set of commands for operating on debugger target image search paths.",
- "target modules search-paths <subcommand> [<subcommand-options>]")
+ CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "target modules search-paths",
+ "Commands for managing module search paths for a target.",
+ "target modules search-paths <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
@@ -4322,13 +4345,9 @@ public:
LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
}
- ~CommandObjectTargetModulesImageSearchPaths() override
- {
- }
+ ~CommandObjectTargetModulesImageSearchPaths() override = default;
};
-
-
#pragma mark CommandObjectTargetModules
//-------------------------------------------------------------------------
@@ -4341,11 +4360,10 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- CommandObjectTargetModules(CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "target modules",
- "A set of commands for accessing information for one or more target modules.",
- "target modules <sub-command> ...")
+ CommandObjectTargetModules(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "target modules",
+ "Commands for accessing information for one or more target modules.",
+ "target modules <sub-command> ...")
{
LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
@@ -4357,9 +4375,7 @@ public:
}
- ~CommandObjectTargetModules() override
- {
- }
+ ~CommandObjectTargetModules() override = default;
private:
//------------------------------------------------------------------
@@ -4368,8 +4384,6 @@ private:
DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
};
-
-
class CommandObjectTargetSymbolsAdd : public CommandObjectParsed
{
public:
@@ -4389,9 +4403,7 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectTargetSymbolsAdd () override
- {
- }
+ ~CommandObjectTargetSymbolsAdd() override = default;
int
HandleArgumentCompletion (Args &input,
@@ -4406,14 +4418,14 @@ public:
std::string completion_str (input.GetArgumentAtIndex(cursor_index));
completion_str.erase (cursor_char_position);
- CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
+ CommandCompletions::eDiskFileCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ nullptr,
+ word_complete,
+ matches);
return matches.GetSize();
}
@@ -4473,7 +4485,7 @@ protected:
// No matches yet, iterate through the module specs to find a UUID value that
// we can match up to an image in our target
const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
- for (size_t i=0; i<num_symfile_module_specs && num_matches == 0; ++i)
+ for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0; ++i)
{
if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec))
{
@@ -4606,8 +4618,8 @@ protected:
const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
-
const size_t argc = args.GetArgumentCount();
+
if (argc == 0)
{
if (uuid_option_set || file_option_set || frame_option_set)
@@ -4682,7 +4694,7 @@ protected:
{
module_spec.GetArchitecture() = target->GetArchitecture();
}
- success |= module_spec.GetFileSpec().Exists();
+ success |= module_spec.GetUUID().IsValid() || module_spec.GetFileSpec().Exists();
}
}
@@ -4738,7 +4750,7 @@ protected:
{
PlatformSP platform_sp (target->GetPlatform());
- for (size_t i=0; i<argc; ++i)
+ for (size_t i = 0; i < argc; ++i)
{
const char *symfile_path = args.GetArgumentAtIndex(i);
if (symfile_path)
@@ -4793,7 +4805,6 @@ protected:
OptionGroupBoolean m_current_frame_option;
};
-
#pragma mark CommandObjectTargetSymbols
//-------------------------------------------------------------------------
@@ -4806,19 +4817,14 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- CommandObjectTargetSymbols(CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "target symbols",
- "A set of commands for adding and managing debug symbol files.",
- "target symbols <sub-command> ...")
+ CommandObjectTargetSymbols(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "target symbols", "Commands for adding and managing debug symbol files.",
+ "target symbols <sub-command> ...")
{
LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));
-
}
- ~CommandObjectTargetSymbols() override
- {
- }
+ ~CommandObjectTargetSymbols() override = default;
private:
//------------------------------------------------------------------
@@ -4827,7 +4833,6 @@ private:
DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
};
-
#pragma mark CommandObjectTargetStopHookAdd
//-------------------------------------------------------------------------
@@ -4839,7 +4844,6 @@ class CommandObjectTargetStopHookAdd :
public IOHandlerDelegateMultiline
{
public:
-
class CommandOptions : public Options
{
public:
@@ -4855,7 +4859,7 @@ public:
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
const OptionDefinition*
GetDefinitions () override
@@ -4875,7 +4879,7 @@ public:
case 'c':
m_class_name = option_arg;
m_sym_ctx_specified = true;
- break;
+ break;
case 'e':
m_line_end = StringConvert::ToUInt32 (option_arg, UINT_MAX, 0, &success);
@@ -4885,7 +4889,7 @@ public:
break;
}
m_sym_ctx_specified = true;
- break;
+ break;
case 'l':
m_line_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
@@ -4895,57 +4899,60 @@ public:
break;
}
m_sym_ctx_specified = true;
- break;
+ break;
case 'i':
m_no_inlines = true;
- break;
+ break;
case 'n':
m_function_name = option_arg;
m_func_name_type_mask |= eFunctionNameTypeAuto;
m_sym_ctx_specified = true;
- break;
+ break;
case 'f':
m_file_name = option_arg;
m_sym_ctx_specified = true;
- break;
+ break;
+
case 's':
m_module_name = option_arg;
m_sym_ctx_specified = true;
- break;
+ break;
+
case 't' :
- {
m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
if (m_thread_id == LLDB_INVALID_THREAD_ID)
error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
m_thread_specified = true;
- }
- break;
+ break;
+
case 'T':
m_thread_name = option_arg;
m_thread_specified = true;
- break;
+ break;
+
case 'q':
m_queue_name = option_arg;
m_thread_specified = true;
break;
+
case 'x':
- {
m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
if (m_thread_id == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
m_thread_specified = true;
- }
- break;
+ break;
+
case 'o':
m_use_one_liner = true;
m_one_liner = option_arg;
- break;
+ break;
+
default:
error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
- break;
+ break;
}
return error;
}
@@ -4973,7 +4980,6 @@ public:
m_one_liner.clear();
}
-
static OptionDefinition g_option_table[];
std::string m_class_name;
@@ -4995,12 +5001,6 @@ public:
std::string m_one_liner;
};
- Options *
- GetOptions () override
- {
- return &m_options;
- }
-
CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"target stop-hook add",
@@ -5011,8 +5011,12 @@ public:
{
}
- ~CommandObjectTargetStopHookAdd () override
+ ~CommandObjectTargetStopHookAdd() override = default;
+
+ Options *
+ GetOptions () override
{
+ return &m_options;
}
protected:
@@ -5106,7 +5110,7 @@ protected:
}
}
- if (specifier_ap.get())
+ if (specifier_ap)
new_hook_sp->SetSpecifier (specifier_ap.release());
// Next see if any of the thread options have been entered:
@@ -5141,10 +5145,10 @@ protected:
else
{
m_stop_hook_sp = new_hook_sp;
- m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt
- *this, // IOHandlerDelegate
- true, // Run IOHandler in async mode
- NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
+ m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ nullptr); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
}
result.SetStatus (eReturnStatusSuccessFinishNoResult);
@@ -5157,6 +5161,7 @@ protected:
return result.Succeeded();
}
+
private:
CommandOptions m_options;
Target::StopHookSP m_stop_hook_sp;
@@ -5165,29 +5170,29 @@ private:
OptionDefinition
CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner,
+ { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner,
"Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
- { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
+ { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
"Set the module within which the stop-hook is to be run."},
- { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
+ { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex,
"The stop hook is run only for the thread whose index matches this argument."},
- { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
+ { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID,
"The stop hook is run only for the thread whose TID matches this argument."},
- { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
+ { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName,
"The stop hook is run only for the thread whose thread name matches this argument."},
- { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
+ { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName,
"The stop hook is run only for threads in the queue whose name is given by this argument."},
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
+ { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
"Specify the source file within which the stop-hook is to be run." },
- { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
+ { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
"Set the start of the line range for which the stop-hook is to be run."},
- { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
+ { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
"Set the end of the line range for which the stop-hook is to be run."},
- { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeClassName,
+ { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeClassName,
"Specify the class within which the stop-hook is to be run." },
- { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
+ { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
"Set the function name within which the stop hook will be run." },
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
#pragma mark CommandObjectTargetStopHookDelete
@@ -5199,7 +5204,6 @@ CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
class CommandObjectTargetStopHookDelete : public CommandObjectParsed
{
public:
-
CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"target stop-hook delete",
@@ -5208,9 +5212,7 @@ public:
{
}
- ~CommandObjectTargetStopHookDelete () override
- {
- }
+ ~CommandObjectTargetStopHookDelete() override = default;
protected:
bool
@@ -5265,6 +5267,7 @@ protected:
return result.Succeeded();
}
};
+
#pragma mark CommandObjectTargetStopHookEnableDisable
//-------------------------------------------------------------------------
@@ -5274,7 +5277,6 @@ protected:
class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
{
public:
-
CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
CommandObjectParsed (interpreter,
name,
@@ -5284,9 +5286,7 @@ public:
{
}
- ~CommandObjectTargetStopHookEnableDisable () override
- {
- }
+ ~CommandObjectTargetStopHookEnableDisable() override = default;
protected:
bool
@@ -5345,7 +5345,6 @@ private:
class CommandObjectTargetStopHookList : public CommandObjectParsed
{
public:
-
CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"target stop-hook list",
@@ -5354,9 +5353,7 @@ public:
{
}
- ~CommandObjectTargetStopHookList () override
- {
- }
+ ~CommandObjectTargetStopHookList() override = default;
protected:
bool
@@ -5391,6 +5388,7 @@ protected:
};
#pragma mark CommandObjectMultiwordTargetStopHooks
+
//-------------------------------------------------------------------------
// CommandObjectMultiwordTargetStopHooks
//-------------------------------------------------------------------------
@@ -5398,12 +5396,10 @@ protected:
class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
{
public:
-
- CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "target stop-hook",
- "A set of commands for operating on debugger target stop-hooks.",
- "target stop-hook <subcommand> [<subcommand-options>]")
+ CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "target stop-hook",
+ "Commands for operating on debugger target stop-hooks.",
+ "target stop-hook <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
@@ -5420,26 +5416,19 @@ public:
LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
}
- ~CommandObjectMultiwordTargetStopHooks() override
- {
- }
+ ~CommandObjectMultiwordTargetStopHooks() override = default;
};
-
-
#pragma mark CommandObjectMultiwordTarget
//-------------------------------------------------------------------------
// CommandObjectMultiwordTarget
//-------------------------------------------------------------------------
-CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "target",
- "A set of commands for operating on debugger targets.",
- "target <subcommand> [<subcommand-options>]")
+CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "target", "Commands for operating on debugger targets.",
+ "target <subcommand> [<subcommand-options>]")
{
-
LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
@@ -5450,8 +5439,4 @@ CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &
LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
}
-CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
-{
-}
-
-
+CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index e932c9d96c35..9e4bffdeb6a5 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -37,11 +37,9 @@
#include "lldb/Target/ThreadPlanStepRange.h"
#include "lldb/Target/ThreadPlanStepInRange.h"
-
using namespace lldb;
using namespace lldb_private;
-
//-------------------------------------------------------------------------
// CommandObjectThreadBacktrace
//-------------------------------------------------------------------------
@@ -58,7 +56,7 @@ public:
{
}
- ~CommandObjectIterateOverThreads() override {}
+ ~CommandObjectIterateOverThreads() override = default;
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -68,34 +66,33 @@ public:
if (command.GetArgumentCount() == 0)
{
Thread *thread = m_exe_ctx.GetThreadPtr();
- if (!HandleOneThread (*thread, result))
+ if (!HandleOneThread (thread->GetID(), result))
return false;
+ return result.Succeeded();
}
- else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
+
+ // Use tids instead of ThreadSPs to prevent deadlocking problems which result from JIT-ing
+ // code while iterating over the (locked) ThreadSP list.
+ std::vector<lldb::tid_t> tids;
+
+ if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
{
Process *process = m_exe_ctx.GetProcessPtr();
- uint32_t idx = 0;
- for (ThreadSP thread_sp : process->Threads())
- {
- if (idx != 0 && m_add_return)
- result.AppendMessage("");
- if (!HandleOneThread(*(thread_sp.get()), result))
- return false;
- ++idx;
- }
+ for (ThreadSP thread_sp : process->Threads())
+ tids.push_back(thread_sp->GetID());
}
else
{
const size_t num_args = command.GetArgumentCount();
Process *process = m_exe_ctx.GetProcessPtr();
- Mutex::Locker locker (process->GetThreadList().GetMutex());
- std::vector<ThreadSP> thread_sps;
+
+ std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex());
for (size_t i = 0; i < num_args; i++)
{
bool success;
-
+
uint32_t thread_idx = StringConvert::ToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
if (!success)
{
@@ -103,32 +100,35 @@ public:
result.SetStatus (eReturnStatusFailed);
return false;
}
-
- thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
-
- if (!thread_sps[i])
+
+ ThreadSP thread = process->GetThreadList().FindThreadByIndexID(thread_idx);
+
+ if (!thread)
{
result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
result.SetStatus (eReturnStatusFailed);
return false;
}
-
- }
-
- for (uint32_t i = 0; i < num_args; i++)
- {
- if (!HandleOneThread (*(thread_sps[i].get()), result))
- return false;
- if (i < num_args - 1 && m_add_return)
- result.AppendMessage("");
+ tids.push_back(thread->GetID());
}
}
+
+ uint32_t idx = 0;
+ for (const lldb::tid_t &tid : tids)
+ {
+ if (idx != 0 && m_add_return)
+ result.AppendMessage("");
+
+ if (!HandleOneThread (tid, result))
+ return false;
+
+ ++idx;
+ }
return result.Succeeded();
}
protected:
-
// Override this to do whatever you need to do for one thread.
//
// If you return false, the iteration will stop, otherwise it will proceed.
@@ -137,11 +137,10 @@ protected:
// If m_add_return is true, a blank line will be inserted between each of the listings (except the last one.)
virtual bool
- HandleOneThread (Thread &thread, CommandReturnObject &result) = 0;
+ HandleOneThread (lldb::tid_t, CommandReturnObject &result) = 0;
ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
bool m_add_return = true;
-
};
//-------------------------------------------------------------------------
@@ -151,11 +150,9 @@ protected:
class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads
{
public:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options(interpreter)
{
@@ -163,9 +160,7 @@ public:
OptionParsingStarting ();
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -194,6 +189,7 @@ public:
if (!success)
error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
}
+ break;
case 'e':
{
bool success;
@@ -205,7 +201,6 @@ public:
default:
error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
break;
-
}
return error;
}
@@ -234,23 +229,18 @@ public:
bool m_extended_backtrace;
};
- CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
- CommandObjectIterateOverThreads (interpreter,
- "thread backtrace",
- "Show the stack for one or more threads. If no threads are specified, show the currently selected thread. Use the thread-index \"all\" to see all threads.",
- NULL,
- eCommandRequiresProcess |
- eCommandRequiresThread |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_options(interpreter)
+ CommandObjectThreadBacktrace(CommandInterpreter &interpreter)
+ : CommandObjectIterateOverThreads(
+ interpreter, "thread backtrace", "Show thread call stacks. Defaults to the current thread, thread "
+ "indexes can be specified as arguments. Use the thread-index \"all\" "
+ "to see all threads.",
+ nullptr, eCommandRequiresProcess | eCommandRequiresThread | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options(interpreter)
{
}
- ~CommandObjectThreadBacktrace() override
- {
- }
+ ~CommandObjectThreadBacktrace() override = default;
Options *
GetOptions () override
@@ -286,25 +276,35 @@ protected:
}
bool
- HandleOneThread (Thread &thread, CommandReturnObject &result) override
+ HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override
{
+ ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
+ if (!thread_sp)
+ {
+ result.AppendErrorWithFormat ("thread disappeared while computing backtraces: 0x%" PRIx64 "\n", tid);
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ Thread *thread = thread_sp.get();
+
Stream &strm = result.GetOutputStream();
// Don't show source context when doing backtraces.
const uint32_t num_frames_with_source = 0;
- if (!thread.GetStatus (strm,
- m_options.m_start,
- m_options.m_count,
- num_frames_with_source))
+ if (!thread->GetStatus (strm,
+ m_options.m_start,
+ m_options.m_count,
+ num_frames_with_source))
{
- result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread.GetIndexID());
+ result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread->GetIndexID());
result.SetStatus (eReturnStatusFailed);
return false;
}
if (m_options.m_extended_backtrace)
{
- DoExtendedBacktrace (&thread, result);
+ DoExtendedBacktrace (thread, result);
}
return true;
@@ -316,10 +316,10 @@ protected:
OptionDefinition
CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
-{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
-{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
+{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
+{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
enum StepScope
@@ -331,11 +331,9 @@ enum StepScope
class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
{
public:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
@@ -343,9 +341,7 @@ public:
OptionParsingStarting ();
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -382,19 +378,16 @@ public:
break;
case 'c':
- {
- m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
- if (m_step_count == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
- break;
- }
+ m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
+ if (m_step_count == UINT32_MAX)
+ error.SetErrorStringWithFormat ("invalid step count '%s'", option_arg);
break;
+
case 'C':
- {
- m_class_name.clear();
- m_class_name.assign(option_arg);
- }
+ m_class_name.clear();
+ m_class_name.assign(option_arg);
break;
+
case 'm':
{
OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
@@ -402,24 +395,35 @@ public:
}
break;
- case 'r':
+ case 'e':
{
- m_avoid_regexp.clear();
- m_avoid_regexp.assign(option_arg);
+ if (strcmp(option_arg, "block") == 0)
+ {
+ m_end_line_is_block_end = 1;
+ break;
+ }
+ uint32_t tmp_end_line = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
+ if (tmp_end_line == UINT32_MAX)
+ error.SetErrorStringWithFormat ("invalid end line number '%s'", option_arg);
+ else
+ m_end_line = tmp_end_line;
+ break;
}
break;
- case 't':
- {
- m_step_in_target.clear();
- m_step_in_target.assign(option_arg);
+ case 'r':
+ m_avoid_regexp.clear();
+ m_avoid_regexp.assign(option_arg);
+ break;
- }
+ case 't':
+ m_step_in_target.clear();
+ m_step_in_target.assign(option_arg);
break;
+
default:
error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
break;
-
}
return error;
}
@@ -433,13 +437,15 @@ public:
// Check if we are in Non-Stop mode
lldb::TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
- if (target_sp.get() != nullptr && target_sp->GetNonStopModeEnabled())
+ if (target_sp && target_sp->GetNonStopModeEnabled())
m_run_mode = eOnlyThisThread;
m_avoid_regexp.clear();
m_step_in_target.clear();
m_class_name.clear();
m_step_count = 1;
+ m_end_line = LLDB_INVALID_LINE_NUMBER;
+ m_end_line_is_block_end = false;
}
const OptionDefinition*
@@ -460,6 +466,8 @@ public:
std::string m_step_in_target;
std::string m_class_name;
uint32_t m_step_count;
+ uint32_t m_end_line;
+ bool m_end_line_is_block_end;
};
CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
@@ -492,9 +500,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectThreadStepWithTypeAndScope () override
- {
- }
+ ~CommandObjectThreadStepWithTypeAndScope() override = default;
Options *
GetOptions () override
@@ -510,12 +516,13 @@ protected:
bool synchronous_execution = m_interpreter.GetSynchronous();
const uint32_t num_threads = process->GetThreadList().GetSize();
- Thread *thread = NULL;
+ Thread *thread = nullptr;
if (command.GetArgumentCount() == 0)
{
- thread = process->GetThreadList().GetSelectedThread().get();
- if (thread == NULL)
+ thread = GetDefaultThread();
+
+ if (thread == nullptr)
{
result.AppendError ("no selected thread in process");
result.SetStatus (eReturnStatusFailed);
@@ -533,7 +540,7 @@ protected:
return false;
}
thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
- if (thread == NULL)
+ if (thread == nullptr)
{
result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
step_thread_idx, num_threads);
@@ -558,6 +565,14 @@ protected:
}
}
+ if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER
+ && m_step_type != eStepTypeInto)
+ {
+ result.AppendErrorWithFormat("end line option is only valid for step into");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
const bool abort_other_plans = false;
const lldb::RunMode stop_other_threads = m_options.m_run_mode;
@@ -567,12 +582,7 @@ protected:
if (m_options.m_run_mode == eAllThreads)
bool_stop_other_threads = false;
else if (m_options.m_run_mode == eOnlyDuringStepping)
- {
- if (m_step_type == eStepTypeOut || m_step_type == eStepTypeScripted)
- bool_stop_other_threads = false;
- else
- bool_stop_other_threads = true;
- }
+ bool_stop_other_threads = (m_step_type != eStepTypeOut && m_step_type != eStepTypeScripted);
else
bool_stop_other_threads = true;
@@ -585,13 +595,54 @@ protected:
if (frame->HasDebugInformation ())
{
+ AddressRange range;
+ SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything);
+ if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER)
+ {
+ Error error;
+ if (!sc.GetAddressRangeFromHereToEndLine(m_options.m_end_line, range, error))
+ {
+ result.AppendErrorWithFormat("invalid end-line option: %s.", error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ else if (m_options.m_end_line_is_block_end)
+ {
+ Error error;
+ Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
+ if (!block)
+ {
+ result.AppendErrorWithFormat("Could not find the current block.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ AddressRange block_range;
+ Address pc_address = frame->GetFrameCodeAddress();
+ block->GetRangeContainingAddress(pc_address, block_range);
+ if (!block_range.GetBaseAddress().IsValid())
+ {
+ result.AppendErrorWithFormat("Could not find the current block address.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ lldb::addr_t pc_offset_in_block = pc_address.GetFileAddress() - block_range.GetBaseAddress().GetFileAddress();
+ lldb::addr_t range_length = block_range.GetByteSize() - pc_offset_in_block;
+ range = AddressRange(pc_address, range_length);
+ }
+ else
+ {
+ range = sc.line_entry.range;
+ }
+
new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
- frame->GetSymbolContext(eSymbolContextEverything).line_entry,
- frame->GetSymbolContext(eSymbolContextEverything),
- m_options.m_step_in_target.c_str(),
- stop_other_threads,
- m_options.m_step_in_avoid_no_debug,
- m_options.m_step_out_avoid_no_debug);
+ range,
+ frame->GetSymbolContext(eSymbolContextEverything),
+ m_options.m_step_in_target.c_str(),
+ stop_other_threads,
+ m_options.m_step_in_avoid_no_debug,
+ m_options.m_step_out_avoid_no_debug);
if (new_plan_sp && !m_options.m_avoid_regexp.empty())
{
@@ -601,7 +652,6 @@ protected:
}
else
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
-
}
else if (m_step_type == eStepTypeOver)
{
@@ -617,7 +667,6 @@ protected:
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
abort_other_plans,
bool_stop_other_threads);
-
}
else if (m_step_type == eStepTypeTrace)
{
@@ -629,14 +678,14 @@ protected:
}
else if (m_step_type == eStepTypeOut)
{
- new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
- NULL,
- false,
- bool_stop_other_threads,
- eVoteYes,
- eVoteNoOpinion,
- thread->GetSelectedFrameIndex(),
- m_options.m_step_out_avoid_no_debug);
+ new_plan_sp = thread->QueueThreadPlanForStepOut(abort_other_plans,
+ nullptr,
+ false,
+ bool_stop_other_threads,
+ eVoteYes,
+ eVoteNoOpinion,
+ thread->GetSelectedFrameIndex(),
+ m_options.m_step_out_avoid_no_debug);
}
else if (m_step_type == eStepTypeScripted)
{
@@ -667,7 +716,6 @@ protected:
}
}
-
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
const uint32_t iohandler_id = process->GetIOHandlerID();
@@ -719,7 +767,7 @@ g_tri_running_mode[] =
{ eOnlyThisThread, "this-thread", "Run only this thread"},
{ eAllThreads, "all-threads", "Run all threads"},
{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
-{ 0, NULL, NULL }
+{ 0, nullptr, nullptr }
};
static OptionEnumValueElement
@@ -727,23 +775,25 @@ g_duo_running_mode[] =
{
{ eOnlyThisThread, "this-thread", "Run only this thread"},
{ eAllThreads, "all-threads", "Run all threads"},
-{ 0, NULL, NULL }
+{ 0, nullptr, nullptr }
};
OptionDefinition
CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."},
-{ LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."},
-{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."},
-{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, NULL, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
-{ LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},
-{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
-{ LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step."},
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."},
+{ LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."},
+{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."},
+{ LLDB_OPT_SET_1, false, "end-linenumber", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeLineNum, "The line at which to stop stepping - defaults to the next line and only supported for step-in and step-over."
+ " You can also pass the string 'block' to step to the end of the current block."
+ " This is particularly useful in conjunction with --step-target to step through a complex calling sequence."},
+{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, nullptr, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
+{ LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},
+{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
+{ LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step."},
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
//-------------------------------------------------------------------------
// CommandObjectThreadContinue
//-------------------------------------------------------------------------
@@ -751,16 +801,12 @@ CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
class CommandObjectThreadContinue : public CommandObjectParsed
{
public:
-
- CommandObjectThreadContinue (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "thread continue",
- "Continue execution of one or more threads in an active process.",
- NULL,
- eCommandRequiresThread |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused)
+ CommandObjectThreadContinue(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "thread continue", "Continue execution of the current target process. One "
+ "or more threads may be specified, by default all "
+ "threads continue.",
+ nullptr, eCommandRequiresThread | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
{
CommandArgumentEntry arg;
CommandArgumentData thread_idx_arg;
@@ -776,17 +822,14 @@ public:
m_arguments.push_back (arg);
}
-
- ~CommandObjectThreadContinue () override
- {
- }
+ ~CommandObjectThreadContinue() override = default;
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
bool synchronous_execution = m_interpreter.GetSynchronous ();
- if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
+ if (!m_interpreter.GetDebugger().GetSelectedTarget())
{
result.AppendError ("invalid target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -794,7 +837,7 @@ public:
}
Process *process = m_exe_ctx.GetProcessPtr();
- if (process == NULL)
+ if (process == nullptr)
{
result.AppendError ("no process exists. Cannot continue");
result.SetStatus (eReturnStatusFailed);
@@ -810,10 +853,10 @@ public:
// These two lines appear at the beginning of both blocks in
// this if..else, but that is because we need to release the
// lock before calling process->Resume below.
- Mutex::Locker locker (process->GetThreadList().GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex());
const uint32_t num_threads = process->GetThreadList().GetSize();
std::vector<Thread *> resume_threads;
- for (uint32_t i=0; i<argc; ++i)
+ for (uint32_t i = 0; i < argc; ++i)
{
bool success;
const int base = 0;
@@ -854,7 +897,7 @@ public:
else
result.AppendMessageWithFormat ("Resuming threads: ");
- for (uint32_t idx=0; idx<num_threads; ++idx)
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
{
Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
@@ -862,7 +905,7 @@ public:
if (this_thread_pos != resume_threads.end())
{
resume_threads.erase(this_thread_pos);
- if (resume_threads.size() > 0)
+ if (!resume_threads.empty())
result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
else
result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
@@ -883,17 +926,17 @@ public:
// These two lines appear at the beginning of both blocks in
// this if..else, but that is because we need to release the
// lock before calling process->Resume below.
- Mutex::Locker locker (process->GetThreadList().GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex());
const uint32_t num_threads = process->GetThreadList().GetSize();
- Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
- if (current_thread == NULL)
+ Thread *current_thread = GetDefaultThread();
+ if (current_thread == nullptr)
{
result.AppendError ("the process doesn't have a current thread");
result.SetStatus (eReturnStatusFailed);
return false;
}
// Set the actions that the threads should each take when resuming
- for (uint32_t idx=0; idx<num_threads; ++idx)
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
{
Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
if (thread == current_thread)
@@ -909,7 +952,6 @@ public:
}
}
-
StreamString stream;
Error error;
if (synchronous_execution)
@@ -950,7 +992,6 @@ public:
return result.Succeeded();
}
-
};
//-------------------------------------------------------------------------
@@ -960,7 +1001,6 @@ public:
class CommandObjectThreadUntil : public CommandObjectParsed
{
public:
-
class CommandOptions : public Options
{
public:
@@ -976,9 +1016,7 @@ public:
OptionParsingStarting ();
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -997,23 +1035,19 @@ public:
}
break;
case 't':
- {
m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32);
if (m_thread_idx == LLDB_INVALID_INDEX32)
{
error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
}
- }
- break;
+ break;
case 'f':
- {
m_frame_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
if (m_frame_idx == LLDB_INVALID_FRAME_ID)
{
error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
}
- }
- break;
+ break;
case 'm':
{
OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
@@ -1031,7 +1065,6 @@ public:
default:
error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
break;
-
}
return error;
}
@@ -1062,16 +1095,13 @@ public:
// Instance variables to hold the values for command options.
};
- CommandObjectThreadUntil (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "thread until",
- "Run the current or specified thread until it reaches a given line number or address or leaves the current function.",
- NULL,
- eCommandRequiresThread |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_options (interpreter)
+ CommandObjectThreadUntil(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "thread until", "Continue until a line number or address is reached by the "
+ "current or specified thread. Stops when returning from "
+ "the current function as a safety measure.",
+ nullptr, eCommandRequiresThread | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options(interpreter)
{
CommandArgumentEntry arg;
CommandArgumentData line_num_arg;
@@ -1087,10 +1117,7 @@ public:
m_arguments.push_back (arg);
}
-
- ~CommandObjectThreadUntil () override
- {
- }
+ ~CommandObjectThreadUntil() override = default;
Options *
GetOptions () override
@@ -1105,7 +1132,7 @@ protected:
bool synchronous_execution = m_interpreter.GetSynchronous ();
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("invalid target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -1113,15 +1140,14 @@ protected:
}
Process *process = m_exe_ctx.GetProcessPtr();
- if (process == NULL)
+ if (process == nullptr)
{
result.AppendError ("need a valid process to step");
result.SetStatus (eReturnStatusFailed);
-
}
else
{
- Thread *thread = NULL;
+ Thread *thread = nullptr;
std::vector<uint32_t> line_numbers;
if (command.GetArgumentCount() >= 1)
@@ -1148,17 +1174,16 @@ protected:
return false;
}
-
if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
{
- thread = process->GetThreadList().GetSelectedThread().get();
+ thread = GetDefaultThread();
}
else
{
thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
}
- if (thread == NULL)
+ if (thread == nullptr)
{
const uint32_t num_threads = process->GetThreadList().GetSize();
result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
@@ -1171,9 +1196,8 @@ protected:
const bool abort_other_plans = false;
StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
- if (frame == NULL)
+ if (frame == nullptr)
{
-
result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
m_options.m_frame_idx,
m_options.m_thread_idx);
@@ -1187,11 +1211,11 @@ protected:
{
// Finally we got here... Translate the given line number to a bunch of addresses:
SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
- LineTable *line_table = NULL;
+ LineTable *line_table = nullptr;
if (sc.comp_unit)
line_table = sc.comp_unit->GetLineTable();
- if (line_table == NULL)
+ if (line_table == nullptr)
{
result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
m_options.m_frame_idx, m_options.m_thread_idx);
@@ -1246,7 +1270,7 @@ protected:
all_in_function = false;
}
- if (address_list.size() == 0)
+ if (address_list.empty())
{
if (all_in_function)
result.AppendErrorWithFormat ("No line entries matching until target.\n");
@@ -1275,11 +1299,8 @@ protected:
m_options.m_thread_idx);
result.SetStatus (eReturnStatusFailed);
return false;
-
}
-
-
process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
StreamString stream;
@@ -1317,20 +1338,18 @@ protected:
}
CommandOptions m_options;
-
};
OptionDefinition
CommandObjectThreadUntil::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
-{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
-{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, NULL, g_duo_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one"},
-{ LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times."},
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
+{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
+{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, nullptr, g_duo_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one"},
+{ LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times."},
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
//-------------------------------------------------------------------------
// CommandObjectThreadSelect
//-------------------------------------------------------------------------
@@ -1338,16 +1357,10 @@ CommandObjectThreadUntil::CommandOptions::g_option_table[] =
class CommandObjectThreadSelect : public CommandObjectParsed
{
public:
-
- CommandObjectThreadSelect (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "thread select",
- "Select a thread as the currently active thread.",
- NULL,
- eCommandRequiresProcess |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused )
+ CommandObjectThreadSelect(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "thread select", "Change the currently selected thread.", nullptr,
+ eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused)
{
CommandArgumentEntry arg;
CommandArgumentData thread_idx_arg;
@@ -1363,17 +1376,14 @@ public:
m_arguments.push_back (arg);
}
-
- ~CommandObjectThreadSelect () override
- {
- }
+ ~CommandObjectThreadSelect() override = default;
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
{
Process *process = m_exe_ctx.GetProcessPtr();
- if (process == NULL)
+ if (process == nullptr)
{
result.AppendError ("no process");
result.SetStatus (eReturnStatusFailed);
@@ -1389,7 +1399,7 @@ protected:
uint32_t index_id = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0);
Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
- if (new_thread == NULL)
+ if (new_thread == nullptr)
{
result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
result.SetStatus (eReturnStatusFailed);
@@ -1401,10 +1411,8 @@ protected:
return result.Succeeded();
}
-
};
-
//-------------------------------------------------------------------------
// CommandObjectThreadList
//-------------------------------------------------------------------------
@@ -1412,23 +1420,15 @@ protected:
class CommandObjectThreadList : public CommandObjectParsed
{
public:
-
-
- CommandObjectThreadList (CommandInterpreter &interpreter):
- CommandObjectParsed (interpreter,
- "thread list",
- "Show a summary of all current threads in a process.",
- "thread list",
- eCommandRequiresProcess |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused )
+ CommandObjectThreadList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "thread list",
+ "Show a summary of each thread in the current target process.", "thread list",
+ eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused)
{
}
- ~CommandObjectThreadList() override
- {
- }
+ ~CommandObjectThreadList() override = default;
protected:
bool
@@ -1458,31 +1458,17 @@ protected:
class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
{
public:
-
- CommandObjectThreadInfo (CommandInterpreter &interpreter) :
- CommandObjectIterateOverThreads (interpreter,
- "thread info",
- "Show an extended summary of information about thread(s) in a process.",
- "thread info",
- eCommandRequiresProcess |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused),
- m_options (interpreter)
- {
- m_add_return = false;
- }
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
OptionParsingStarting ();
}
+ ~CommandOptions() override = default;
+
void
OptionParsingStarting () override
{
@@ -1490,10 +1476,6 @@ public:
m_json_stopinfo = false;
}
- ~CommandOptions () override
- {
- }
-
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -1512,7 +1494,6 @@ public:
default:
return Error("invalid short option character '%c'", short_option);
-
}
return error;
}
@@ -1529,23 +1510,42 @@ public:
static OptionDefinition g_option_table[];
};
- Options *
- GetOptions () override
+ CommandObjectThreadInfo(CommandInterpreter &interpreter)
+ : CommandObjectIterateOverThreads(
+ interpreter, "thread info",
+ "Show an extended summary of one or more threads. Defaults to the current thread.", "thread info",
+ eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
+ m_options(interpreter)
{
- return &m_options;
+ m_add_return = false;
}
- ~CommandObjectThreadInfo () override
+ ~CommandObjectThreadInfo() override = default;
+
+ Options *
+ GetOptions () override
{
+ return &m_options;
}
bool
- HandleOneThread (Thread &thread, CommandReturnObject &result) override
+ HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override
{
+ ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
+ if (!thread_sp)
+ {
+ result.AppendErrorWithFormat ("thread no longer exists: 0x%" PRIx64 "\n", tid);
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ Thread *thread = thread_sp.get();
+
Stream &strm = result.GetOutputStream();
- if (!thread.GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
+ if (!thread->GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
{
- result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread.GetIndexID());
+ result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread->GetIndexID());
result.SetStatus (eReturnStatusFailed);
return false;
}
@@ -1553,19 +1553,17 @@ public:
}
CommandOptions m_options;
-
};
OptionDefinition
CommandObjectThreadInfo::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the thread info in JSON format."},
- { LLDB_OPT_SET_ALL, false, "stop-info",'s', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the extended stop info in JSON format."},
+ { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the thread info in JSON format."},
+ { LLDB_OPT_SET_ALL, false, "stop-info",'s', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the extended stop info in JSON format."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
//-------------------------------------------------------------------------
// CommandObjectThreadReturn
//-------------------------------------------------------------------------
@@ -1576,7 +1574,6 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_from_expression (false)
@@ -1585,9 +1582,7 @@ public:
OptionParsingStarting ();
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -1612,7 +1607,6 @@ public:
default:
error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
break;
-
}
return error;
}
@@ -1638,23 +1632,14 @@ public:
// Instance variables to hold the values for command options.
};
- Options *
- GetOptions () override
- {
- return &m_options;
- }
-
- CommandObjectThreadReturn (CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "thread return",
- "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
- " or with the -x option from the innermost function evaluation.",
- "thread return",
- eCommandRequiresFrame |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_options (interpreter)
+ CommandObjectThreadReturn(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "thread return",
+ "Prematurely return from a stack frame, short-circuiting execution of newer frames "
+ "and optionally yielding a specified value. Defaults to the exiting the current stack "
+ "frame.",
+ "thread return", eCommandRequiresFrame | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options(interpreter)
{
CommandArgumentEntry arg;
CommandArgumentData expression_arg;
@@ -1668,16 +1653,17 @@ public:
// Push the data for the first argument into the m_arguments vector.
m_arguments.push_back (arg);
-
-
}
-
- ~CommandObjectThreadReturn() override
+
+ ~CommandObjectThreadReturn() override = default;
+
+ Options *
+ GetOptions() override
{
+ return &m_options;
}
-
-protected:
+protected:
bool
DoExecute (const char *command, CommandReturnObject &result) override
{
@@ -1746,7 +1732,6 @@ protected:
result.AppendErrorWithFormat("Unknown error evaluating result expression.");
result.SetStatus (eReturnStatusFailed);
return false;
-
}
}
@@ -1766,13 +1751,13 @@ protected:
}
CommandOptions m_options;
-
};
+
OptionDefinition
CommandObjectThreadReturn::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -1785,13 +1770,14 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
OptionParsingStarting ();
}
+ ~CommandOptions() override = default;
+
void
OptionParsingStarting () override
{
@@ -1802,10 +1788,6 @@ public:
m_force = false;
}
- ~CommandOptions () override
- {
- }
-
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -1839,10 +1821,8 @@ public:
case 'r':
m_force = true;
break;
-
default:
return Error("invalid short option character '%c'", short_option);
-
}
return error;
}
@@ -1862,12 +1842,6 @@ public:
static OptionDefinition g_option_table[];
};
- Options *
- GetOptions () override
- {
- return &m_options;
- }
-
CommandObjectThreadJump (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"thread jump",
@@ -1881,12 +1855,15 @@ public:
{
}
- ~CommandObjectThreadJump() override
+ ~CommandObjectThreadJump() override = default;
+
+ Options *
+ GetOptions() override
{
+ return &m_options;
}
protected:
-
bool DoExecute (Args& args, CommandReturnObject &result) override
{
RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
@@ -1953,44 +1930,43 @@ protected:
CommandOptions m_options;
};
+
OptionDefinition
CommandObjectThreadJump::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
+ { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
"Specifies the source file to jump to."},
- { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
+ { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
"Specifies the line number to jump to."},
- { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset,
+ { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset,
"Jumps by a relative line offset from the current line."},
- { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
+ { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression,
"Jumps to a specific address."},
{ LLDB_OPT_SET_1|
LLDB_OPT_SET_2|
- LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."},
+ LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,"Allows the PC to leave the current function."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
// Next are the subcommands of CommandObjectMultiwordThreadPlan
//-------------------------------------------------------------------------
-
//-------------------------------------------------------------------------
// CommandObjectThreadPlanList
//-------------------------------------------------------------------------
+
class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
{
public:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options(interpreter)
{
@@ -1998,9 +1974,7 @@ public:
OptionParsingStarting ();
}
- ~CommandOptions () override
- {
- }
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -2011,19 +1985,14 @@ public:
switch (short_option)
{
case 'i':
- {
m_internal = true;
- }
- break;
+ break;
case 'v':
- {
m_verbose = true;
- }
- break;
+ break;
default:
error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
break;
-
}
return error;
}
@@ -2050,24 +2019,18 @@ public:
bool m_internal;
};
- CommandObjectThreadPlanList (CommandInterpreter &interpreter) :
- CommandObjectIterateOverThreads (interpreter,
- "thread plan list",
- "Show thread plans for one or more threads. If no threads are specified, show the "
- "currently selected thread. Use the thread-index \"all\" to see all threads.",
- NULL,
- eCommandRequiresProcess |
- eCommandRequiresThread |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_options(interpreter)
+ CommandObjectThreadPlanList(CommandInterpreter &interpreter)
+ : CommandObjectIterateOverThreads(
+ interpreter, "thread plan list",
+ "Show thread plans for one or more threads. If no threads are specified, show the "
+ "current thread. Use the thread-index \"all\" to see all threads.",
+ nullptr, eCommandRequiresProcess | eCommandRequiresThread | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options(interpreter)
{
}
- ~CommandObjectThreadPlanList () override
- {
- }
+ ~CommandObjectThreadPlanList() override = default;
Options *
GetOptions () override
@@ -2077,42 +2040,48 @@ public:
protected:
bool
- HandleOneThread (Thread &thread, CommandReturnObject &result) override
+ HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override
{
+ ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
+ if (!thread_sp)
+ {
+ result.AppendErrorWithFormat ("thread no longer exists: 0x%" PRIx64 "\n", tid);
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ Thread *thread = thread_sp.get();
+
Stream &strm = result.GetOutputStream();
DescriptionLevel desc_level = eDescriptionLevelFull;
if (m_options.m_verbose)
desc_level = eDescriptionLevelVerbose;
- thread.DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
+ thread->DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
return true;
}
+
CommandOptions m_options;
};
OptionDefinition
CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display more information about the thread plans"},
-{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display internal as well as user thread plans"},
-{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display more information about the thread plans"},
+{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display internal as well as user thread plans"},
+{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
class CommandObjectThreadPlanDiscard : public CommandObjectParsed
{
public:
- CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "thread plan discard",
- "Discards thread plans up to and including the plan passed as the command argument."
- "Only user visible plans can be discarded, use the index from \"thread plan list\""
- " without the \"-i\" argument.",
- NULL,
- eCommandRequiresProcess |
- eCommandRequiresThread |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused )
+ CommandObjectThreadPlanDiscard(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "thread plan discard",
+ "Discards thread plans up to and including the specified index (see 'thread plan list'.) "
+ "Only user visible plans can be discarded.",
+ nullptr, eCommandRequiresProcess | eCommandRequiresThread | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
{
CommandArgumentEntry arg;
CommandArgumentData plan_index_arg;
@@ -2128,7 +2097,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectThreadPlanDiscard () override {}
+ ~CommandObjectThreadPlanDiscard() override = default;
bool
DoExecute (Args& args, CommandReturnObject &result) override
@@ -2181,30 +2150,25 @@ public:
class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
{
public:
- CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "plan",
- "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.",
- "thread plan <subcommand> [<subcommand objects]")
+ CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "plan", "Commands for managing thread plans that control execution.",
+ "thread plan <subcommand> [<subcommand objects]")
{
LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter)));
LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter)));
}
- ~CommandObjectMultiwordThreadPlan () override {}
-
-
+ ~CommandObjectMultiwordThreadPlan() override = default;
};
//-------------------------------------------------------------------------
// CommandObjectMultiwordThread
//-------------------------------------------------------------------------
-CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "thread",
- "A set of commands for operating on one or more threads within a running process.",
- "thread <subcommand> [<subcommand-options>]")
+CommandObjectMultiwordThread::CommandObjectMultiwordThread(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "thread",
+ "Commands for operating on one or more threads in the current process.",
+ "thread <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
@@ -2214,59 +2178,47 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &
LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter)));
- LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
- interpreter,
- "thread step-in",
- "Source level single step in specified thread (current thread, if none specified).",
- NULL,
- eStepTypeInto,
- eStepScopeSource)));
-
- LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
- interpreter,
- "thread step-out",
- "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
- NULL,
- eStepTypeOut,
- eStepScopeSource)));
-
- LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
- interpreter,
- "thread step-over",
- "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
- NULL,
- eStepTypeOver,
- eStepScopeSource)));
-
- LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
- interpreter,
- "thread step-inst",
- "Single step one instruction in specified thread (current thread, if none specified).",
- NULL,
- eStepTypeTrace,
- eStepScopeInstruction)));
-
- LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
- interpreter,
- "thread step-inst-over",
- "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
- NULL,
- eStepTypeTraceOver,
- eStepScopeInstruction)));
+ LoadSubCommand("step-in",
+ CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
+ interpreter, "thread step-in",
+ "Source level single step, stepping into calls. Defaults to current thread unless specified.",
+ nullptr, eStepTypeInto, eStepScopeSource)));
+
+ LoadSubCommand("step-out",
+ CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
+ interpreter, "thread step-out", "Finish executing the current stack frame and stop after "
+ "returning. Defaults to current thread unless specified.",
+ nullptr, eStepTypeOut, eStepScopeSource)));
+
+ LoadSubCommand("step-over",
+ CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
+ interpreter, "thread step-over",
+ "Source level single step, stepping over calls. Defaults to current thread unless specified.",
+ nullptr, eStepTypeOver, eStepScopeSource)));
+
+ LoadSubCommand(
+ "step-inst",
+ CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
+ interpreter, "thread step-inst",
+ "Instruction level single step, stepping into calls. Defaults to current thread unless specified.",
+ nullptr, eStepTypeTrace, eStepScopeInstruction)));
+
+ LoadSubCommand(
+ "step-inst-over",
+ CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
+ interpreter, "thread step-inst-over",
+ "Instruction level single step, stepping over calls. Defaults to current thread unless specified.",
+ nullptr, eStepTypeTraceOver, eStepScopeInstruction)));
LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
interpreter,
"thread step-scripted",
"Step as instructed by the script class passed in the -C option.",
- NULL,
+ nullptr,
eStepTypeScripted,
eStepScopeSource)));
LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter)));
}
-CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
-{
-}
-
-
+CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default;
diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp
index 2b803e7eb0d3..6f1199de69de 100644
--- a/source/Commands/CommandObjectType.cpp
+++ b/source/Commands/CommandObjectType.cpp
@@ -1,4 +1,4 @@
-//===-- CommandObjectType.cpp ----------------------------------*- C++ -*-===//
+//===-- CommandObjectType.cpp -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,14 +10,15 @@
#include "CommandObjectType.h"
// C Includes
-
-#include <ctype.h>
-
// C++ Includes
+#include <algorithm>
+#include <cctype>
#include <functional>
+// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/IOHandler.h"
@@ -33,6 +34,7 @@
#include "lldb/Interpreter/OptionValueBoolean.h"
#include "lldb/Interpreter/OptionValueLanguage.h"
#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
@@ -43,20 +45,13 @@
using namespace lldb;
using namespace lldb_private;
-
class ScriptAddOptions
{
-
public:
-
TypeSummaryImpl::Flags m_flags;
-
StringList m_target_types;
-
bool m_regex;
-
ConstString m_name;
-
std::string m_category;
ScriptAddOptions(const TypeSummaryImpl::Flags& flags,
@@ -71,20 +66,16 @@ public:
}
typedef std::shared_ptr<ScriptAddOptions> SharedPointer;
-
};
class SynthAddOptions
{
-
public:
-
bool m_skip_pointers;
bool m_skip_references;
bool m_cascade;
bool m_regex;
StringList m_target_types;
-
std::string m_category;
SynthAddOptions(bool sptr,
@@ -102,7 +93,6 @@ public:
}
typedef std::shared_ptr<SynthAddOptions> SharedPointer;
-
};
static bool
@@ -136,20 +126,17 @@ class CommandObjectTypeSummaryAdd :
public CommandObjectParsed,
public IOHandlerDelegateMultiline
{
-
private:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override;
@@ -193,7 +180,6 @@ private:
Execute_StringSummary (Args& command, CommandReturnObject &result);
public:
-
enum SummaryFormatType
{
eRegularSummary,
@@ -202,11 +188,9 @@ public:
};
CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter);
-
- ~CommandObjectTypeSummaryAdd () override
- {
- }
-
+
+ ~CommandObjectTypeSummaryAdd() override = default;
+
void
IOHandlerActivated (IOHandler &io_handler) override
{
@@ -222,8 +206,7 @@ public:
output_sp->Flush();
}
}
-
-
+
void
IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
{
@@ -344,7 +327,7 @@ public:
error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
error_sp->Flush();
}
-#endif // #ifndef LLDB_DISABLE_PYTHON
+#endif // LLDB_DISABLE_PYTHON
io_handler.SetIsDone(true);
}
@@ -353,11 +336,11 @@ public:
lldb::TypeSummaryImplSP entry,
SummaryFormatType type,
std::string category,
- Error* error = NULL);
+ Error* error = nullptr);
+
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override;
-
};
static const char *g_synth_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
@@ -374,20 +357,17 @@ class CommandObjectTypeSynthAdd :
public CommandObjectParsed,
public IOHandlerDelegateMultiline
{
-
private:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -460,13 +440,9 @@ private:
std::string m_class_name;
bool m_input_python;
std::string m_category;
-
bool is_class_based;
-
bool handwrite_python;
-
bool m_regex;
-
};
CommandOptions m_options;
@@ -511,8 +487,7 @@ protected:
output_sp->Flush();
}
}
-
-
+
void
IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
{
@@ -614,12 +589,11 @@ protected:
error_sp->Flush();
}
-#endif // #ifndef LLDB_DISABLE_PYTHON
+#endif // LLDB_DISABLE_PYTHON
io_handler.SetIsDone(true);
}
public:
-
enum SynthFormatType
{
eRegularSynth,
@@ -627,11 +601,9 @@ public:
};
CommandObjectTypeSynthAdd (CommandInterpreter &interpreter);
-
- ~CommandObjectTypeSynthAdd () override
- {
- }
-
+
+ ~CommandObjectTypeSynthAdd() override = default;
+
static bool
AddSynth(ConstString type_name,
lldb::SyntheticChildrenSP entry,
@@ -646,22 +618,17 @@ public:
class CommandObjectTypeFormatAdd : public CommandObjectParsed
{
-
private:
-
class CommandOptions : public OptionGroup
{
public:
-
CommandOptions () :
OptionGroup()
{
}
-
- ~CommandOptions () override
- {
- }
-
+
+ ~CommandOptions() override = default;
+
uint32_t
GetNumDefinitions () override;
@@ -681,6 +648,7 @@ private:
m_category.assign("default");
m_custom_type_name.clear();
}
+
Error
SetOptionValue (CommandInterpreter &interpreter,
uint32_t option_idx,
@@ -746,10 +714,10 @@ private:
public:
CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "type format add",
- "Add a new formatting style for a type.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "type format add",
+ "Add a new formatting style for a type.",
+ nullptr),
m_option_group (interpreter),
m_format_options (eFormatInvalid),
m_command_options ()
@@ -804,13 +772,10 @@ pointers to floats. Nor will it change the default display for Afloat and Bfloa
m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
m_option_group.Append (&m_command_options);
m_option_group.Finalize();
-
}
-
- ~CommandObjectTypeFormatAdd () override
- {
- }
-
+
+ ~CommandObjectTypeFormatAdd() override = default;
+
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -891,16 +856,15 @@ protected:
OptionDefinition
CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
- { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
- { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Format variables as if they were of this type."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one."},
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
+ { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
+ { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
+ { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions."},
+ { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Format variables as if they were of this type."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
uint32_t
CommandObjectTypeFormatAdd::CommandOptions::GetNumDefinitions ()
{
@@ -913,14 +877,13 @@ protected:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -985,12 +948,12 @@ public:
uint32_t formatter_kind_mask,
const char* name,
const char* help) :
- CommandObjectParsed (interpreter,
- name,
- help,
- NULL),
- m_options(interpreter),
- m_formatter_kind_mask(formatter_kind_mask)
+ CommandObjectParsed(interpreter,
+ name,
+ help,
+ nullptr),
+ m_options(interpreter),
+ m_formatter_kind_mask(formatter_kind_mask)
{
CommandArgumentEntry type_arg;
CommandArgumentData type_style_arg;
@@ -1001,11 +964,10 @@ public:
type_arg.push_back (type_style_arg);
m_arguments.push_back (type_arg);
-
}
-
- ~CommandObjectTypeFormatterDelete () override = default;
-
+
+ ~CommandObjectTypeFormatterDelete() override = default;
+
protected:
virtual bool
FormatterSpecificDeletion (ConstString typeCS)
@@ -1076,35 +1038,31 @@ protected:
result.SetStatus(eReturnStatusFailed);
return false;
}
-
}
-
};
OptionDefinition
CommandObjectTypeFormatterDelete::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Delete from every category."},
- { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Delete from given category."},
- { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Delete from given language's category."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete from every category."},
+ { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Delete from given category."},
+ { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Delete from given language's category."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
class CommandObjectTypeFormatterClear : public CommandObjectParsed
{
private:
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -1158,19 +1116,17 @@ public:
uint32_t formatter_kind_mask,
const char* name,
const char* help) :
- CommandObjectParsed (interpreter,
- name,
- help,
- NULL),
- m_options(interpreter),
- m_formatter_kind_mask(formatter_kind_mask)
+ CommandObjectParsed(interpreter,
+ name,
+ help,
+ nullptr),
+ m_options(interpreter),
+ m_formatter_kind_mask(formatter_kind_mask)
{
}
-
- ~CommandObjectTypeFormatterClear () override
- {
- }
-
+
+ ~CommandObjectTypeFormatterClear() override = default;
+
protected:
virtual void
FormatterSpecificDeletion ()
@@ -1198,7 +1154,7 @@ protected:
}
else
{
- DataVisualization::Categories::GetCategory(ConstString(NULL), category);
+ DataVisualization::Categories::GetCategory(ConstString(nullptr), category);
}
category->Clear(m_formatter_kind_mask);
}
@@ -1208,14 +1164,13 @@ protected:
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
-
};
OptionDefinition
CommandObjectTypeFormatterClear::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Clear every category."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Clear every category."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -1232,10 +1187,8 @@ public:
"Delete an existing formatting style for a type.")
{
}
-
- ~CommandObjectTypeFormatDelete () override
- {
- }
+
+ ~CommandObjectTypeFormatDelete() override = default;
};
//-------------------------------------------------------------------------
@@ -1262,16 +1215,15 @@ class CommandObjectTypeFormatterList : public CommandObjectParsed
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_category_regex("",""),
m_category_language(lldb::eLanguageTypeUnknown, lldb::eLanguageTypeUnknown)
{
}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -1282,9 +1234,12 @@ class CommandObjectTypeFormatterList : public CommandObjectParsed
{
case 'w':
m_category_regex.SetCurrentValue(option_arg);
+ m_category_regex.SetOptionWasSet();
break;
case 'l':
error = m_category_language.SetValueFromString(option_arg);
+ if (error.Success())
+ m_category_language.SetOptionWasSet();
break;
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
@@ -1306,9 +1261,9 @@ class CommandObjectTypeFormatterList : public CommandObjectParsed
{
static OptionDefinition g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Only show categories matching this filter."},
- { LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Only show the category for a specific language."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_1, false, "category-regex", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Only show categories matching this filter."},
+ { LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Only show the category for a specific language."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
return g_option_table;
@@ -1336,11 +1291,11 @@ public:
CommandObjectTypeFormatterList (CommandInterpreter &interpreter,
const char* name,
const char* help) :
- CommandObjectParsed (interpreter,
- name,
- help,
- NULL),
- m_options(interpreter)
+ CommandObjectParsed(interpreter,
+ name,
+ help,
+ nullptr),
+ m_options(interpreter)
{
CommandArgumentEntry type_arg;
CommandArgumentData type_style_arg;
@@ -1352,15 +1307,14 @@ public:
m_arguments.push_back (type_arg);
}
-
- ~CommandObjectTypeFormatterList () override
- {
- }
-
+
+ ~CommandObjectTypeFormatterList() override = default;
+
protected:
- virtual void
+ virtual bool
FormatterSpecificList (CommandReturnObject &result)
{
+ return false;
}
bool
@@ -1384,7 +1338,7 @@ protected:
if (argc == 1)
{
- const char* arg = command.GetArgumentAtIndex(1);
+ const char* arg = command.GetArgumentAtIndex(0);
formatter_regex.reset(new RegularExpression());
if (!formatter_regex->Compile(arg))
{
@@ -1394,10 +1348,15 @@ protected:
}
}
- auto category_closure = [&result, &formatter_regex] (const lldb::TypeCategoryImplSP& category) -> void {
- result.GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", category->GetName());
+ bool any_printed = false;
+
+ auto category_closure = [&result, &formatter_regex, &any_printed] (const lldb::TypeCategoryImplSP& category) -> void {
+ result.GetOutputStream().Printf("-----------------------\nCategory: %s%s\n-----------------------\n",
+ category->GetName(),
+ category->IsEnabled() ? "" : " (disabled)");
+
TypeCategoryImpl::ForEachCallbacks<FormatterType> foreach;
- foreach.SetExact([&result, &formatter_regex] (ConstString name, const FormatterSharedPointer& format_sp) -> bool {
+ foreach.SetExact([&result, &formatter_regex, &any_printed] (ConstString name, const FormatterSharedPointer& format_sp) -> bool {
if (formatter_regex)
{
bool escape = true;
@@ -1413,13 +1372,13 @@ protected:
if (escape)
return true;
}
-
+
+ any_printed = true;
result.GetOutputStream().Printf ("%s: %s\n", name.AsCString(), format_sp->GetDescription().c_str());
-
return true;
});
- foreach.SetWithRegex( [&result, &formatter_regex] (RegularExpressionSP regex_sp, const FormatterSharedPointer& format_sp) -> bool {
+ foreach.SetWithRegex([&result, &formatter_regex, &any_printed] (RegularExpressionSP regex_sp, const FormatterSharedPointer& format_sp) -> bool {
if (formatter_regex)
{
bool escape = true;
@@ -1436,8 +1395,8 @@ protected:
return true;
}
+ any_printed = true;
result.GetOutputStream().Printf ("%s: %s\n", regex_sp->GetText(), format_sp->GetDescription().c_str());
-
return true;
});
@@ -1475,10 +1434,16 @@ protected:
return true;
});
- FormatterSpecificList(result);
+ any_printed = FormatterSpecificList(result) | any_printed;
}
- result.SetStatus(eReturnStatusSuccessFinishResult);
+ if (any_printed)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else
+ {
+ result.GetOutputStream().PutCString("no matching results found.\n");
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
return result.Succeeded();
}
};
@@ -1505,7 +1470,7 @@ public:
// CommandObjectTypeSummaryAdd
//-------------------------------------------------------------------------
-#endif // #ifndef LLDB_DISABLE_PYTHON
+#endif // LLDB_DISABLE_PYTHON
Error
CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
@@ -1588,8 +1553,6 @@ CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting ()
m_category = "default";
}
-
-
#ifndef LLDB_DISABLE_PYTHON
bool
@@ -1624,7 +1587,7 @@ CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturn
ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (interpreter && interpreter->CheckObjectExists(funct_name) == false)
+ if (interpreter && !interpreter->CheckObjectExists(funct_name))
result.AppendWarningWithFormat("The provided function \"%s\" does not exist - "
"please define it before attempting to use this summary.\n",
funct_name);
@@ -1727,8 +1690,7 @@ CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturn
return result.Succeeded();
}
-#endif
-
+#endif // LLDB_DISABLE_PYTHON
bool
CommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturnObject &result)
@@ -1759,20 +1721,23 @@ CommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturn
return false;
}
- Error error;
-
- lldb::TypeSummaryImplSP entry(new StringSummaryFormat(m_options.m_flags,
- format_cstr));
-
- if (error.Fail())
+ std::unique_ptr<StringSummaryFormat> string_format(new StringSummaryFormat(m_options.m_flags, format_cstr));
+ if (!string_format)
{
- result.AppendError(error.AsCString());
+ result.AppendError("summary creation failed");
result.SetStatus(eReturnStatusFailed);
return false;
}
+ if (string_format->m_error.Fail())
+ {
+ result.AppendErrorWithFormat("syntax error: %s", string_format->m_error.AsCString("<unknown>"));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ lldb::TypeSummaryImplSP entry(string_format.release());
// now I have a valid format, let's add it to every type
-
+ Error error;
for (size_t i = 0; i < argc; i++)
{
const char* typeA = command.GetArgumentAtIndex(i);
@@ -1815,10 +1780,10 @@ CommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturn
}
CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "type summary add",
- "Add a new summary style for a type.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "type summary add",
+ "Add a new summary style for a type.",
+ nullptr),
IOHandlerDelegateMultiline ("DONE"),
m_options (interpreter)
{
@@ -1928,7 +1893,7 @@ CommandObjectTypeSummaryAdd::DoExecute (Args& command, CommandReturnObject &resu
result.AppendError ("python is disabled");
result.SetStatus(eReturnStatusFailed);
return false;
-#endif
+#endif // LLDB_DISABLE_PYTHON
}
return Execute_StringSummary(command, result);
@@ -2000,25 +1965,24 @@ CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
OptionDefinition
CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
- { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type."},
- { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
- { LLDB_OPT_SET_1 , true, "inline-children", 'c', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "If true, inline all child values into summary string."},
- { LLDB_OPT_SET_1 , false, "omit-names", 'O', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "If true, omit value names in the summary display."},
- { LLDB_OPT_SET_2 , true, "summary-string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSummaryString, "Summary string used to display text and object contents."},
- { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."},
- { LLDB_OPT_SET_3, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type."},
- { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."},
- { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines."},
- { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "hide-empty", 'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Do not expand aggregate data types with no children."},
- { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "A name for this summary string."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one."},
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
+ { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type."},
+ { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
+ { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
+ { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions."},
+ { LLDB_OPT_SET_1 , true, "inline-children", 'c', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If true, inline all child values into summary string."},
+ { LLDB_OPT_SET_1 , false, "omit-names", 'O', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If true, omit value names in the summary display."},
+ { LLDB_OPT_SET_2 , true, "summary-string", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSummaryString, "Summary string used to display text and object contents."},
+ { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."},
+ { LLDB_OPT_SET_3, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type."},
+ { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Input Python code to use for this type manually."},
+ { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines."},
+ { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "hide-empty", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Do not expand aggregate data types with no children."},
+ { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "A name for this summary string."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
//-------------------------------------------------------------------------
// CommandObjectTypeSummaryDelete
//-------------------------------------------------------------------------
@@ -2033,11 +1997,9 @@ public:
"Delete an existing summary for a type.")
{
}
-
- ~CommandObjectTypeSummaryDelete () override
- {
- }
-
+
+ ~CommandObjectTypeSummaryDelete() override = default;
+
protected:
bool
FormatterSpecificDeletion (ConstString typeCS) override
@@ -2074,7 +2036,6 @@ protected:
class CommandObjectTypeSummaryList : public CommandObjectTypeFormatterList<TypeSummaryImpl>
{
public:
-
CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :
CommandObjectTypeFormatterList(interpreter,
"type summary list",
@@ -2083,7 +2044,7 @@ public:
}
protected:
- void
+ bool
FormatterSpecificList (CommandReturnObject &result) override
{
if (DataVisualization::NamedSummaryFormats::GetCount() > 0)
@@ -2093,7 +2054,9 @@ protected:
result.GetOutputStream().Printf ("%s: %s\n", name.AsCString(), summary_sp->GetDescription().c_str());
return true;
});
+ return true;
}
+ return false;
}
};
@@ -2103,20 +2066,18 @@ protected:
class CommandObjectTypeCategoryDefine : public CommandObjectParsed
{
-
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_define_enabled(false,false),
m_cate_language(eLanguageTypeUnknown,eLanguageTypeUnknown)
{
}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -2160,8 +2121,6 @@ class CommandObjectTypeCategoryDefine : public CommandObjectParsed
OptionValueBoolean m_define_enabled;
OptionValueLanguage m_cate_language;
-
-
};
CommandOptions m_options;
@@ -2174,11 +2133,11 @@ class CommandObjectTypeCategoryDefine : public CommandObjectParsed
public:
CommandObjectTypeCategoryDefine (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "type category define",
- "Define a new category as a source of formatters.",
- NULL),
- m_options(interpreter)
+ CommandObjectParsed(interpreter,
+ "type category define",
+ "Define a new category as a source of formatters.",
+ nullptr),
+ m_options(interpreter)
{
CommandArgumentEntry type_arg;
CommandArgumentData type_style_arg;
@@ -2189,13 +2148,10 @@ public:
type_arg.push_back (type_style_arg);
m_arguments.push_back (type_arg);
-
- }
-
- ~CommandObjectTypeCategoryDefine () override
- {
}
-
+
+ ~CommandObjectTypeCategoryDefine() override = default;
+
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -2224,15 +2180,14 @@ protected:
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
-
};
OptionDefinition
CommandObjectTypeCategoryDefine::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "enabled", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "If specified, this category will be created enabled."},
- { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Specify the language that this category is supported for."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "enabled", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If specified, this category will be created enabled."},
+ { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specify the language that this category is supported for."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -2244,14 +2199,13 @@ class CommandObjectTypeCategoryEnable : public CommandObjectParsed
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -2308,10 +2262,10 @@ class CommandObjectTypeCategoryEnable : public CommandObjectParsed
public:
CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "type category enable",
- "Enable a category as a source of formatters.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "type category enable",
+ "Enable a category as a source of formatters.",
+ nullptr),
m_options(interpreter)
{
CommandArgumentEntry type_arg;
@@ -2325,11 +2279,9 @@ public:
m_arguments.push_back (type_arg);
}
-
- ~CommandObjectTypeCategoryEnable () override
- {
- }
-
+
+ ~CommandObjectTypeCategoryEnable() override = default;
+
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -2363,7 +2315,7 @@ protected:
}
DataVisualization::Categories::Enable(typeCS);
lldb::TypeCategoryImplSP cate;
- if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate.get())
+ if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate)
{
if (cate->GetCount() == 0)
{
@@ -2379,14 +2331,13 @@ protected:
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
-
};
OptionDefinition
CommandObjectTypeCategoryEnable::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Enable the category for this language."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Enable the category for this language."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -2397,10 +2348,10 @@ class CommandObjectTypeCategoryDelete : public CommandObjectParsed
{
public:
CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "type category delete",
- "Delete a category and all associated formatters.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "type category delete",
+ "Delete a category and all associated formatters.",
+ nullptr)
{
CommandArgumentEntry type_arg;
CommandArgumentData type_style_arg;
@@ -2411,13 +2362,10 @@ public:
type_arg.push_back (type_style_arg);
m_arguments.push_back (type_arg);
-
- }
-
- ~CommandObjectTypeCategoryDelete () override
- {
}
-
+
+ ~CommandObjectTypeCategoryDelete() override = default;
+
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -2471,14 +2419,13 @@ class CommandObjectTypeCategoryDisable : public CommandObjectParsed
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -2522,7 +2469,6 @@ class CommandObjectTypeCategoryDisable : public CommandObjectParsed
// Instance variables to hold the values for command options.
lldb::LanguageType m_language;
-
};
CommandOptions m_options;
@@ -2535,10 +2481,10 @@ class CommandObjectTypeCategoryDisable : public CommandObjectParsed
public:
CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "type category disable",
- "Disable a category as a source of formatters.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "type category disable",
+ "Disable a category as a source of formatters.",
+ nullptr),
m_options(interpreter)
{
CommandArgumentEntry type_arg;
@@ -2550,13 +2496,10 @@ public:
type_arg.push_back (type_style_arg);
m_arguments.push_back (type_arg);
-
}
-
- ~CommandObjectTypeCategoryDisable () override
- {
- }
-
+
+ ~CommandObjectTypeCategoryDisable() override = default;
+
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -2599,14 +2542,13 @@ protected:
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
-
};
OptionDefinition
CommandObjectTypeCategoryDisable::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Enable the category for this language."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Enable the category for this language."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -2617,10 +2559,10 @@ class CommandObjectTypeCategoryList : public CommandObjectParsed
{
public:
CommandObjectTypeCategoryList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "type category list",
- "Provide a list of all existing categories.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "type category list",
+ "Provide a list of all existing categories.",
+ nullptr)
{
CommandArgumentEntry type_arg;
CommandArgumentData type_style_arg;
@@ -2632,11 +2574,9 @@ public:
m_arguments.push_back (type_arg);
}
-
- ~CommandObjectTypeCategoryList () override
- {
- }
-
+
+ ~CommandObjectTypeCategoryList() override = default;
+
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -2688,7 +2628,6 @@ protected:
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
-
};
//-------------------------------------------------------------------------
@@ -2698,7 +2637,6 @@ protected:
class CommandObjectTypeFilterList : public CommandObjectTypeFormatterList<TypeFilterImpl>
{
public:
-
CommandObjectTypeFilterList (CommandInterpreter &interpreter) :
CommandObjectTypeFormatterList(interpreter,
"type filter list",
@@ -2716,7 +2654,6 @@ public:
class CommandObjectTypeSynthList : public CommandObjectTypeFormatterList<SyntheticChildren>
{
public:
-
CommandObjectTypeSynthList (CommandInterpreter &interpreter) :
CommandObjectTypeFormatterList(interpreter,
"type synthetic list",
@@ -2725,7 +2662,8 @@ public:
}
};
-#endif // #ifndef LLDB_DISABLE_PYTHON
+#endif // LLDB_DISABLE_PYTHON
+
//-------------------------------------------------------------------------
// CommandObjectTypeFilterDelete
//-------------------------------------------------------------------------
@@ -2740,10 +2678,8 @@ public:
"Delete an existing filter for a type.")
{
}
-
- ~CommandObjectTypeFilterDelete () override
- {
- }
+
+ ~CommandObjectTypeFilterDelete() override = default;
};
#ifndef LLDB_DISABLE_PYTHON
@@ -2762,13 +2698,11 @@ public:
"Delete an existing synthetic provider for a type.")
{
}
-
- ~CommandObjectTypeSynthDelete () override
- {
- }
+
+ ~CommandObjectTypeSynthDelete() override = default;
};
-#endif // #ifndef LLDB_DISABLE_PYTHON
+#endif // LLDB_DISABLE_PYTHON
//-------------------------------------------------------------------------
// CommandObjectTypeFilterClear
@@ -2866,7 +2800,7 @@ CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObje
ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (interpreter && interpreter->CheckObjectExists(impl->GetPythonClassName()) == false)
+ if (interpreter && !interpreter->CheckObjectExists(impl->GetPythonClassName()))
result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider");
// now I have a valid provider, let's add it to every type
@@ -2906,10 +2840,10 @@ CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObje
}
CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "type synthetic add",
- "Add a new synthetic provider for a type.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "type synthetic add",
+ "Add a new synthetic provider for a type.",
+ nullptr),
IOHandlerDelegateMultiline ("DONE"),
m_options (interpreter)
{
@@ -2922,7 +2856,6 @@ CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interp
type_arg.push_back (type_style_arg);
m_arguments.push_back (type_arg);
-
}
bool
@@ -2975,35 +2908,33 @@ CommandObjectTypeSynthAdd::AddSynth(ConstString type_name,
OptionDefinition
CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
- { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children."},
- { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children."},
- { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
+ { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
+ { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
+ { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one."},
+ { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children."},
+ { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children."},
+ { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-#endif // #ifndef LLDB_DISABLE_PYTHON
+#endif // LLDB_DISABLE_PYTHON
class CommandObjectTypeFilterAdd : public CommandObjectParsed
{
-
private:
-
class CommandOptions : public Options
{
typedef std::vector<std::string> option_vector;
+
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
{
@@ -3072,9 +3003,7 @@ private:
bool m_input_python;
option_vector m_expr_paths;
std::string m_category;
-
bool has_child_list;
-
bool m_regex;
typedef option_vector::iterator ExpressionPathsIterator;
@@ -3141,14 +3070,12 @@ private:
}
}
-
public:
-
CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "type filter add",
- "Add a new filter for a type.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "type filter add",
+ "Add a new filter for a type.",
+ nullptr),
m_options (interpreter)
{
CommandArgumentEntry type_arg;
@@ -3194,11 +3121,9 @@ all children of my_foo as if no filter was defined:" R"(
(lldb) frame variable my_foo --raw)"
);
}
-
- ~CommandObjectTypeFilterAdd () override
- {
- }
-
+
+ ~CommandObjectTypeFilterAdd() override = default;
+
protected:
bool
DoExecute (Args& command, CommandReturnObject &result) override
@@ -3212,7 +3137,7 @@ protected:
return false;
}
- if (m_options.m_expr_paths.size() == 0)
+ if (m_options.m_expr_paths.empty())
{
result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
@@ -3267,19 +3192,18 @@ protected:
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
}
-
};
OptionDefinition
CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
- { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."},
- { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
+ { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
+ { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
+ { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one."},
+ { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."},
+ { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions."},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//----------------------------------------------------------------------
@@ -3288,19 +3212,38 @@ CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] =
class CommandObjectTypeLookup : public CommandObjectRaw
{
protected:
+ // this function is allowed to do a more aggressive job at guessing languages than the expression parser
+ // is comfortable with - so leave the original call alone and add one that is specific to type lookup
+ lldb::LanguageType
+ GuessLanguage (StackFrame *frame)
+ {
+ lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown;
+
+ if (!frame)
+ return lang_type;
+
+ lang_type = frame->GuessLanguage();
+ if (lang_type != lldb::eLanguageTypeUnknown)
+ return lang_type;
+
+ Symbol *s = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
+ if (s)
+ lang_type = s->GetMangled().GuessLanguage();
+
+ return lang_type;
+ }
class CommandOptions : public OptionGroup
{
public:
-
CommandOptions () :
OptionGroup(),
m_show_help(false),
m_language(eLanguageTypeUnknown)
{}
-
- ~CommandOptions () override {}
-
+
+ ~CommandOptions() override = default;
+
uint32_t
GetNumDefinitions () override
{
@@ -3358,12 +3301,11 @@ protected:
CommandOptions m_command_options;
public:
-
CommandObjectTypeLookup (CommandInterpreter &interpreter) :
CommandObjectRaw (interpreter,
"type lookup",
- "Lookup a type by name in the select target.",
- "type lookup <typename>",
+ "Lookup types and declarations in the current target, following language-specific naming conventions.",
+ "type lookup <type-specifier>",
eCommandRequiresTarget),
m_option_group(interpreter),
m_command_options()
@@ -3371,17 +3313,41 @@ public:
m_option_group.Append(&m_command_options);
m_option_group.Finalize();
}
-
- ~CommandObjectTypeLookup () override
- {
- }
-
+
+ ~CommandObjectTypeLookup() override = default;
+
Options *
GetOptions () override
{
return &m_option_group;
}
+ const char*
+ GetHelpLong () override
+ {
+ if (m_cmd_help_long.empty())
+ {
+ StreamString stream;
+ // FIXME: hardcoding languages is not good
+ lldb::LanguageType languages[] = {eLanguageTypeObjC,eLanguageTypeC_plus_plus};
+
+ for(const auto lang_type : languages)
+ {
+ if (auto language = Language::FindPlugin(lang_type))
+ {
+ if (const char* help = language->GetLanguageSpecificTypeLookupHelp())
+ {
+ stream.Printf("%s\n", help);
+ }
+ }
+ }
+
+ if (stream.GetData())
+ m_cmd_help_long.assign(stream.GetString());
+ }
+ return this->CommandObject::GetHelpLong();
+ }
+
bool
DoExecute (const char *raw_command_line, CommandReturnObject &result) override
{
@@ -3393,12 +3359,12 @@ public:
m_option_group.NotifyOptionParsingStarting();
- const char * name_of_type = NULL;
+ const char * name_of_type = nullptr;
if (raw_command_line[0] == '-')
{
// We have some options and these options MUST end with --.
- const char *end_options = NULL;
+ const char *end_options = nullptr;
const char *s = raw_command_line;
while (s && s[0])
{
@@ -3444,7 +3410,9 @@ public:
std::vector<Language*> languages;
- if (m_command_options.m_language == eLanguageTypeUnknown)
+ bool is_global_search = false;
+
+ if ( (is_global_search = (m_command_options.m_language == eLanguageTypeUnknown)) )
{
// FIXME: hardcoding languages is not good
languages.push_back(Language::FindPlugin(eLanguageTypeObjC));
@@ -3455,6 +3423,27 @@ public:
languages.push_back(Language::FindPlugin(m_command_options.m_language));
}
+ // This is not the most efficient way to do this, but we support very few languages
+ // so the cost of the sort is going to be dwarfed by the actual lookup anyway
+ if (StackFrame* frame = m_exe_ctx.GetFramePtr())
+ {
+ LanguageType lang = GuessLanguage(frame);
+ if (lang != eLanguageTypeUnknown)
+ {
+ std::sort(languages.begin(),
+ languages.end(),
+ [lang] (Language* lang1,
+ Language* lang2) -> bool {
+ if (!lang1 || !lang2) return false;
+ LanguageType lt1 = lang1->GetLanguageType();
+ LanguageType lt2 = lang2->GetLanguageType();
+ if (lt1 == lang) return true; // make the selected frame's language come first
+ if (lt2 == lang) return false; // make the selected frame's language come first
+ return (lt1 < lt2); // normal comparison otherwise
+ });
+ }
+ }
+
for (Language* language : languages)
{
if (!language)
@@ -3474,21 +3463,26 @@ public:
}
}
}
+ // this is "type lookup SomeName" and we did find a match, so get out
+ if (any_found && is_global_search)
+ break;
}
}
+ if (!any_found)
+ result.AppendMessageWithFormat("no type was found matching '%s'\n", name_of_type);
+
result.SetStatus (any_found ? lldb::eReturnStatusSuccessFinishResult : lldb::eReturnStatusSuccessFinishNoResult);
return true;
}
-
};
OptionDefinition
CommandObjectTypeLookup::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "show-help", 'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display available help for types"},
- { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Which language's types should the search scope be"},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "show-help", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display available help for types"},
+ { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Which language's types should the search scope be"},
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
template <typename FormatterType>
@@ -3517,17 +3511,23 @@ public:
syntax.Printf("type %s info <expr>", formatter_name);
SetSyntax(syntax.GetData());
}
-
- ~CommandObjectFormatterInfo () override
- {
- }
-
+
+ ~CommandObjectFormatterInfo() override = default;
+
protected:
bool
DoExecute (const char *command, CommandReturnObject &result) override
{
- auto target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
- auto frame_sp = target_sp->GetProcessSP()->GetThreadList().GetSelectedThread()->GetSelectedFrame();
+ TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
+ Thread *thread = GetDefaultThread();
+ if (!thread)
+ {
+ result.AppendError("no default thread");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
+ }
+
+ StackFrameSP frame_sp = thread->GetSelectedFrame();
ValueObjectSP result_valobj_sp;
EvaluateExpressionOptions options;
lldb::ExpressionResults expr_result = target_sp->EvaluateExpression(command, frame_sp.get(), result_valobj_sp, options);
@@ -3571,11 +3571,9 @@ private:
class CommandObjectTypeFormat : public CommandObjectMultiword
{
public:
- CommandObjectTypeFormat (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "type format",
- "A set of commands for editing variable value display options",
- "type format [<sub-command-options>] ")
+ CommandObjectTypeFormat(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "type format", "Commands for customizing value display formats.",
+ "type format [<sub-command-options>] ")
{
LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter)));
LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFormatClear (interpreter)));
@@ -3588,10 +3586,7 @@ public:
})));
}
-
- ~CommandObjectTypeFormat () override
- {
- }
+ ~CommandObjectTypeFormat() override = default;
};
#ifndef LLDB_DISABLE_PYTHON
@@ -3599,11 +3594,10 @@ public:
class CommandObjectTypeSynth : public CommandObjectMultiword
{
public:
- CommandObjectTypeSynth (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "type synthetic",
- "A set of commands for operating on synthetic type representations",
- "type synthetic [<sub-command-options>] ")
+ CommandObjectTypeSynth(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "type synthetic",
+ "Commands for operating on synthetic type representations.",
+ "type synthetic [<sub-command-options>] ")
{
LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter)));
LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSynthClear (interpreter)));
@@ -3615,44 +3609,34 @@ public:
return valobj.GetSyntheticChildren();
})));
}
-
-
- ~CommandObjectTypeSynth () override
- {
- }
+
+ ~CommandObjectTypeSynth() override = default;
};
-#endif // #ifndef LLDB_DISABLE_PYTHON
+#endif // LLDB_DISABLE_PYTHON
class CommandObjectTypeFilter : public CommandObjectMultiword
{
public:
- CommandObjectTypeFilter (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "type filter",
- "A set of commands for operating on type filters",
- "type synthetic [<sub-command-options>] ")
+ CommandObjectTypeFilter(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "type filter", "Commands for operating on type filters.",
+ "type synthetic [<sub-command-options>] ")
{
LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter)));
LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFilterClear (interpreter)));
LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter)));
LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFilterList (interpreter)));
}
-
-
- ~CommandObjectTypeFilter () override
- {
- }
+
+ ~CommandObjectTypeFilter() override = default;
};
class CommandObjectTypeCategory : public CommandObjectMultiword
{
public:
- CommandObjectTypeCategory (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "type category",
- "A set of commands for operating on categories",
- "type category [<sub-command-options>] ")
+ CommandObjectTypeCategory(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "type category", "Commands for operating on type categories.",
+ "type category [<sub-command-options>] ")
{
LoadSubCommand ("define", CommandObjectSP (new CommandObjectTypeCategoryDefine (interpreter)));
LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter)));
@@ -3660,21 +3644,16 @@ public:
LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter)));
LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeCategoryList (interpreter)));
}
-
-
- ~CommandObjectTypeCategory () override
- {
- }
+
+ ~CommandObjectTypeCategory() override = default;
};
class CommandObjectTypeSummary : public CommandObjectMultiword
{
public:
- CommandObjectTypeSummary (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "type summary",
- "A set of commands for editing variable summary display options",
- "type summary [<sub-command-options>] ")
+ CommandObjectTypeSummary(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "type summary", "Commands for editing variable summary display options.",
+ "type summary [<sub-command-options>] ")
{
LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter)));
LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter)));
@@ -3686,22 +3665,17 @@ public:
return valobj.GetSummaryFormat();
})));
}
-
-
- ~CommandObjectTypeSummary () override
- {
- }
+
+ ~CommandObjectTypeSummary() override = default;
};
//-------------------------------------------------------------------------
// CommandObjectType
//-------------------------------------------------------------------------
-CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "type",
- "A set of commands for operating on the type system",
- "type [<sub-command-options>]")
+CommandObjectType::CommandObjectType(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "type", "Commands for operating on the type system.",
+ "type [<sub-command-options>]")
{
LoadSubCommand ("category", CommandObjectSP (new CommandObjectTypeCategory (interpreter)));
LoadSubCommand ("filter", CommandObjectSP (new CommandObjectTypeFilter (interpreter)));
@@ -3709,11 +3683,8 @@ CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) :
LoadSubCommand ("summary", CommandObjectSP (new CommandObjectTypeSummary (interpreter)));
#ifndef LLDB_DISABLE_PYTHON
LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter)));
-#endif
+#endif // LLDB_DISABLE_PYTHON
LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTypeLookup (interpreter)));
}
-
-CommandObjectType::~CommandObjectType ()
-{
-}
+CommandObjectType::~CommandObjectType() = default;
diff --git a/source/Commands/CommandObjectVersion.cpp b/source/Commands/CommandObjectVersion.cpp
index 70e101c22330..06962f8648ad 100644
--- a/source/Commands/CommandObjectVersion.cpp
+++ b/source/Commands/CommandObjectVersion.cpp
@@ -24,8 +24,8 @@ using namespace lldb_private;
// CommandObjectVersion
//-------------------------------------------------------------------------
-CommandObjectVersion::CommandObjectVersion (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter, "version", "Show version of LLDB debugger.", "version")
+CommandObjectVersion::CommandObjectVersion(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "version", "Show the LLDB debugger version.", "version")
{
}
diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp
index a97f5ade6460..977b6bb37437 100644
--- a/source/Commands/CommandObjectWatchpoint.cpp
+++ b/source/Commands/CommandObjectWatchpoint.cpp
@@ -12,7 +12,11 @@
// C Includes
// C++ Includes
+#include <vector>
+
// Other libraries and framework includes
+#include "llvm/ADT/StringRef.h"
+
// Project includes
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Breakpoint/WatchpointList.h"
@@ -28,10 +32,6 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
-#include "llvm/ADT/StringRef.h"
-
-#include <vector>
-
using namespace lldb;
using namespace lldb_private;
@@ -47,7 +47,7 @@ AddWatchpointDescription(Stream *s, Watchpoint *wp, lldb::DescriptionLevel level
static bool
CheckTargetForWatchpointOperations(Target *target, CommandReturnObject &result)
{
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("Invalid target. No existing target or watchpoints.");
result.SetStatus (eReturnStatusFailed);
@@ -87,7 +87,7 @@ CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(Target *target, Args &args
// Pre-condition: args.GetArgumentCount() > 0.
if (args.GetArgumentCount() == 0)
{
- if (target == NULL)
+ if (target == nullptr)
return false;
WatchpointSP watch_sp = target->GetLastCreatedWatchpoint();
if (watch_sp)
@@ -166,10 +166,10 @@ class CommandObjectWatchpointList : public CommandObjectParsed
{
public:
CommandObjectWatchpointList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "watchpoint list",
- "List all watchpoints at configurable levels of detail.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "watchpoint list",
+ "List all watchpoints at configurable levels of detail.",
+ nullptr),
m_options(interpreter)
{
CommandArgumentEntry arg;
@@ -178,7 +178,7 @@ public:
m_arguments.push_back(arg);
}
- ~CommandObjectWatchpointList () override {}
+ ~CommandObjectWatchpointList() override = default;
Options *
GetOptions () override
@@ -189,14 +189,13 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options(interpreter),
m_level(lldb::eDescriptionLevelBrief) // Watchpoint List defaults to brief descriptions
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -235,7 +234,6 @@ public:
return g_option_table;
}
-
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table[];
@@ -250,7 +248,7 @@ protected:
DoExecute (Args& command, CommandReturnObject &result) override
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("Invalid target. No current target or watchpoints.");
result.SetStatus (eReturnStatusSuccessFinishNoResult);
@@ -267,8 +265,9 @@ protected:
}
const WatchpointList &watchpoints = target->GetWatchpointList();
- Mutex::Locker locker;
- target->GetWatchpointList().GetListMutex(locker);
+
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetWatchpointList().GetListMutex(lock);
size_t num_watchpoints = watchpoints.GetSize();
@@ -324,19 +323,20 @@ private:
// CommandObjectWatchpointList::Options
//-------------------------------------------------------------------------
#pragma mark List::CommandOptions
+
OptionDefinition
CommandObjectWatchpointList::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Give a brief description of the watchpoint (no location info)."},
- { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Give a full description of the watchpoint and its locations."},
- { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
"Explain everything we know about the watchpoint (for debugging debugger bugs)." },
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -348,10 +348,10 @@ class CommandObjectWatchpointEnable : public CommandObjectParsed
{
public:
CommandObjectWatchpointEnable (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "enable",
- "Enable the specified disabled watchpoint(s). If no watchpoints are specified, enable all of them.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "enable",
+ "Enable the specified disabled watchpoint(s). If no watchpoints are specified, enable all of them.",
+ nullptr)
{
CommandArgumentEntry arg;
CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
@@ -359,7 +359,7 @@ public:
m_arguments.push_back(arg);
}
- ~CommandObjectWatchpointEnable () override {}
+ ~CommandObjectWatchpointEnable() override = default;
protected:
bool
@@ -370,8 +370,8 @@ protected:
if (!CheckTargetForWatchpointOperations(target, result))
return false;
- Mutex::Locker locker;
- target->GetWatchpointList().GetListMutex(locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetWatchpointList().GetListMutex(lock);
const WatchpointList &watchpoints = target->GetWatchpointList();
@@ -413,8 +413,6 @@ protected:
return result.Succeeded();
}
-
-private:
};
//-------------------------------------------------------------------------
@@ -426,10 +424,10 @@ class CommandObjectWatchpointDisable : public CommandObjectParsed
{
public:
CommandObjectWatchpointDisable (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "watchpoint disable",
- "Disable the specified watchpoint(s) without removing it/them. If no watchpoints are specified, disable them all.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "watchpoint disable",
+ "Disable the specified watchpoint(s) without removing it/them. If no watchpoints are specified, disable them all.",
+ nullptr)
{
CommandArgumentEntry arg;
CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
@@ -437,8 +435,7 @@ public:
m_arguments.push_back(arg);
}
-
- ~CommandObjectWatchpointDisable () override {}
+ ~CommandObjectWatchpointDisable() override = default;
protected:
bool
@@ -448,8 +445,8 @@ protected:
if (!CheckTargetForWatchpointOperations(target, result))
return false;
- Mutex::Locker locker;
- target->GetWatchpointList().GetListMutex(locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetWatchpointList().GetListMutex(lock);
const WatchpointList &watchpoints = target->GetWatchpointList();
size_t num_watchpoints = watchpoints.GetSize();
@@ -497,7 +494,6 @@ protected:
return result.Succeeded();
}
-
};
//-------------------------------------------------------------------------
@@ -512,7 +508,7 @@ public:
CommandObjectParsed(interpreter,
"watchpoint delete",
"Delete the specified watchpoint(s). If no watchpoints are specified, delete them all.",
- NULL)
+ nullptr)
{
CommandArgumentEntry arg;
CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
@@ -520,7 +516,7 @@ public:
m_arguments.push_back(arg);
}
- ~CommandObjectWatchpointDelete () override {}
+ ~CommandObjectWatchpointDelete() override = default;
protected:
bool
@@ -530,9 +526,9 @@ protected:
if (!CheckTargetForWatchpointOperations(target, result))
return false;
- Mutex::Locker locker;
- target->GetWatchpointList().GetListMutex(locker);
-
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetWatchpointList().GetListMutex(lock);
+
const WatchpointList &watchpoints = target->GetWatchpointList();
size_t num_watchpoints = watchpoints.GetSize();
@@ -579,7 +575,6 @@ protected:
return result.Succeeded();
}
-
};
//-------------------------------------------------------------------------
@@ -590,10 +585,10 @@ class CommandObjectWatchpointIgnore : public CommandObjectParsed
{
public:
CommandObjectWatchpointIgnore (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "watchpoint ignore",
- "Set ignore count on the specified watchpoint(s). If no watchpoints are specified, set them all.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "watchpoint ignore",
+ "Set ignore count on the specified watchpoint(s). If no watchpoints are specified, set them all.",
+ nullptr),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -602,7 +597,7 @@ public:
m_arguments.push_back(arg);
}
- ~CommandObjectWatchpointIgnore () override {}
+ ~CommandObjectWatchpointIgnore() override = default;
Options *
GetOptions () override
@@ -613,14 +608,13 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_ignore_count (0)
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -631,12 +625,10 @@ public:
switch (short_option)
{
case 'i':
- {
m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
if (m_ignore_count == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
- }
- break;
+ break;
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -657,7 +649,6 @@ public:
return g_option_table;
}
-
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table[];
@@ -676,9 +667,9 @@ protected:
if (!CheckTargetForWatchpointOperations(target, result))
return false;
- Mutex::Locker locker;
- target->GetWatchpointList().GetListMutex(locker);
-
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetWatchpointList().GetListMutex(lock);
+
const WatchpointList &watchpoints = target->GetWatchpointList();
size_t num_watchpoints = watchpoints.GetSize();
@@ -724,14 +715,14 @@ private:
};
#pragma mark Ignore::CommandOptions
+
OptionDefinition
CommandObjectWatchpointIgnore::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, true, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "Set the number of times this watchpoint is skipped before stopping." },
- { 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, true, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this watchpoint is skipped before stopping." },
+ { 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
-
//-------------------------------------------------------------------------
// CommandObjectWatchpointModify
//-------------------------------------------------------------------------
@@ -740,14 +731,13 @@ CommandObjectWatchpointIgnore::CommandOptions::g_option_table[] =
class CommandObjectWatchpointModify : public CommandObjectParsed
{
public:
-
CommandObjectWatchpointModify (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "watchpoint modify",
- "Modify the options on a watchpoint or set of watchpoints in the executable. "
- "If no watchpoint is specified, act on the last created watchpoint. "
- "Passing an empty argument clears the modification.",
- NULL),
+ CommandObjectParsed(interpreter,
+ "watchpoint modify",
+ "Modify the options on a watchpoint or set of watchpoints in the executable. "
+ "If no watchpoint is specified, act on the last created watchpoint. "
+ "Passing an empty argument clears the modification.",
+ nullptr),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -756,7 +746,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectWatchpointModify () override {}
+ ~CommandObjectWatchpointModify() override = default;
Options *
GetOptions () override
@@ -767,7 +757,6 @@ public:
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_condition (),
@@ -775,7 +764,7 @@ public:
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -786,7 +775,7 @@ public:
switch (short_option)
{
case 'c':
- if (option_arg != NULL)
+ if (option_arg != nullptr)
m_condition.assign (option_arg);
else
m_condition.clear();
@@ -831,9 +820,9 @@ protected:
if (!CheckTargetForWatchpointOperations(target, result))
return false;
- Mutex::Locker locker;
- target->GetWatchpointList().GetListMutex(locker);
-
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetWatchpointList().GetListMutex(lock);
+
const WatchpointList &watchpoints = target->GetWatchpointList();
size_t num_watchpoints = watchpoints.GetSize();
@@ -885,11 +874,12 @@ private:
};
#pragma mark Modify::CommandOptions
+
OptionDefinition
CommandObjectWatchpointModify::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The watchpoint stops only if this condition expression evaluates to true."},
-{ 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The watchpoint stops only if this condition expression evaluates to true."},
+{ 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -900,24 +890,23 @@ CommandObjectWatchpointModify::CommandOptions::g_option_table[] =
class CommandObjectWatchpointSetVariable : public CommandObjectParsed
{
public:
-
CommandObjectWatchpointSetVariable (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "watchpoint set variable",
- "Set a watchpoint on a variable. "
- "Use the '-w' option to specify the type of watchpoint and "
- "the '-x' option to specify the byte size to watch for. "
- "If no '-w' option is specified, it defaults to write. "
- "If no '-x' option is specified, it defaults to the variable's "
- "byte size. "
- "Note that there are limited hardware resources for watchpoints. "
- "If watchpoint setting fails, consider disable/delete existing ones "
- "to free up resources.",
- NULL,
- eCommandRequiresFrame |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
+ CommandObjectParsed(interpreter,
+ "watchpoint set variable",
+ "Set a watchpoint on a variable. "
+ "Use the '-w' option to specify the type of watchpoint and "
+ "the '-s' option to specify the byte size to watch for. "
+ "If no '-w' option is specified, it defaults to write. "
+ "If no '-s' option is specified, it defaults to the variable's "
+ "byte size. "
+ "Note that there are limited hardware resources for watchpoints. "
+ "If watchpoint setting fails, consider disable/delete existing ones "
+ "to free up resources.",
+ nullptr,
+ eCommandRequiresFrame |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_option_group (interpreter),
m_option_watchpoint ()
{
@@ -944,12 +933,12 @@ corresponding to the byte size of the data type."
// Push the data for the only argument into the m_arguments vector.
m_arguments.push_back (arg);
- // Absorb the '-w' and '-x' options into our option group.
+ // Absorb the '-w' and '-s' options into our option group.
m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Finalize();
}
- ~CommandObjectWatchpointSetVariable () override {}
+ ~CommandObjectWatchpointSetVariable() override = default;
Options *
GetOptions () override
@@ -1055,7 +1044,7 @@ protected:
}
else
{
- const char *error_cstr = error.AsCString(NULL);
+ const char *error_cstr = error.AsCString(nullptr);
if (error_cstr)
result.GetErrorStream().Printf("error: %s\n", error_cstr);
else
@@ -1089,7 +1078,7 @@ protected:
{
result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%" PRIu64 ", variable expression='%s').\n",
addr, (uint64_t)size, command.GetArgumentAtIndex(0));
- if (error.AsCString(NULL))
+ if (error.AsCString(nullptr))
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
}
@@ -1110,24 +1099,23 @@ private:
class CommandObjectWatchpointSetExpression : public CommandObjectRaw
{
public:
-
CommandObjectWatchpointSetExpression (CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "watchpoint set expression",
- "Set a watchpoint on an address by supplying an expression. "
- "Use the '-w' option to specify the type of watchpoint and "
- "the '-x' option to specify the byte size to watch for. "
- "If no '-w' option is specified, it defaults to write. "
- "If no '-x' option is specified, it defaults to the target's "
- "pointer byte size. "
- "Note that there are limited hardware resources for watchpoints. "
- "If watchpoint setting fails, consider disable/delete existing ones "
- "to free up resources.",
- NULL,
- eCommandRequiresFrame |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
+ CommandObjectRaw(interpreter,
+ "watchpoint set expression",
+ "Set a watchpoint on an address by supplying an expression. "
+ "Use the '-w' option to specify the type of watchpoint and "
+ "the '-s' option to specify the byte size to watch for. "
+ "If no '-w' option is specified, it defaults to write. "
+ "If no '-s' option is specified, it defaults to the target's "
+ "pointer byte size. "
+ "Note that there are limited hardware resources for watchpoints. "
+ "If watchpoint setting fails, consider disable/delete existing ones "
+ "to free up resources.",
+ nullptr,
+ eCommandRequiresFrame |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_option_group (interpreter),
m_option_watchpoint ()
{
@@ -1135,7 +1123,7 @@ public:
R"(
Examples:
-(lldb) watchpoint set expression -w write -x 1 -- foo + 32
+(lldb) watchpoint set expression -w write -s 1 -- foo + 32
Watches write access for the 1-byte region pointed to by the address 'foo + 32')"
);
@@ -1153,13 +1141,12 @@ Examples:
// Push the data for the only argument into the m_arguments vector.
m_arguments.push_back (arg);
- // Absorb the '-w' and '-x' options into our option group.
+ // Absorb the '-w' and '-s' options into our option group.
m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Finalize();
}
-
- ~CommandObjectWatchpointSetExpression () override {}
+ ~CommandObjectWatchpointSetExpression() override = default;
// Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
bool
@@ -1181,11 +1168,11 @@ protected:
StackFrame *frame = m_exe_ctx.GetFramePtr();
Args command(raw_command);
- const char *expr = NULL;
+ const char *expr = nullptr;
if (raw_command[0] == '-')
{
// We have some options and these options MUST end with --.
- const char *end_options = NULL;
+ const char *end_options = nullptr;
const char *s = raw_command;
while (s && s[0])
{
@@ -1220,7 +1207,7 @@ protected:
}
}
- if (expr == NULL)
+ if (expr == nullptr)
expr = raw_command;
// If no argument is present, issue an error message. There's no way to set a watchpoint.
@@ -1300,7 +1287,7 @@ protected:
{
result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%" PRIu64 ").\n",
addr, (uint64_t)size);
- if (error.AsCString(NULL))
+ if (error.AsCString(nullptr))
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
}
@@ -1321,21 +1308,16 @@ private:
class CommandObjectWatchpointSet : public CommandObjectMultiword
{
public:
-
- CommandObjectWatchpointSet (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "watchpoint set",
- "A set of commands for setting a watchpoint.",
- "watchpoint set <subcommand> [<subcommand-options>]")
+ CommandObjectWatchpointSet(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "watchpoint set", "Commands for setting a watchpoint.",
+ "watchpoint set <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("variable", CommandObjectSP (new CommandObjectWatchpointSetVariable (interpreter)));
LoadSubCommand ("expression", CommandObjectSP (new CommandObjectWatchpointSetExpression (interpreter)));
}
-
- ~CommandObjectWatchpointSet () override {}
-
+ ~CommandObjectWatchpointSet() override = default;
};
//-------------------------------------------------------------------------
@@ -1343,11 +1325,9 @@ public:
//-------------------------------------------------------------------------
#pragma mark MultiwordWatchpoint
-CommandObjectMultiwordWatchpoint::CommandObjectMultiwordWatchpoint(CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "watchpoint",
- "A set of commands for operating on watchpoints.",
- "watchpoint <command> [<command-options>]")
+CommandObjectMultiwordWatchpoint::CommandObjectMultiwordWatchpoint(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "watchpoint", "Commands for operating on watchpoints.",
+ "watchpoint <subcommand> [<command-options>]")
{
CommandObjectSP list_command_object (new CommandObjectWatchpointList (interpreter));
CommandObjectSP enable_command_object (new CommandObjectWatchpointEnable (interpreter));
@@ -1377,7 +1357,4 @@ CommandObjectMultiwordWatchpoint::CommandObjectMultiwordWatchpoint(CommandInterp
LoadSubCommand ("set", set_command_object);
}
-CommandObjectMultiwordWatchpoint::~CommandObjectMultiwordWatchpoint()
-{
-}
-
+CommandObjectMultiwordWatchpoint::~CommandObjectMultiwordWatchpoint() = default;
diff --git a/source/Commands/CommandObjectWatchpointCommand.cpp b/source/Commands/CommandObjectWatchpointCommand.cpp
index 2fa849f97674..0ae1850b5e28 100644
--- a/source/Commands/CommandObjectWatchpointCommand.cpp
+++ b/source/Commands/CommandObjectWatchpointCommand.cpp
@@ -9,11 +9,12 @@
// C Includes
// C++ Includes
+#include <vector>
-
+// Other libraries and framework includes
+// Project includes
#include "CommandObjectWatchpointCommand.h"
#include "CommandObjectWatchpoint.h"
-
#include "lldb/Core/IOHandler.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -23,8 +24,6 @@
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/State.h"
-#include <vector>
-
using namespace lldb;
using namespace lldb_private;
@@ -32,20 +31,17 @@ using namespace lldb_private;
// CommandObjectWatchpointCommandAdd
//-------------------------------------------------------------------------
-
class CommandObjectWatchpointCommandAdd :
public CommandObjectParsed,
public IOHandlerDelegateMultiline
{
public:
-
- CommandObjectWatchpointCommandAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "add",
- "Add a set of commands to a watchpoint, to be executed whenever the watchpoint is hit.",
- NULL),
- IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand),
- m_options (interpreter)
+ CommandObjectWatchpointCommandAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "add",
+ "Add a set of LLDB commands to a watchpoint, to be executed whenever the watchpoint is hit.", nullptr),
+ IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand),
+ m_options(interpreter)
{
SetHelpLong (
R"(
@@ -169,7 +165,7 @@ are no syntax errors may indicate that a function was declared but never called.
m_arguments.push_back (arg);
}
- ~CommandObjectWatchpointCommandAdd () override {}
+ ~CommandObjectWatchpointCommandAdd() override = default;
Options *
GetOptions () override
@@ -187,8 +183,7 @@ are no syntax errors may indicate that a function was declared but never called.
output_sp->Flush();
}
}
-
-
+
void
IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override
{
@@ -199,7 +194,7 @@ are no syntax errors may indicate that a function was declared but never called.
if (wp_options)
{
std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
- if (data_ap.get())
+ if (data_ap)
{
data_ap->user_source.SplitIntoLines(line);
BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
@@ -234,8 +229,6 @@ are no syntax errors may indicate that a function was declared but never called.
BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
wp_options->SetCallback (WatchpointOptionsCallbackFunction, baton_sp);
-
- return;
}
static bool
@@ -244,10 +237,9 @@ are no syntax errors may indicate that a function was declared but never called.
lldb::user_id_t watch_id)
{
bool ret_value = true;
- if (baton == NULL)
+ if (baton == nullptr)
return true;
-
-
+
WatchpointOptions::CommandData *data = (WatchpointOptions::CommandData *) baton;
StringList &commands = data->user_source;
@@ -288,7 +280,6 @@ are no syntax errors may indicate that a function was declared but never called.
class CommandOptions : public Options
{
public:
-
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
m_use_commands (false),
@@ -300,7 +291,7 @@ are no syntax errors may indicate that a function was declared but never called.
{
}
- ~CommandOptions () override {}
+ ~CommandOptions() override = default;
Error
SetOptionValue (uint32_t option_idx, const char *option_arg) override
@@ -321,14 +312,8 @@ are no syntax errors may indicate that a function was declared but never called.
eScriptLanguageNone,
error);
- if (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault)
- {
- m_use_script_language = true;
- }
- else
- {
- m_use_script_language = false;
- }
+ m_use_script_language =
+ (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault);
break;
case 'e':
@@ -341,11 +326,9 @@ are no syntax errors may indicate that a function was declared but never called.
break;
case 'F':
- {
- m_use_one_liner = false;
- m_use_script_language = true;
- m_function_name.assign(option_arg);
- }
+ m_use_one_liner = false;
+ m_use_script_language = true;
+ m_function_name.assign(option_arg);
break;
default:
@@ -353,6 +336,7 @@ are no syntax errors may indicate that a function was declared but never called.
}
return error;
}
+
void
OptionParsingStarting () override
{
@@ -395,7 +379,7 @@ protected:
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("There is not a current executable; there are no watchpoints to which to add commands");
result.SetStatus (eReturnStatusFailed);
@@ -412,7 +396,7 @@ protected:
return false;
}
- if (m_options.m_use_script_language == false && m_options.m_function_name.size())
+ if (!m_options.m_use_script_language && !m_options.m_function_name.empty())
{
result.AppendError ("need to enable scripting to have a function run as a watchpoint command");
result.SetStatus (eReturnStatusFailed);
@@ -436,11 +420,11 @@ protected:
{
Watchpoint *wp = target->GetWatchpointList().FindByID (cur_wp_id).get();
// Sanity check wp first.
- if (wp == NULL) continue;
+ if (wp == nullptr) continue;
WatchpointOptions *wp_options = wp->GetOptions();
// Skip this watchpoint if wp_options is not good.
- if (wp_options == NULL) continue;
+ if (wp_options == nullptr) continue;
// If we are using script language, get the script interpreter
// in order to set or collect command callback. Otherwise, call
@@ -456,7 +440,7 @@ protected:
// Special handling for using a Python function by name
// instead of extending the watchpoint callback data structures, we just automatize
// what the user would do manually: make their watchpoint command be a function call
- else if (m_options.m_function_name.size())
+ else if (!m_options.m_function_name.empty())
{
std::string oneliner(m_options.m_function_name);
oneliner += "(frame, wp, internal_dict)";
@@ -489,7 +473,6 @@ private:
CommandOptions m_options;
};
-
// FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting
// language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper.
@@ -499,25 +482,25 @@ g_script_option_enumeration[4] =
{ eScriptLanguageNone, "command", "Commands are in the lldb command interpreter language"},
{ eScriptLanguagePython, "python", "Commands are in the Python language."},
{ eSortOrderByName, "default-script", "Commands are in the default scripting language."},
- { 0, NULL, NULL }
+ { 0, nullptr, nullptr }
};
OptionDefinition
CommandObjectWatchpointCommandAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner,
+ { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner,
"Specify a one-line watchpoint command inline. Be sure to surround it with quotes." },
- { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
+ { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
"Specify whether watchpoint command execution should terminate on error." },
- { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, NULL, g_script_option_enumeration, 0, eArgTypeNone,
+ { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, g_script_option_enumeration, 0, eArgTypeNone,
"Specify the language for the commands - if none is specified, the lldb command interpreter will be used."},
- { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction,
+ { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction,
"Give the name of a Python function to run as command for this watchpoint. Be sure to give a module name if appropriate."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
//-------------------------------------------------------------------------
@@ -528,10 +511,10 @@ class CommandObjectWatchpointCommandDelete : public CommandObjectParsed
{
public:
CommandObjectWatchpointCommandDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "delete",
- "Delete the set of commands from a watchpoint.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "delete",
+ "Delete the set of commands from a watchpoint.",
+ nullptr)
{
CommandArgumentEntry arg;
CommandArgumentData wp_id_arg;
@@ -547,8 +530,7 @@ public:
m_arguments.push_back (arg);
}
-
- ~CommandObjectWatchpointCommandDelete () override {}
+ ~CommandObjectWatchpointCommandDelete() override = default;
protected:
bool
@@ -556,7 +538,7 @@ protected:
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("There is not a current executable; there are no watchpoints from which to delete commands");
result.SetStatus (eReturnStatusFailed);
@@ -619,10 +601,10 @@ class CommandObjectWatchpointCommandList : public CommandObjectParsed
{
public:
CommandObjectWatchpointCommandList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "list",
- "List the script or set of commands to be executed when the watchpoint is hit.",
- NULL)
+ CommandObjectParsed(interpreter,
+ "list",
+ "List the script or set of commands to be executed when the watchpoint is hit.",
+ nullptr)
{
CommandArgumentEntry arg;
CommandArgumentData wp_id_arg;
@@ -638,7 +620,7 @@ public:
m_arguments.push_back (arg);
}
- ~CommandObjectWatchpointCommandList () override {}
+ ~CommandObjectWatchpointCommandList() override = default;
protected:
bool
@@ -646,7 +628,7 @@ protected:
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ if (target == nullptr)
{
result.AppendError ("There is not a current executable; there are no watchpoints for which to list commands");
result.SetStatus (eReturnStatusFailed);
@@ -725,11 +707,10 @@ protected:
// CommandObjectWatchpointCommand
//-------------------------------------------------------------------------
-CommandObjectWatchpointCommand::CommandObjectWatchpointCommand (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "command",
- "A set of commands for adding, removing and examining bits of code to be executed when the watchpoint is hit (watchpoint 'commmands').",
- "command <sub-command> [<sub-command-options>] <watchpoint-id>")
+CommandObjectWatchpointCommand::CommandObjectWatchpointCommand(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "command", "Commands for adding, removing and examining LLDB commands "
+ "executed when the watchpoint is hit (watchpoint 'commmands').",
+ "command <sub-command> [<sub-command-options>] <watchpoint-id>")
{
CommandObjectSP add_command_object (new CommandObjectWatchpointCommandAdd (interpreter));
CommandObjectSP delete_command_object (new CommandObjectWatchpointCommandDelete (interpreter));
@@ -744,8 +725,4 @@ CommandObjectWatchpointCommand::CommandObjectWatchpointCommand (CommandInterpret
LoadSubCommand ("list", list_command_object);
}
-CommandObjectWatchpointCommand::~CommandObjectWatchpointCommand ()
-{
-}
-
-
+CommandObjectWatchpointCommand::~CommandObjectWatchpointCommand() = default;
diff --git a/source/Commands/Makefile b/source/Commands/Makefile
deleted file mode 100644
index 1a66485a0c21..000000000000
--- a/source/Commands/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- source/Commands/Makefile ----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LIBRARYNAME := lldbCommands
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
-
-EXTRA_OPTIONS += -Wno-four-char-constants \ No newline at end of file
diff --git a/source/Core/Address.cpp b/source/Core/Address.cpp
index 83100dea93bc..f3ea1718d6f2 100644
--- a/source/Core/Address.cpp
+++ b/source/Core/Address.cpp
@@ -8,6 +8,13 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/Address.h"
+
+// C Includes
+// C++ Includes
+#include "llvm/ADT/Triple.h"
+
+// Other libraries and framework includes
+// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/Block.h"
@@ -20,15 +27,13 @@
#include "lldb/Target/Target.h"
#include "lldb/Symbol/SymbolVendor.h"
-#include "llvm/ADT/Triple.h"
-
using namespace lldb;
using namespace lldb_private;
static size_t
ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
{
- if (exe_scope == NULL)
+ if (exe_scope == nullptr)
return 0;
TargetSP target_sp (exe_scope->CalculateTarget());
@@ -46,7 +51,7 @@ GetByteOrderAndAddressSize (ExecutionContextScope *exe_scope, const Address &add
{
byte_order = eByteOrderInvalid;
addr_size = 0;
- if (exe_scope == NULL)
+ if (exe_scope == nullptr)
return false;
TargetSP target_sp (exe_scope->CalculateTarget());
@@ -72,7 +77,7 @@ static uint64_t
ReadUIntMax64 (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, bool &success)
{
uint64_t uval64 = 0;
- if (exe_scope == NULL || byte_size > sizeof(uint64_t))
+ if (exe_scope == nullptr || byte_size > sizeof(uint64_t))
{
success = false;
return 0;
@@ -99,10 +104,9 @@ ReadUIntMax64 (ExecutionContextScope *exe_scope, const Address &address, uint32_
static bool
ReadAddress (ExecutionContextScope *exe_scope, const Address &address, uint32_t pointer_size, Address &deref_so_addr)
{
- if (exe_scope == NULL)
+ if (exe_scope == nullptr)
return false;
-
bool success = false;
addr_t deref_addr = ReadUIntMax64 (exe_scope, address, pointer_size, success);
if (success)
@@ -140,7 +144,7 @@ ReadAddress (ExecutionContextScope *exe_scope, const Address &address, uint32_t
static bool
DumpUInt (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, Stream* strm)
{
- if (exe_scope == NULL || byte_size == 0)
+ if (exe_scope == nullptr || byte_size == 0)
return 0;
std::vector<uint8_t> buf(byte_size, 0);
@@ -168,11 +172,10 @@ DumpUInt (ExecutionContextScope *exe_scope, const Address &address, uint32_t byt
return false;
}
-
static size_t
ReadCStringFromMemory (ExecutionContextScope *exe_scope, const Address &address, Stream *strm)
{
- if (exe_scope == NULL)
+ if (exe_scope == nullptr)
return 0;
const size_t k_buf_len = 256;
char buf[k_buf_len+1];
@@ -334,7 +337,7 @@ Address::GetCallableLoadAddress (Target *target, bool is_indirect) const
{
ProcessSP processSP = target->GetProcessSP();
Error error;
- if (processSP.get())
+ if (processSP)
{
code_addr = processSP->ResolveIndirectFunction(this, error);
if (!error.Success())
@@ -398,7 +401,7 @@ Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target, AddressCl
bool
Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
{
- // If the section was NULL, only load address is going to work unless we are
+ // If the section was nullptr, only load address is going to work unless we are
// trying to deref a pointer
SectionSP section_sp (GetSection());
if (!section_sp && style != DumpStyleResolvedPointerDescription)
@@ -442,9 +445,13 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
case DumpStyleModuleWithFileAddress:
if (section_sp)
{
- s->Printf("%s[", section_sp->GetModule()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
+ ModuleSP module_sp = section_sp->GetModule();
+ if (module_sp)
+ s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"));
+ else
+ s->Printf("%s[","<Unknown>");
}
- // Fall through
+ LLVM_FALLTHROUGH;
case DumpStyleFileAddress:
{
addr_t file_addr = GetFileAddress();
@@ -541,59 +548,55 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
break;
case eSectionTypeDataCStringPointers:
+ if (ReadAddress(exe_scope, *this, pointer_size, so_addr))
{
- if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
- {
#if VERBOSE_OUTPUT
- s->PutCString("(char *)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
- s->PutCString(": ");
+ s->PutCString("(char *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
+ s->PutCString(": ");
#endif
- showed_info = true;
- ReadCStringFromMemory (exe_scope, so_addr, s);
- }
+ showed_info = true;
+ ReadCStringFromMemory(exe_scope, so_addr, s);
}
break;
case eSectionTypeDataObjCMessageRefs:
+ if (ReadAddress(exe_scope, *this, pointer_size, so_addr))
{
- if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
+ if (target && so_addr.IsSectionOffset())
{
- if (target && so_addr.IsSectionOffset())
+ SymbolContext func_sc;
+ target->GetImages().ResolveSymbolContextForAddress(so_addr,
+ eSymbolContextEverything,
+ func_sc);
+ if (func_sc.function != nullptr || func_sc.symbol != nullptr)
{
- SymbolContext func_sc;
- target->GetImages().ResolveSymbolContextForAddress (so_addr,
- eSymbolContextEverything,
- func_sc);
- if (func_sc.function || func_sc.symbol)
- {
- showed_info = true;
+ showed_info = true;
#if VERBOSE_OUTPUT
- s->PutCString ("(objc_msgref *) -> { (func*)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
+ s->PutCString ("(objc_msgref *) -> { (func*)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
#else
- s->PutCString ("{ ");
+ s->PutCString ("{ ");
#endif
- Address cstr_addr(*this);
- cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
- func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false, true, true);
- if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr))
- {
+ Address cstr_addr(*this);
+ cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
+ func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false, true, true);
+ if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr))
+ {
#if VERBOSE_OUTPUT
- s->PutCString("), (char *)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
- s->PutCString(" (");
+ s->PutCString("), (char *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
+ s->PutCString(" (");
#else
- s->PutCString(", ");
+ s->PutCString(", ");
#endif
- ReadCStringFromMemory (exe_scope, so_addr, s);
- }
+ ReadCStringFromMemory (exe_scope, so_addr, s);
+ }
#if VERBOSE_OUTPUT
- s->PutCString(") }");
+ s->PutCString(") }");
#else
- s->PutCString(" }");
+ s->PutCString(" }");
#endif
- }
}
}
}
@@ -641,26 +644,24 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
case eSectionTypeDataPointers:
// Read the pointer data and display it
+ if (ReadAddress(exe_scope, *this, pointer_size, so_addr))
{
- if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
- {
- s->PutCString ("(void *)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
+ s->PutCString ("(void *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
- showed_info = true;
- if (so_addr.IsSectionOffset())
+ showed_info = true;
+ if (so_addr.IsSectionOffset())
+ {
+ SymbolContext pointer_sc;
+ if (target)
{
- SymbolContext pointer_sc;
- if (target)
+ target->GetImages().ResolveSymbolContextForAddress(so_addr,
+ eSymbolContextEverything,
+ pointer_sc);
+ if (pointer_sc.function != nullptr || pointer_sc.symbol != nullptr)
{
- target->GetImages().ResolveSymbolContextForAddress (so_addr,
- eSymbolContextEverything,
- pointer_sc);
- if (pointer_sc.function || pointer_sc.symbol)
- {
- s->PutCString(": ");
- pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false, true, true);
- }
+ s->PutCString(": ");
+ pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false, true, true);
}
}
}
@@ -677,7 +678,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
if (module_sp)
{
SymbolContext sc;
- module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything | eSymbolContextVariable, sc);
+ module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
if (sc.function || sc.symbol)
{
bool show_stop_context = true;
@@ -686,7 +687,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
const bool show_inlined_frames = true;
const bool show_function_arguments = (style != DumpStyleResolvedDescriptionNoFunctionArguments);
const bool show_function_name = (style != DumpStyleNoFunctionName);
- if (sc.function == NULL && sc.symbol != NULL)
+ if (sc.function == nullptr && sc.symbol != nullptr)
{
// If we have just a symbol make sure it is in the right section
if (sc.symbol->ValueIsAddress())
@@ -745,7 +746,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
// the last symbol that came before the address that we are
// looking up that has nothing to do with our address lookup.
if (sc.symbol->ValueIsAddress() && sc.symbol->GetAddressRef().GetSection() != GetSection())
- sc.symbol = NULL;
+ sc.symbol = nullptr;
}
sc.GetDescription(s, eDescriptionLevelBrief, target);
@@ -756,10 +757,11 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
bool stop_if_block_is_inlined_function = false;
VariableList variable_list;
sc.block->AppendVariables (can_create,
- get_parent_variables,
- stop_if_block_is_inlined_function,
+ get_parent_variables,
+ stop_if_block_is_inlined_function,
+ [](Variable*) { return true; },
&variable_list);
-
+
const size_t num_variables = variable_list.GetSize();
for (size_t var_idx = 0; var_idx < num_variables; ++var_idx)
{
@@ -792,6 +794,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
return false;
}
break;
+
case DumpStyleResolvedPointerDescription:
{
Process *process = exe_ctx.GetProcessPtr();
@@ -892,7 +895,7 @@ Address::CalculateSymbolContextCompileUnit () const
return sc.comp_unit;
}
}
- return NULL;
+ return nullptr;
}
Function *
@@ -909,7 +912,7 @@ Address::CalculateSymbolContextFunction () const
return sc.function;
}
}
- return NULL;
+ return nullptr;
}
Block *
@@ -926,7 +929,7 @@ Address::CalculateSymbolContextBlock () const
return sc.block;
}
}
- return NULL;
+ return nullptr;
}
Symbol *
@@ -943,7 +946,7 @@ Address::CalculateSymbolContextSymbol () const
return sc.symbol;
}
}
- return NULL;
+ return nullptr;
}
bool
@@ -980,11 +983,10 @@ Address::CompareFileAddress (const Address& a, const Address& b)
return 0;
}
-
int
Address::CompareLoadAddress (const Address& a, const Address& b, Target *target)
{
- assert (target != NULL);
+ assert(target != nullptr);
addr_t a_load_addr = a.GetLoadAddress (target);
addr_t b_load_addr = b.GetLoadAddress (target);
if (a_load_addr < b_load_addr)
@@ -1016,7 +1018,6 @@ Address::CompareModulePointerAndOffset (const Address& a, const Address& b)
return 0;
}
-
size_t
Address::MemorySize () const
{
@@ -1025,7 +1026,6 @@ Address::MemorySize () const
return sizeof(Address);
}
-
//----------------------------------------------------------------------
// NOTE: Be careful using this operator. It can correctly compare two
// addresses from the same Module correctly. It can't compare two
@@ -1081,7 +1081,6 @@ lldb_private::operator> (const Address& lhs, const Address& rhs)
}
}
-
// The operator == checks for exact equality only (same section, same offset)
bool
lldb_private::operator== (const Address& a, const Address& rhs)
@@ -1089,6 +1088,7 @@ lldb_private::operator== (const Address& a, const Address& rhs)
return a.GetOffset() == rhs.GetOffset() &&
a.GetSection() == rhs.GetSection();
}
+
// The operator != checks for exact inequality only (differing section, or
// different offset)
bool
@@ -1124,4 +1124,3 @@ Address::SetLoadAddress (lldb::addr_t load_addr, Target *target)
m_offset = load_addr;
return false;
}
-
diff --git a/source/Core/AddressRange.cpp b/source/Core/AddressRange.cpp
index ac64833884ee..072c2450836c 100644
--- a/source/Core/AddressRange.cpp
+++ b/source/Core/AddressRange.cpp
@@ -163,7 +163,7 @@ AddressRange::Dump(Stream *s, Target *target, Address::DumpStyle style, Address:
case Address::DumpStyleModuleWithFileAddress:
show_module = true;
- // fall through
+ LLVM_FALLTHROUGH;
case Address::DumpStyleFileAddress:
vmaddr = m_base_addr.GetFileAddress();
break;
diff --git a/source/Core/AddressResolverName.cpp b/source/Core/AddressResolverName.cpp
index 293002ad517f..dacc7d777f85 100644
--- a/source/Core/AddressResolverName.cpp
+++ b/source/Core/AddressResolverName.cpp
@@ -9,6 +9,9 @@
#include "lldb/Core/AddressResolverName.h"
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
@@ -20,16 +23,13 @@
using namespace lldb;
using namespace lldb_private;
-AddressResolverName::AddressResolverName
-(
- const char *func_name,
- AddressResolver::MatchType type
-) :
- AddressResolver (),
- m_func_name (func_name),
- m_class_name (NULL),
- m_regex (),
- m_match_type (type)
+AddressResolverName::AddressResolverName(const char *func_name,
+ AddressResolver::MatchType type) :
+ AddressResolver(),
+ m_func_name(func_name),
+ m_class_name(nullptr),
+ m_regex(),
+ m_match_type(type)
{
if (m_match_type == AddressResolver::Regexp)
{
@@ -43,50 +43,37 @@ AddressResolverName::AddressResolverName
}
}
-AddressResolverName::AddressResolverName
-(
- RegularExpression &func_regex
-) :
- AddressResolver (),
- m_func_name (NULL),
- m_class_name (NULL),
- m_regex (func_regex),
- m_match_type (AddressResolver::Regexp)
+AddressResolverName::AddressResolverName(RegularExpression &func_regex) :
+ AddressResolver(),
+ m_func_name(nullptr),
+ m_class_name(nullptr),
+ m_regex(func_regex),
+ m_match_type(AddressResolver::Regexp)
{
-
}
-AddressResolverName::AddressResolverName
-(
- const char *class_name,
- const char *method,
- AddressResolver::MatchType type
-) :
+AddressResolverName::AddressResolverName(const char *class_name,
+ const char *method,
+ AddressResolver::MatchType type) :
AddressResolver (),
m_func_name (method),
m_class_name (class_name),
m_regex (),
m_match_type (type)
{
-
}
-AddressResolverName::~AddressResolverName ()
-{
-}
+AddressResolverName::~AddressResolverName() = default;
// FIXME: Right now we look at the module level, and call the module's "FindFunctions".
// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables.
Searcher::CallbackReturn
-AddressResolverName::SearchCallback
-(
- SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool containing
-)
+AddressResolverName::SearchCallback(SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool containing)
{
SymbolContextList func_list;
SymbolContextList sym_list;
@@ -116,13 +103,13 @@ AddressResolverName::SearchCallback
context.module_sp->FindSymbolsWithNameAndType (m_func_name,
eSymbolTypeCode,
sym_list);
- context.module_sp->FindFunctions (m_func_name,
- NULL,
- eFunctionNameTypeAuto,
- include_symbols,
- include_inlines,
- append,
- func_list);
+ context.module_sp->FindFunctions(m_func_name,
+ nullptr,
+ eFunctionNameTypeAuto,
+ include_symbols,
+ include_inlines,
+ append,
+ func_list);
}
break;
@@ -151,10 +138,10 @@ AddressResolverName::SearchCallback
{
for (i = 0; i < func_list.GetSize(); i++)
{
- if (func_list.GetContextAtIndex(i, sc) == false)
+ if (!func_list.GetContextAtIndex(i, sc))
continue;
- if (sc.function == NULL)
+ if (sc.function == nullptr)
continue;
uint32_t j = 0;
while (j < sym_list.GetSize())
@@ -250,4 +237,3 @@ AddressResolverName::GetDescription (Stream *s)
else
s->Printf("'%s'", m_func_name.AsCString());
}
-
diff --git a/source/Core/ArchSpec.cpp b/source/Core/ArchSpec.cpp
index ffe717f29c43..24aba81350a6 100644
--- a/source/Core/ArchSpec.cpp
+++ b/source/Core/ArchSpec.cpp
@@ -9,16 +9,19 @@
#include "lldb/Core/ArchSpec.h"
-#include <stdio.h>
-#include <errno.h>
-
+// C Includes
+// C++ Includes
+#include <cstdio>
+#include <cerrno>
#include <string>
+// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/Host.h"
+// Project includes
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/StringList.h"
#include "lldb/Host/Endian.h"
@@ -35,9 +38,6 @@
using namespace lldb;
using namespace lldb_private;
-#define ARCH_SPEC_SEPARATOR_CHAR '-'
-
-
static bool cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_inverse, bool enforce_exact_match);
namespace lldb_private {
@@ -53,7 +53,7 @@ namespace lldb_private {
const char * const name;
};
-}
+} // namespace lldb_private
// This core information can be looked using the ArchSpec::Core as the index
static const CoreDefinition g_core_definitions[] =
@@ -130,6 +130,8 @@ static const CoreDefinition g_core_definitions[] =
{ eByteOrderBig , 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "powerpc64" },
{ eByteOrderBig , 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" },
+ { eByteOrderBig , 8, 2, 6, llvm::Triple::systemz, ArchSpec::eCore_s390x_generic , "s390x" },
+
{ eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" },
{ eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic , "sparcv9" },
@@ -156,7 +158,6 @@ static const CoreDefinition g_core_definitions[] =
// you will need to comment out the corresponding ArchSpec::Core enumeration.
static_assert(sizeof(g_core_definitions) / sizeof(CoreDefinition) == ArchSpec::kNumCores, "make sure we have one core definition for each core");
-
struct ArchDefinitionEntry
{
ArchSpec::Core core;
@@ -174,14 +175,12 @@ struct ArchDefinition
const char *name;
};
-
size_t
ArchSpec::AutoComplete (const char *name, StringList &matches)
{
- uint32_t i;
if (name && name[0])
{
- for (i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
+ for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
{
if (NameMatches(g_core_definitions[i].name, eNameMatchStartsWith, name))
matches.AppendString (g_core_definitions[i].name);
@@ -189,14 +188,12 @@ ArchSpec::AutoComplete (const char *name, StringList &matches)
}
else
{
- for (i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
+ for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
matches.AppendString (g_core_definitions[i].name);
}
return matches.GetSize();
}
-
-
#define CPU_ANY (UINT32_MAX)
//===----------------------------------------------------------------------===//
@@ -205,6 +202,7 @@ ArchSpec::AutoComplete (const char *name, StringList &matches)
// architecture names to cpu types and subtypes. The ordering is important and
// allows the precedence to be set when the table is built.
#define SUBTYPE_MASK 0x00FFFFFFu
+
static const ArchDefinitionEntry g_macho_arch_entries[] =
{
{ ArchSpec::eCore_arm_generic , llvm::MachO::CPU_TYPE_ARM , CPU_ANY, UINT32_MAX , UINT32_MAX },
@@ -267,6 +265,7 @@ static const ArchDefinitionEntry g_macho_arch_entries[] =
{ ArchSpec::eCore_uknownMach32 , 0 , 0 , 0xFF000000u, 0x00000000u },
{ ArchSpec::eCore_uknownMach64 , llvm::MachO::CPU_ARCH_ABI64 , 0 , 0xFF000000u, 0x00000000u }
};
+
static const ArchDefinition g_macho_arch_def = {
eArchTypeMachO,
llvm::array_lengthof(g_macho_arch_entries),
@@ -288,6 +287,7 @@ static const ArchDefinitionEntry g_elf_arch_entries[] =
{ ArchSpec::eCore_ppc64_generic , llvm::ELF::EM_PPC64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC64
{ ArchSpec::eCore_arm_generic , llvm::ELF::EM_ARM , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM
{ ArchSpec::eCore_arm_aarch64 , llvm::ELF::EM_AARCH64, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM64
+ { ArchSpec::eCore_s390x_generic , llvm::ELF::EM_S390 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // SystemZ
{ ArchSpec::eCore_sparc9_generic , llvm::ELF::EM_SPARCV9, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // SPARC V9
{ ArchSpec::eCore_x86_64_x86_64 , llvm::ELF::EM_X86_64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // AMD64
{ ArchSpec::eCore_mips32 , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips32, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips32
@@ -346,7 +346,6 @@ static const size_t k_num_arch_definitions = llvm::array_lengthof(g_arch_definit
//===----------------------------------------------------------------------===//
// Static helper functions.
-
// Get the architecture definition for a given object type.
static const ArchDefinition *
FindArchDefinition (ArchitectureType arch_type)
@@ -357,7 +356,7 @@ FindArchDefinition (ArchitectureType arch_type)
if (def->type == arch_type)
return def;
}
- return NULL;
+ return nullptr;
}
// Get an architecture definition by name.
@@ -369,7 +368,7 @@ FindCoreDefinition (llvm::StringRef name)
if (name.equals_lower(g_core_definitions[i].name))
return &g_core_definitions[i];
}
- return NULL;
+ return nullptr;
}
static inline const CoreDefinition *
@@ -377,15 +376,15 @@ FindCoreDefinition (ArchSpec::Core core)
{
if (core >= 0 && core < llvm::array_lengthof(g_core_definitions))
return &g_core_definitions[core];
- return NULL;
+ return nullptr;
}
// Get a definition entry by cpu type and subtype.
static const ArchDefinitionEntry *
FindArchDefinitionEntry (const ArchDefinition *def, uint32_t cpu, uint32_t sub)
{
- if (def == NULL)
- return NULL;
+ if (def == nullptr)
+ return nullptr;
const ArchDefinitionEntry *entries = def->entries;
for (size_t i = 0; i < def->num_entries; ++i)
@@ -394,14 +393,14 @@ FindArchDefinitionEntry (const ArchDefinition *def, uint32_t cpu, uint32_t sub)
if (entries[i].sub == (sub & entries[i].sub_mask))
return &entries[i];
}
- return NULL;
+ return nullptr;
}
static const ArchDefinitionEntry *
FindArchDefinitionEntry (const ArchDefinition *def, ArchSpec::Core core)
{
- if (def == NULL)
- return NULL;
+ if (def == nullptr)
+ return nullptr;
const ArchDefinitionEntry *entries = def->entries;
for (size_t i = 0; i < def->num_entries; ++i)
@@ -409,7 +408,7 @@ FindArchDefinitionEntry (const ArchDefinition *def, ArchSpec::Core core)
if (entries[i].core == core)
return &entries[i];
}
- return NULL;
+ return nullptr;
}
//===----------------------------------------------------------------------===//
@@ -467,9 +466,7 @@ ArchSpec::ArchSpec (ArchitectureType arch_type, uint32_t cpu, uint32_t subtype)
SetArchitecture (arch_type, cpu, subtype);
}
-ArchSpec::~ArchSpec()
-{
-}
+ArchSpec::~ArchSpec() = default;
//===----------------------------------------------------------------------===//
// Assignment and initialization.
@@ -501,7 +498,6 @@ ArchSpec::Clear()
//===----------------------------------------------------------------------===//
// Predicates.
-
const char *
ArchSpec::GetArchitectureName () const
{
@@ -511,6 +507,68 @@ ArchSpec::GetArchitectureName () const
return "unknown";
}
+bool
+ArchSpec::IsMIPS() const
+{
+ const llvm::Triple::ArchType machine = GetMachine();
+ if(machine == llvm::Triple::mips ||
+ machine == llvm::Triple::mipsel ||
+ machine == llvm::Triple::mips64 ||
+ machine == llvm::Triple::mips64el)
+ return true;
+ return false;
+}
+
+std::string
+ArchSpec::GetClangTargetCPU ()
+{
+ std::string cpu;
+ const llvm::Triple::ArchType machine = GetMachine();
+
+ if (machine == llvm::Triple::mips ||
+ machine == llvm::Triple::mipsel ||
+ machine == llvm::Triple::mips64 ||
+ machine == llvm::Triple::mips64el)
+ {
+ switch (m_core)
+ {
+ case ArchSpec::eCore_mips32:
+ case ArchSpec::eCore_mips32el:
+ cpu = "mips32"; break;
+ case ArchSpec::eCore_mips32r2:
+ case ArchSpec::eCore_mips32r2el:
+ cpu = "mips32r2"; break;
+ case ArchSpec::eCore_mips32r3:
+ case ArchSpec::eCore_mips32r3el:
+ cpu = "mips32r3"; break;
+ case ArchSpec::eCore_mips32r5:
+ case ArchSpec::eCore_mips32r5el:
+ cpu = "mips32r5"; break;
+ case ArchSpec::eCore_mips32r6:
+ case ArchSpec::eCore_mips32r6el:
+ cpu = "mips32r6"; break;
+ case ArchSpec::eCore_mips64:
+ case ArchSpec::eCore_mips64el:
+ cpu = "mips64"; break;
+ case ArchSpec::eCore_mips64r2:
+ case ArchSpec::eCore_mips64r2el:
+ cpu = "mips64r2"; break;
+ case ArchSpec::eCore_mips64r3:
+ case ArchSpec::eCore_mips64r3el:
+ cpu = "mips64r3"; break;
+ case ArchSpec::eCore_mips64r5:
+ case ArchSpec::eCore_mips64r5el:
+ cpu = "mips64r5"; break;
+ case ArchSpec::eCore_mips64r6:
+ case ArchSpec::eCore_mips64r6el:
+ cpu = "mips64r6"; break;
+ default:
+ break;
+ }
+ }
+ return cpu;
+}
+
uint32_t
ArchSpec::GetMachOCPUType () const
{
@@ -680,7 +738,6 @@ ArchSpec::SetTriple (const llvm::Triple &triple)
Clear();
}
-
return IsValid();
}
@@ -690,7 +747,7 @@ ParseMachCPUDashSubtypeTriple (const char *triple_cstr, ArchSpec &arch)
// Accept "12-10" or "12.10" as cpu type/subtype
if (isdigit(triple_cstr[0]))
{
- char *end = NULL;
+ char *end = nullptr;
errno = 0;
uint32_t cpu = (uint32_t)::strtoul (triple_cstr, &end, 0);
if (errno == 0 && cpu != 0 && end && ((*end == '-') || (*end == '.')))
@@ -729,6 +786,7 @@ ParseMachCPUDashSubtypeTriple (const char *triple_cstr, ArchSpec &arch)
}
return false;
}
+
bool
ArchSpec::SetTriple (const char *triple_cstr)
{
@@ -855,6 +913,17 @@ ArchSpec::MergeFrom(const ArchSpec &other)
if (other.TripleVendorWasSpecified())
GetTriple().setEnvironment(other.GetTriple().getEnvironment());
}
+ // If this and other are both arm ArchSpecs and this ArchSpec is a generic "some kind of arm"
+ // spec but the other ArchSpec is a specific arm core, adopt the specific arm core.
+ if (GetTriple().getArch() == llvm::Triple::arm
+ && other.GetTriple().getArch() == llvm::Triple::arm
+ && IsCompatibleMatch (other)
+ && GetCore() == ArchSpec::eCore_arm_generic
+ && other.GetCore() != ArchSpec::eCore_arm_generic)
+ {
+ m_core = other.GetCore();
+ CoreUpdated (true);
+ }
}
bool
@@ -945,6 +1014,30 @@ ArchSpec::IsCompatibleMatch (const ArchSpec& rhs) const
return IsEqualTo (rhs, false);
}
+static bool
+isCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, llvm::Triple::EnvironmentType rhs)
+{
+ if (lhs == rhs)
+ return true;
+
+ // If any of the environment is unknown then they are compatible
+ if (lhs == llvm::Triple::UnknownEnvironment || rhs == llvm::Triple::UnknownEnvironment)
+ return true;
+
+ // If one of the environment is Android and the other one is EABI then they are considered to
+ // be compatible. This is required as a workaround for shared libraries compiled for Android
+ // without the NOTE section indicating that they are using the Android ABI.
+ if ((lhs == llvm::Triple::Android && rhs == llvm::Triple::EABI) ||
+ (rhs == llvm::Triple::Android && lhs == llvm::Triple::EABI) ||
+ (lhs == llvm::Triple::GNUEABI && rhs == llvm::Triple::EABI) ||
+ (rhs == llvm::Triple::GNUEABI && lhs == llvm::Triple::EABI) ||
+ (lhs == llvm::Triple::GNUEABIHF && rhs == llvm::Triple::EABIHF) ||
+ (rhs == llvm::Triple::GNUEABIHF && lhs == llvm::Triple::EABIHF))
+ return true;
+
+ return false;
+}
+
bool
ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const
{
@@ -999,14 +1092,9 @@ ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const
const llvm::Triple::EnvironmentType lhs_triple_env = lhs_triple.getEnvironment();
const llvm::Triple::EnvironmentType rhs_triple_env = rhs_triple.getEnvironment();
-
- if (lhs_triple_env != rhs_triple_env)
- {
- // Only fail if both environment types are not unknown
- if (lhs_triple_env != llvm::Triple::UnknownEnvironment &&
- rhs_triple_env != llvm::Triple::UnknownEnvironment)
- return false;
- }
+
+ if (!isCompatibleEnvironment(lhs_triple_env, rhs_triple_env))
+ return false;
return true;
}
return false;
@@ -1050,7 +1138,7 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in
case ArchSpec::eCore_arm_generic:
if (enforce_exact_match)
break;
- // Fall through to case below
+ LLVM_FALLTHROUGH;
case ArchSpec::kCore_arm_any:
if (core2 >= ArchSpec::kCore_arm_first && core2 <= ArchSpec::kCore_arm_last)
return true;
@@ -1207,6 +1295,7 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in
return true;
try_inverse = false;
}
+ break;
case ArchSpec::eCore_mips64:
if (!enforce_exact_match)
@@ -1217,6 +1306,7 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in
return true;
try_inverse = false;
}
+ break;
case ArchSpec::eCore_mips64el:
if (!enforce_exact_match)
@@ -1227,6 +1317,7 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in
return true;
try_inverse = false;
}
+ break;
case ArchSpec::eCore_mips64r2:
case ArchSpec::eCore_mips64r3:
@@ -1287,7 +1378,6 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in
{
if (core2 == ArchSpec::eCore_mips32el || core2 == ArchSpec::eCore_mips32r6el)
return true;
- return true;
}
break;
@@ -1393,7 +1483,7 @@ StopInfoOverrideCallbackTypeARM(lldb_private::Thread &thread)
if (opcode <= UINT32_MAX)
{
const uint32_t condition = Bits32((uint32_t)opcode, 31, 28);
- if (ARMConditionPassed(condition, cpsr) == false)
+ if (!ARMConditionPassed(condition, cpsr))
{
// We ARE stopped on an ARM instruction whose condition doesn't
// pass so this instruction won't get executed.
@@ -1410,7 +1500,7 @@ StopInfoOverrideCallbackTypeARM(lldb_private::Thread &thread)
if (ITSTATE != 0)
{
const uint32_t condition = Bits32(ITSTATE, 7, 4);
- if (ARMConditionPassed(condition, cpsr) == false)
+ if (!ARMConditionPassed(condition, cpsr))
{
// We ARE stopped in a Thumb IT instruction on an instruction whose
// condition doesn't pass so this instruction won't get executed.
@@ -1429,7 +1519,7 @@ ArchSpec::GetStopInfoOverrideCallback () const
const llvm::Triple::ArchType machine = GetMachine();
if (machine == llvm::Triple::arm)
return StopInfoOverrideCallbackTypeARM;
- return NULL;
+ return nullptr;
}
bool
@@ -1476,6 +1566,31 @@ ArchSpec::PiecewiseTripleCompare (const ArchSpec &other,
env_different = (me.getEnvironment() != them.getEnvironment());
}
+bool
+ArchSpec::IsAlwaysThumbInstructions () const
+{
+ std::string Error;
+ if (GetTriple().getArch() == llvm::Triple::arm || GetTriple().getArch() == llvm::Triple::thumb)
+ {
+ // v. https://en.wikipedia.org/wiki/ARM_Cortex-M
+ //
+ // Cortex-M0 through Cortex-M7 are ARM processor cores which can only
+ // execute thumb instructions. We map the cores to arch names like this:
+ //
+ // Cortex-M0, Cortex-M0+, Cortex-M1: armv6m
+ // Cortex-M3: armv7m
+ // Cortex-M4, Cortex-M7: armv7em
+
+ if (GetCore() == ArchSpec::Core::eCore_arm_armv7m
+ || GetCore() == ArchSpec::Core::eCore_arm_armv7em
+ || GetCore() == ArchSpec::Core::eCore_arm_armv6m)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
void
ArchSpec::DumpTriple(Stream &s) const
{
@@ -1483,10 +1598,14 @@ ArchSpec::DumpTriple(Stream &s) const
llvm::StringRef arch_str = triple.getArchName();
llvm::StringRef vendor_str = triple.getVendorName();
llvm::StringRef os_str = triple.getOSName();
+ llvm::StringRef environ_str = triple.getEnvironmentName();
s.Printf("%s-%s-%s",
arch_str.empty() ? "*" : arch_str.str().c_str(),
vendor_str.empty() ? "*" : vendor_str.str().c_str(),
os_str.empty() ? "*" : os_str.str().c_str()
);
+
+ if (!environ_str.empty())
+ s.Printf("-%s", environ_str.str().c_str());
}
diff --git a/source/Core/Broadcaster.cpp b/source/Core/Broadcaster.cpp
index 351487401f6b..30bc78b48220 100644
--- a/source/Core/Broadcaster.cpp
+++ b/source/Core/Broadcaster.cpp
@@ -15,23 +15,26 @@
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/Event.h"
+#include "lldb/Core/Listener.h"
#include "lldb/Core/StreamString.h"
using namespace lldb;
using namespace lldb_private;
-Broadcaster::Broadcaster (BroadcasterManager *manager, const char *name) :
- m_broadcaster_name (name),
- m_listeners (),
- m_listeners_mutex (Mutex::eMutexTypeRecursive),
- m_hijacking_listeners(),
- m_hijacking_masks(),
- m_manager (manager)
+Broadcaster::Broadcaster(BroadcasterManagerSP manager_sp, const char *name) :
+ m_broadcaster_sp(new BroadcasterImpl(*this)),
+ m_manager_sp(manager_sp),
+ m_broadcaster_name(name)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
log->Printf ("%p Broadcaster::Broadcaster(\"%s\")",
- static_cast<void*>(this), m_broadcaster_name.AsCString());
+ static_cast<void*>(this), GetBroadcasterName().AsCString());
+}
+
+Broadcaster::BroadcasterImpl::BroadcasterImpl(Broadcaster &broadcaster)
+ : m_broadcaster(broadcaster), m_listeners(), m_listeners_mutex(), m_hijacking_listeners(), m_hijacking_masks()
+{
}
Broadcaster::~Broadcaster()
@@ -47,35 +50,64 @@ Broadcaster::~Broadcaster()
void
Broadcaster::CheckInWithManager ()
{
- if (m_manager != NULL)
+ if (m_manager_sp)
{
- m_manager->SignUpListenersForBroadcaster(*this);
+ m_manager_sp->SignUpListenersForBroadcaster(*this);
}
}
void
-Broadcaster::Clear()
+Broadcaster::BroadcasterImpl::ListenerIterator (std::function <bool (const lldb::ListenerSP &listener_sp, uint32_t &event_mask)> const &callback)
{
- Mutex::Locker listeners_locker(m_listeners_mutex);
-
+ // Private iterator that should be used by everyone except BroadcasterImpl::RemoveListener().
+ // We have weak pointers to our listeners which means that at any point the listener can
+ // expire which means we will need to take it out of our list. To take care of this, we
+ // iterate and check that the weak pointer can be made into a valid shared pointer before
+ // we call the callback. If the weak pointer has expired, we remove it from our list.
+ collection::iterator pos = m_listeners.begin();
+ while (pos != m_listeners.end())
+ {
+ lldb::ListenerSP curr_listener_sp(pos->first.lock());
+ if (curr_listener_sp)
+ {
+ if (callback(curr_listener_sp, pos->second))
+ ++pos; // Keep iterating
+ else
+ return; // Done iterating
+ }
+ else
+ {
+ // The listener has been expired. Remove this entry.
+ pos = m_listeners.erase(pos);
+ }
+ }
+}
+
+void
+Broadcaster::BroadcasterImpl::Clear()
+{
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
// Make sure the listener forgets about this broadcaster. We do
// this in the broadcaster in case the broadcaster object initiates
// the removal.
-
- collection::iterator pos, end = m_listeners.end();
- for (pos = m_listeners.begin(); pos != end; ++pos)
- pos->first->BroadcasterWillDestruct (this);
+
+ ListenerIterator([this](const lldb::ListenerSP &curr_listener_sp, uint32_t &curr_event_mask) -> bool {
+ curr_listener_sp->BroadcasterWillDestruct (&m_broadcaster);
+ return true; // Keep iterating
+ });
m_listeners.clear();
}
-const ConstString &
-Broadcaster::GetBroadcasterName ()
+
+Broadcaster *
+Broadcaster::BroadcasterImpl::GetBroadcaster()
{
- return m_broadcaster_name;
+ return &m_broadcaster;
}
bool
-Broadcaster::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_broadcaster_name) const
+Broadcaster::BroadcasterImpl::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_broadcaster_name) const
{
uint32_t num_names_added = 0;
if (event_mask && !m_event_names.empty())
@@ -93,7 +125,7 @@ Broadcaster::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_bro
if (prefix_with_broadcaster_name)
{
- s.PutCString (m_broadcaster_name.GetCString());
+ s.PutCString (GetBroadcasterName());
s.PutChar('.');
}
s.PutCString(pos->second.c_str());
@@ -106,134 +138,149 @@ Broadcaster::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_bro
}
void
-Broadcaster::AddInitialEventsToListener (Listener *listener, uint32_t requested_events)
+Broadcaster::AddInitialEventsToListener (const lldb::ListenerSP &listener_sp, uint32_t requested_events)
{
-
}
uint32_t
-Broadcaster::AddListener (Listener* listener, uint32_t event_mask)
+Broadcaster::BroadcasterImpl::AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask)
{
- if (listener == NULL)
+ if (!listener_sp)
return 0;
- Mutex::Locker locker(m_listeners_mutex);
- collection::iterator pos, end = m_listeners.end();
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
- collection::iterator existing_pos = end;
// See if we already have this listener, and if so, update its mask
- uint32_t taken_event_types = 0;
- for (pos = m_listeners.begin(); pos != end; ++pos)
- {
- if (pos->first == listener)
- existing_pos = pos;
- // For now don't descriminate on who gets what
- // FIXME: Implement "unique listener for this bit" mask
- // taken_event_types |= pos->second;
- }
- // Each event bit in a Broadcaster object can only be used
- // by one listener
- uint32_t available_event_types = ~taken_event_types & event_mask;
+ bool handled = false;
- if (available_event_types)
- {
- // If we didn't find our listener, add it
- if (existing_pos == end)
- {
- // Grant a new listener the available event bits
- m_listeners.push_back(std::make_pair(listener, available_event_types));
- }
- else
+ ListenerIterator([this, &listener_sp, &handled, event_mask](const lldb::ListenerSP &curr_listener_sp, uint32_t &curr_event_mask) -> bool {
+ if (curr_listener_sp == listener_sp)
{
- // Grant the existing listener the available event bits
- existing_pos->second |= available_event_types;
+ handled = true;
+ curr_event_mask |= event_mask;
+ m_broadcaster.AddInitialEventsToListener (listener_sp, event_mask);
+ return false; // Stop iterating
}
+ return true; // Keep iterating
+ });
+
+ if (!handled)
+ {
+ // Grant a new listener the available event bits
+ m_listeners.push_back(std::make_pair(lldb::ListenerWP(listener_sp), event_mask));
// Individual broadcasters decide whether they have outstanding data when a
// listener attaches, and insert it into the listener with this method.
-
- AddInitialEventsToListener (listener, available_event_types);
+ m_broadcaster.AddInitialEventsToListener (listener_sp, event_mask);
}
// Return the event bits that were granted to the listener
- return available_event_types;
+ return event_mask;
}
bool
-Broadcaster::EventTypeHasListeners (uint32_t event_type)
+Broadcaster::BroadcasterImpl::EventTypeHasListeners (uint32_t event_type)
{
- Mutex::Locker locker (m_listeners_mutex);
-
- if (m_hijacking_listeners.size() > 0 && event_type & m_hijacking_masks.back())
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ if (!m_hijacking_listeners.empty() && event_type & m_hijacking_masks.back())
return true;
if (m_listeners.empty())
return false;
- collection::iterator pos, end = m_listeners.end();
- for (pos = m_listeners.begin(); pos != end; ++pos)
- {
- if (pos->second & event_type)
- return true;
- }
- return false;
+ bool result = false;
+ ListenerIterator([this, event_type, &result](const lldb::ListenerSP &curr_listener_sp, uint32_t &curr_event_mask) -> bool {
+
+ if (curr_event_mask & event_type)
+ {
+ result = true;
+ return false; // Stop iterating
+ }
+ else
+ {
+ return true; // Keep iterating
+ }
+ });
+ return result;
}
bool
-Broadcaster::RemoveListener (Listener* listener, uint32_t event_mask)
+Broadcaster::BroadcasterImpl::RemoveListener (lldb_private::Listener *listener, uint32_t event_mask)
{
- Mutex::Locker locker(m_listeners_mutex);
- collection::iterator pos, end = m_listeners.end();
- // See if we already have this listener, and if so, update its mask
- for (pos = m_listeners.begin(); pos != end; ++pos)
+ if (listener)
{
- if (pos->first == listener)
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+ collection::iterator pos = m_listeners.begin();
+ // See if we already have this listener, and if so, update its mask
+ while (pos != m_listeners.end())
{
- // Relinquish all event bits in "event_mask"
- pos->second &= ~event_mask;
- // If all bits have been relinquished then remove this listener
- if (pos->second == 0)
- m_listeners.erase (pos);
- return true;
+ lldb::ListenerSP curr_listener_sp(pos->first.lock());
+ if (curr_listener_sp)
+ {
+ if (curr_listener_sp.get() == listener)
+ {
+ // Relinquish all event bits in "event_mask"
+ pos->second &= ~event_mask;
+ // If all bits have been relinquished then remove this listener
+ if (pos->second == 0)
+ m_listeners.erase (pos);
+ return true;
+ }
+ ++pos;
+ }
+ else
+ {
+ // The listener has been destroyed since we couldn't turn the std::weak_ptr
+ // into a valid shared pointer, so we can remove it.
+ pos = m_listeners.erase (pos);
+ }
}
}
return false;
}
+bool
+Broadcaster::BroadcasterImpl::RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask)
+{
+ return RemoveListener (listener_sp.get(), event_mask);
+}
+
void
-Broadcaster::BroadcastEvent (EventSP &event_sp)
+Broadcaster::BroadcasterImpl::BroadcastEvent (EventSP &event_sp)
{
return PrivateBroadcastEvent (event_sp, false);
}
void
-Broadcaster::BroadcastEventIfUnique (EventSP &event_sp)
+Broadcaster::BroadcasterImpl::BroadcastEventIfUnique (EventSP &event_sp)
{
return PrivateBroadcastEvent (event_sp, true);
}
void
-Broadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
+Broadcaster::BroadcasterImpl::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
{
- // Can't add a NULL event...
- if (event_sp.get() == NULL)
+ // Can't add a nullptr event...
+ if (!event_sp)
return;
// Update the broadcaster on this event
- event_sp->SetBroadcaster (this);
+ event_sp->SetBroadcaster (&m_broadcaster);
const uint32_t event_type = event_sp->GetType();
- Mutex::Locker event_types_locker(m_listeners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ ListenerSP hijacking_listener_sp;
- Listener *hijacking_listener = NULL;
if (!m_hijacking_listeners.empty())
{
assert (!m_hijacking_masks.empty());
- hijacking_listener = m_hijacking_listeners.back();
+ hijacking_listener_sp = m_hijacking_listeners.back();
if ((event_type & m_hijacking_masks.back()) == 0)
- hijacking_listener = NULL;
+ hijacking_listener_sp.reset();
}
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
@@ -242,91 +289,106 @@ Broadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
StreamString event_description;
event_sp->Dump (&event_description);
log->Printf ("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, unique =%i) hijack = %p",
- static_cast<void*>(this), m_broadcaster_name.AsCString(""),
+ static_cast<void*>(this), GetBroadcasterName(),
event_description.GetData(), unique,
- static_cast<void*>(hijacking_listener));
+ static_cast<void*>(hijacking_listener_sp.get()));
}
- if (hijacking_listener)
+ if (hijacking_listener_sp)
{
- if (unique && hijacking_listener->PeekAtNextEventForBroadcasterWithType (this, event_type))
+ if (unique && hijacking_listener_sp->PeekAtNextEventForBroadcasterWithType (&m_broadcaster, event_type))
return;
- hijacking_listener->AddEvent (event_sp);
+ hijacking_listener_sp->AddEvent (event_sp);
}
else
{
- collection::iterator pos, end = m_listeners.end();
+ ListenerIterator([this, unique, event_type, &event_sp](const lldb::ListenerSP &curr_listener_sp, uint32_t &curr_event_mask) -> bool {
- // Iterate through all listener/mask pairs
- for (pos = m_listeners.begin(); pos != end; ++pos)
- {
- // If the listener's mask matches any bits that we just set, then
- // put the new event on its event queue.
- if (event_type & pos->second)
+ if (event_type & curr_event_mask)
{
- if (unique && pos->first->PeekAtNextEventForBroadcasterWithType (this, event_type))
- continue;
- pos->first->AddEvent (event_sp);
+ if (!unique || curr_listener_sp->PeekAtNextEventForBroadcasterWithType (&m_broadcaster, event_type) == nullptr)
+ curr_listener_sp->AddEvent (event_sp);
}
- }
+ return true; // Keep iterating
+ });
}
}
void
-Broadcaster::BroadcastEvent (uint32_t event_type, EventData *event_data)
+Broadcaster::BroadcasterImpl::BroadcastEvent (uint32_t event_type, EventData *event_data)
{
EventSP event_sp (new Event (event_type, event_data));
PrivateBroadcastEvent (event_sp, false);
}
void
-Broadcaster::BroadcastEventIfUnique (uint32_t event_type, EventData *event_data)
+Broadcaster::BroadcasterImpl::BroadcastEvent (uint32_t event_type, const lldb::EventDataSP &event_data_sp)
+{
+ EventSP event_sp (new Event (event_type, event_data_sp));
+ PrivateBroadcastEvent (event_sp, false);
+}
+
+void
+Broadcaster::BroadcasterImpl::BroadcastEventIfUnique (uint32_t event_type, EventData *event_data)
{
EventSP event_sp (new Event (event_type, event_data));
PrivateBroadcastEvent (event_sp, true);
}
bool
-Broadcaster::HijackBroadcaster (Listener *listener, uint32_t event_mask)
+Broadcaster::BroadcasterImpl::HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask)
{
- Mutex::Locker event_types_locker(m_listeners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
if (log)
log->Printf ("%p Broadcaster(\"%s\")::HijackBroadcaster (listener(\"%s\")=%p)",
- static_cast<void*>(this), m_broadcaster_name.AsCString(""),
- listener->m_name.c_str(), static_cast<void*>(listener));
- m_hijacking_listeners.push_back(listener);
+ static_cast<void*>(this), GetBroadcasterName(),
+ listener_sp->m_name.c_str(), static_cast<void*>(listener_sp.get()));
+ m_hijacking_listeners.push_back(listener_sp);
m_hijacking_masks.push_back(event_mask);
return true;
}
bool
-Broadcaster::IsHijackedForEvent (uint32_t event_mask)
+Broadcaster::BroadcasterImpl::IsHijackedForEvent (uint32_t event_mask)
{
- Mutex::Locker event_types_locker(m_listeners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
if (!m_hijacking_listeners.empty())
return (event_mask & m_hijacking_masks.back()) != 0;
return false;
}
+const char *
+Broadcaster::BroadcasterImpl::GetHijackingListenerName()
+{
+ if (m_hijacking_listeners.size())
+ {
+ return m_hijacking_listeners.back()->GetName();
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
void
-Broadcaster::RestoreBroadcaster ()
+Broadcaster::BroadcasterImpl::RestoreBroadcaster ()
{
- Mutex::Locker event_types_locker(m_listeners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
if (!m_hijacking_listeners.empty())
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
if (log)
{
- Listener *listener = m_hijacking_listeners.back();
+ ListenerSP listener_sp = m_hijacking_listeners.back();
log->Printf ("%p Broadcaster(\"%s\")::RestoreBroadcaster (about to pop listener(\"%s\")=%p)",
static_cast<void*>(this),
- m_broadcaster_name.AsCString(""),
- listener->m_name.c_str(), static_cast<void*>(listener));
+ GetBroadcasterName(),
+ listener_sp->m_name.c_str(), static_cast<void*>(listener_sp.get()));
}
m_hijacking_listeners.pop_back();
}
@@ -341,11 +403,7 @@ Broadcaster::GetBroadcasterClass() const
return class_name;
}
-BroadcastEventSpec::BroadcastEventSpec (const BroadcastEventSpec &rhs) :
- m_broadcaster_class (rhs.m_broadcaster_class),
- m_event_bits (rhs.m_event_bits)
-{
-}
+BroadcastEventSpec::BroadcastEventSpec(const BroadcastEventSpec &rhs) = default;
bool
BroadcastEventSpec::operator< (const BroadcastEventSpec &rhs) const
@@ -360,25 +418,24 @@ BroadcastEventSpec::operator< (const BroadcastEventSpec &rhs) const
}
}
-const BroadcastEventSpec &
-BroadcastEventSpec::operator= (const BroadcastEventSpec &rhs)
+BroadcastEventSpec &
+BroadcastEventSpec::operator=(const BroadcastEventSpec &rhs) = default;
+
+BroadcasterManager::BroadcasterManager() : m_manager_mutex()
{
- m_broadcaster_class = rhs.m_broadcaster_class;
- m_event_bits = rhs.m_event_bits;
- return *this;
}
-BroadcasterManager::BroadcasterManager() :
- m_manager_mutex(Mutex::eMutexTypeRecursive)
+lldb::BroadcasterManagerSP
+BroadcasterManager::MakeBroadcasterManager()
{
-
+ return BroadcasterManagerSP(new BroadcasterManager());
}
uint32_t
-BroadcasterManager::RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec)
+BroadcasterManager::RegisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec)
{
- Mutex::Locker locker(m_manager_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+
collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end();
uint32_t available_bits = event_spec.GetEventBits();
@@ -391,28 +448,28 @@ BroadcasterManager::RegisterListenerForEvents (Listener &listener, BroadcastEven
if (available_bits != 0)
{
- m_event_map.insert (event_listener_key (BroadcastEventSpec (event_spec.GetBroadcasterClass(), available_bits), &listener));
- m_listeners.insert(&listener);
+ m_event_map.insert (event_listener_key (BroadcastEventSpec (event_spec.GetBroadcasterClass(), available_bits), listener_sp));
+ m_listeners.insert(listener_sp);
}
return available_bits;
}
bool
-BroadcasterManager::UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec)
+BroadcasterManager::UnregisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec)
{
- Mutex::Locker locker(m_manager_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
bool removed_some = false;
- if (m_listeners.erase(&listener) == 0)
+ if (m_listeners.erase(listener_sp) == 0)
return false;
- ListenerMatchesAndSharedBits predicate (event_spec, listener);
+ ListenerMatchesAndSharedBits predicate (event_spec, listener_sp);
std::vector<BroadcastEventSpec> to_be_readded;
uint32_t event_bits_to_remove = event_spec.GetEventBits();
// Go through the map and delete the exact matches, and build a list of matches that weren't exact to re-add:
- while (1)
+ while (true)
{
collection::iterator iter, end_iter = m_event_map.end();
iter = find_if (m_event_map.begin(), end_iter, predicate);
@@ -437,36 +494,57 @@ BroadcasterManager::UnregisterListenerForEvents (Listener &listener, BroadcastEv
// Okay now add back the bits that weren't completely removed:
for (size_t i = 0; i < to_be_readded.size(); i++)
{
- m_event_map.insert (event_listener_key (to_be_readded[i], &listener));
+ m_event_map.insert (event_listener_key (to_be_readded[i], listener_sp));
}
return removed_some;
}
-Listener *
+ListenerSP
BroadcasterManager::GetListenerForEventSpec (BroadcastEventSpec event_spec) const
{
- Mutex::Locker locker(*(const_cast<Mutex *> (&m_manager_mutex)));
-
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+
collection::const_iterator iter, end_iter = m_event_map.end();
iter = find_if (m_event_map.begin(), end_iter, BroadcastEventSpecMatches (event_spec));
if (iter != end_iter)
return (*iter).second;
else
- return NULL;
+ return nullptr;
}
void
-BroadcasterManager::RemoveListener (Listener &listener)
+BroadcasterManager::RemoveListener(Listener *listener)
{
- Mutex::Locker locker(m_manager_mutex);
- ListenerMatches predicate (listener);
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+ ListenerMatchesPointer predicate (listener);
+ listener_collection::iterator iter = m_listeners.begin(), end_iter = m_listeners.end();
+
+ std::find_if (iter, end_iter, predicate);
+ if (iter != end_iter)
+ m_listeners.erase(iter);
+
+ while (true)
+ {
+ collection::iterator iter, end_iter = m_event_map.end();
+ iter = find_if (m_event_map.begin(), end_iter, predicate);
+ if (iter == end_iter)
+ break;
+ else
+ m_event_map.erase(iter);
+ }
+}
+void
+BroadcasterManager::RemoveListener (const lldb::ListenerSP &listener_sp)
+{
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+ ListenerMatches predicate (listener_sp);
- if (m_listeners.erase (&listener) == 0)
+ if (m_listeners.erase (listener_sp) == 0)
return;
- while (1)
+ while (true)
{
collection::iterator iter, end_iter = m_event_map.end();
iter = find_if (m_event_map.begin(), end_iter, predicate);
@@ -480,8 +558,8 @@ BroadcasterManager::RemoveListener (Listener &listener)
void
BroadcasterManager::SignUpListenersForBroadcaster (Broadcaster &broadcaster)
{
- Mutex::Locker locker(m_manager_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+
collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end();
while (iter != end_iter
@@ -495,12 +573,11 @@ BroadcasterManager::SignUpListenersForBroadcaster (Broadcaster &broadcaster)
void
BroadcasterManager::Clear ()
{
- Mutex::Locker locker(m_manager_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
listener_collection::iterator end_iter = m_listeners.end();
for (listener_collection::iterator iter = m_listeners.begin(); iter != end_iter; iter++)
- (*iter)->BroadcasterManagerWillDestruct(this);
+ (*iter)->BroadcasterManagerWillDestruct(this->shared_from_this());
m_listeners.clear();
m_event_map.clear();
-
}
diff --git a/source/Core/Communication.cpp b/source/Core/Communication.cpp
index ae579d1b00ae..f1dcb95e8af0 100644
--- a/source/Core/Communication.cpp
+++ b/source/Core/Communication.cpp
@@ -9,17 +9,19 @@
// C Includes
// C++ Includes
+#include <cstring>
+
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Communication.h"
#include "lldb/Core/Connection.h"
+#include "lldb/Core/Listener.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/Event.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/ThreadLauncher.h"
-#include <string.h>
using namespace lldb;
using namespace lldb_private;
@@ -31,54 +33,47 @@ Communication::GetStaticBroadcasterClass ()
return class_name;
}
-//----------------------------------------------------------------------
-// Constructor
-//----------------------------------------------------------------------
-Communication::Communication(const char *name) :
- Broadcaster (NULL, name),
- m_connection_sp (),
- m_read_thread_enabled (false),
- m_read_thread_did_exit (false),
- m_bytes(),
- m_bytes_mutex (Mutex::eMutexTypeRecursive),
- m_write_mutex (Mutex::eMutexTypeNormal),
- m_synchronize_mutex (Mutex::eMutexTypeNormal),
- m_callback (NULL),
- m_callback_baton (NULL),
- m_close_on_eof (true)
+Communication::Communication(const char *name)
+ : Broadcaster(nullptr, name),
+ m_connection_sp(),
+ m_read_thread_enabled(false),
+ m_read_thread_did_exit(false),
+ m_bytes(),
+ m_bytes_mutex(),
+ m_write_mutex(),
+ m_synchronize_mutex(),
+ m_callback(nullptr),
+ m_callback_baton(nullptr),
+ m_close_on_eof(true)
{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::Communication (name = %s)",
- this, name);
-
- SetEventName (eBroadcastBitDisconnected, "disconnected");
- SetEventName (eBroadcastBitReadThreadGotBytes, "got bytes");
- SetEventName (eBroadcastBitReadThreadDidExit, "read thread did exit");
- SetEventName (eBroadcastBitReadThreadShouldExit, "read thread should exit");
- SetEventName (eBroadcastBitPacketAvailable, "packet available");
- SetEventName (eBroadcastBitNoMorePendingInput, "no more pending input");
-
+ lldb_private::LogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
+ "%p Communication::Communication (name = %s)", this, name);
+
+ SetEventName(eBroadcastBitDisconnected, "disconnected");
+ SetEventName(eBroadcastBitReadThreadGotBytes, "got bytes");
+ SetEventName(eBroadcastBitReadThreadDidExit, "read thread did exit");
+ SetEventName(eBroadcastBitReadThreadShouldExit, "read thread should exit");
+ SetEventName(eBroadcastBitPacketAvailable, "packet available");
+ SetEventName(eBroadcastBitNoMorePendingInput, "no more pending input");
+
CheckInWithManager();
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
Communication::~Communication()
{
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
"%p Communication::~Communication (name = %s)",
- this, m_broadcaster_name.AsCString(""));
+ this, GetBroadcasterName().AsCString());
Clear();
}
void
Communication::Clear()
{
- SetReadThreadBytesReceivedCallback (NULL, NULL);
- Disconnect (NULL);
- StopReadThread (NULL);
+ SetReadThreadBytesReceivedCallback(nullptr, nullptr);
+ Disconnect(nullptr);
+ StopReadThread(nullptr);
}
ConnectionStatus
@@ -89,7 +84,7 @@ Communication::Connect (const char *url, Error *error_ptr)
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Connect (url = %s)", this, url);
lldb::ConnectionSP connection_sp (m_connection_sp);
- if (connection_sp.get())
+ if (connection_sp)
return connection_sp->Connect (url, error_ptr);
if (error_ptr)
error_ptr->SetErrorString("Invalid connection.");
@@ -102,7 +97,7 @@ Communication::Disconnect (Error *error_ptr)
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Disconnect ()", this);
lldb::ConnectionSP connection_sp (m_connection_sp);
- if (connection_sp.get())
+ if (connection_sp)
{
ConnectionStatus status = connection_sp->Disconnect (error_ptr);
// We currently don't protect connection_sp with any mutex for
@@ -123,16 +118,14 @@ Communication::Disconnect (Error *error_ptr)
bool
Communication::IsConnected () const
{
- lldb::ConnectionSP connection_sp (m_connection_sp);
- if (connection_sp.get())
- return connection_sp->IsConnected ();
- return false;
+ lldb::ConnectionSP connection_sp(m_connection_sp);
+ return (connection_sp ? connection_sp->IsConnected() : false);
}
bool
Communication::HasConnection () const
{
- return m_connection_sp.get() != NULL;
+ return m_connection_sp.get() != nullptr;
}
size_t
@@ -156,7 +149,7 @@ Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connectio
return cached_bytes;
}
- if (m_connection_sp.get() == NULL)
+ if (!m_connection_sp)
{
if (error_ptr)
error_ptr->SetErrorString("Invalid connection.");
@@ -171,10 +164,10 @@ Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connectio
timeout_time.OffsetWithMicroSeconds (timeout_usec);
}
- Listener listener ("Communication::Read");
- listener.StartListeningForEvents (this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
+ ListenerSP listener_sp(Listener::MakeListener("Communication::Read"));
+ listener_sp->StartListeningForEvents (this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
EventSP event_sp;
- while (listener.WaitForEvent (timeout_time.IsValid() ? &timeout_time : NULL, event_sp))
+ while (listener_sp->WaitForEvent (timeout_time.IsValid() ? &timeout_time : nullptr, event_sp))
{
const uint32_t event_type = event_sp->GetType();
if (event_type & eBroadcastBitReadThreadGotBytes)
@@ -185,7 +178,7 @@ Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connectio
if (event_type & eBroadcastBitReadThreadDidExit)
{
if (GetCloseOnEOF ())
- Disconnect (NULL);
+ Disconnect(nullptr);
break;
}
}
@@ -195,7 +188,7 @@ Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connectio
// We aren't using a read thread, just read the data synchronously in this
// thread.
lldb::ConnectionSP connection_sp (m_connection_sp);
- if (connection_sp.get())
+ if (connection_sp)
{
return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr);
}
@@ -206,13 +199,12 @@ Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connectio
return 0;
}
-
size_t
Communication::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr)
{
lldb::ConnectionSP connection_sp (m_connection_sp);
- Mutex::Locker locker(m_write_mutex);
+ std::lock_guard<std::mutex> guard(m_write_mutex);
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
"%p Communication::Write (src = %p, src_len = %" PRIu64 ") connection = %p",
this,
@@ -220,7 +212,7 @@ Communication::Write (const void *src, size_t src_len, ConnectionStatus &status,
(uint64_t)src_len,
connection_sp.get());
- if (connection_sp.get())
+ if (connection_sp)
return connection_sp->Write (src, src_len, status, error_ptr);
if (error_ptr)
@@ -229,7 +221,6 @@ Communication::Write (const void *src, size_t src_len, ConnectionStatus &status,
return 0;
}
-
bool
Communication::StartReadThread (Error *error_ptr)
{
@@ -242,9 +233,8 @@ Communication::StartReadThread (Error *error_ptr)
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
"%p Communication::StartReadThread ()", this);
-
char thread_name[1024];
- snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>", m_broadcaster_name.AsCString());
+ snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>", GetBroadcasterName().AsCString());
m_read_thread_enabled = true;
m_read_thread_did_exit = false;
@@ -265,7 +255,7 @@ Communication::StopReadThread (Error *error_ptr)
m_read_thread_enabled = false;
- BroadcastEvent (eBroadcastBitReadThreadShouldExit, NULL);
+ BroadcastEvent(eBroadcastBitReadThreadShouldExit, nullptr);
// error = m_read_thread.Cancel();
@@ -286,12 +276,12 @@ Communication::JoinReadThread (Error *error_ptr)
size_t
Communication::GetCachedBytes (void *dst, size_t dst_len)
{
- Mutex::Locker locker(m_bytes_mutex);
- if (m_bytes.size() > 0)
+ std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
+ if (!m_bytes.empty())
{
- // If DST is NULL and we have a thread, then return the number
+ // If DST is nullptr and we have a thread, then return the number
// of bytes that are available so the caller can call again
- if (dst == NULL)
+ if (dst == nullptr)
return m_bytes.size();
const size_t len = std::min<size_t>(dst_len, m_bytes.size());
@@ -310,7 +300,7 @@ Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broad
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
"%p Communication::AppendBytesToCache (src = %p, src_len = %" PRIu64 ", broadcast = %i)",
this, bytes, (uint64_t)len, broadcast);
- if ((bytes == NULL || len == 0)
+ if ((bytes == nullptr || len == 0)
&& (status != lldb::eConnectionStatusEndOfFile))
return;
if (m_callback)
@@ -318,9 +308,9 @@ Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broad
// If the user registered a callback, then call it and do not broadcast
m_callback (m_callback_baton, bytes, len);
}
- else if (bytes != NULL && len > 0)
+ else if (bytes != nullptr && len > 0)
{
- Mutex::Locker locker(m_bytes_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
m_bytes.append ((const char *)bytes, len);
if (broadcast)
BroadcastEventIfUnique (eBroadcastBitReadThreadGotBytes);
@@ -334,10 +324,8 @@ Communication::ReadFromConnection (void *dst,
ConnectionStatus &status,
Error *error_ptr)
{
- lldb::ConnectionSP connection_sp (m_connection_sp);
- if (connection_sp.get())
- return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr);
- return 0;
+ lldb::ConnectionSP connection_sp(m_connection_sp);
+ return (connection_sp ? connection_sp->Read(dst, dst_len, timeout_usec, status, error_ptr) : 0);
}
bool
@@ -403,7 +391,7 @@ Communication::ReadThread (lldb::thread_arg_t p)
case eConnectionStatusNoConnection: // No connection
case eConnectionStatusLostConnection: // Lost connection while connected to a valid connection
done = true;
- // Fall through...
+ LLVM_FALLTHROUGH;
case eConnectionStatusTimedOut: // Request timed out
if (log)
error.LogIfError (log,
@@ -425,11 +413,8 @@ Communication::ReadThread (lldb::thread_arg_t p)
}
void
-Communication::SetReadThreadBytesReceivedCallback
-(
- ReadThreadBytesReceived callback,
- void *callback_baton
-)
+Communication::SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback,
+ void *callback_baton)
{
m_callback = callback;
m_callback_baton = callback_baton;
@@ -439,11 +424,11 @@ void
Communication::SynchronizeWithReadThread ()
{
// Only one thread can do the synchronization dance at a time.
- Mutex::Locker locker(m_synchronize_mutex);
+ std::lock_guard<std::mutex> guard(m_synchronize_mutex);
// First start listening for the synchronization event.
- Listener listener("Communication::SyncronizeWithReadThread");
- listener.StartListeningForEvents(this, eBroadcastBitNoMorePendingInput);
+ ListenerSP listener_sp(Listener::MakeListener("Communication::SyncronizeWithReadThread"));
+ listener_sp->StartListeningForEvents(this, eBroadcastBitNoMorePendingInput);
// If the thread is not running, there is no point in synchronizing.
if (!m_read_thread_enabled || m_read_thread_did_exit)
@@ -454,14 +439,14 @@ Communication::SynchronizeWithReadThread ()
// Wait for the synchronization event.
EventSP event_sp;
- listener.WaitForEvent(NULL, event_sp);
+ listener_sp->WaitForEvent(nullptr, event_sp);
}
void
Communication::SetConnection (Connection *connection)
{
- Disconnect (NULL);
- StopReadThread(NULL);
+ Disconnect(nullptr);
+ StopReadThread(nullptr);
m_connection_sp.reset(connection);
}
diff --git a/source/Core/ConnectionSharedMemory.cpp b/source/Core/ConnectionSharedMemory.cpp
index e417347579eb..707644d36b1c 100644
--- a/source/Core/ConnectionSharedMemory.cpp
+++ b/source/Core/ConnectionSharedMemory.cpp
@@ -1,4 +1,4 @@
-//===-- ConnectionSharedMemory.cpp ----------------------------*- C++ -*-===//
+//===-- ConnectionSharedMemory.cpp ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,13 +6,12 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#ifndef __ANDROID_NDK__
#include "lldb/Core/ConnectionSharedMemory.h"
// C Includes
-#include <errno.h>
-#include <stdlib.h>
#ifdef _WIN32
#include "lldb/Host/windows/windows.h"
#else
@@ -23,12 +22,18 @@
#endif
// C++ Includes
+#include <cerrno>
+#include <cstdlib>
+
// Other libraries and framework includes
-// Project includes
#include "llvm/Support/MathExtras.h"
+
+// Project includes
#include "lldb/Core/Communication.h"
#include "lldb/Core/Log.h"
+#include "llvm/Support/ConvertUTF.h"
+
using namespace lldb;
using namespace lldb_private;
@@ -42,7 +47,7 @@ ConnectionSharedMemory::ConnectionSharedMemory () :
ConnectionSharedMemory::~ConnectionSharedMemory ()
{
- Disconnect (NULL);
+ Disconnect(nullptr);
}
bool
@@ -132,18 +137,18 @@ ConnectionSharedMemory::Open (bool create, const char *name, size_t size, Error
m_name.assign (name);
#ifdef _WIN32
- HANDLE handle;
- if (create) {
- handle = CreateFileMapping(
- INVALID_HANDLE_VALUE,
- NULL,
- PAGE_READWRITE,
- llvm::Hi_32(size),
- llvm::Lo_32(size),
- name);
+ HANDLE handle = INVALID_HANDLE_VALUE;
+ std::wstring wname;
+ if (llvm::ConvertUTF8toWide(name, wname))
+ {
+ if (create)
+ {
+ handle = CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, llvm::Hi_32(size),
+ llvm::Lo_32(size), wname.c_str());
+ }
+ else
+ handle = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, wname.c_str());
}
- else
- handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name);
m_fd = _open_osfhandle((intptr_t)handle, 0);
#else
@@ -159,7 +164,7 @@ ConnectionSharedMemory::Open (bool create, const char *name, size_t size, Error
if (m_mmap.MemoryMapFromFileDescriptor(m_fd, 0, size, true, false) == size)
return eConnectionStatusSuccess;
- Disconnect(NULL);
+ Disconnect(nullptr);
return eConnectionStatusError;
}
diff --git a/source/Core/ConstString.cpp b/source/Core/ConstString.cpp
index c2e95d801723..f983f1444d7c 100644
--- a/source/Core/ConstString.cpp
+++ b/source/Core/ConstString.cpp
@@ -6,14 +6,21 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#include "lldb/Core/ConstString.h"
-#include "lldb/Core/Stream.h"
+
+// C Includes
+// C++ Includes
+#include <array>
+#include <mutex>
+
+// Other libraries and framework includes
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/RWMutex.h"
-#include <array>
-#include <mutex>
+// Project includes
+#include "lldb/Core/Stream.h"
using namespace lldb_private;
@@ -34,7 +41,7 @@ public:
size_t
GetConstCStringLength (const char *ccstr) const
{
- if (ccstr)
+ if (ccstr != nullptr)
{
const uint8_t h = hash (llvm::StringRef(ccstr));
llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex);
@@ -47,19 +54,19 @@ public:
StringPoolValueType
GetMangledCounterpart (const char *ccstr) const
{
- if (ccstr)
+ if (ccstr != nullptr)
{
const uint8_t h = hash (llvm::StringRef(ccstr));
llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex);
return GetStringMapEntryFromKeyData (ccstr).getValue();
}
- return 0;
+ return nullptr;
}
bool
SetMangledCounterparts (const char *key_ccstr, const char *value_ccstr)
{
- if (key_ccstr && value_ccstr)
+ if (key_ccstr != nullptr && value_ccstr != nullptr)
{
{
const uint8_t h = hash (llvm::StringRef(key_ccstr));
@@ -79,7 +86,7 @@ public:
const char *
GetConstCString (const char *cstr)
{
- if (cstr)
+ if (cstr != nullptr)
return GetConstCStringWithLength (cstr, strlen (cstr));
return nullptr;
}
@@ -87,7 +94,7 @@ public:
const char *
GetConstCStringWithLength (const char *cstr, size_t cstr_len)
{
- if (cstr)
+ if (cstr != nullptr)
return GetConstCStringWithStringRef(llvm::StringRef(cstr, cstr_len));
return nullptr;
}
@@ -116,7 +123,7 @@ public:
const char *
GetConstCStringAndSetMangledCounterPart (const char *demangled_cstr, const char *mangled_ccstr)
{
- if (demangled_cstr)
+ if (demangled_cstr != nullptr)
{
const char *demangled_ccstr = nullptr;
@@ -150,7 +157,7 @@ public:
const char *
GetConstTrimmedCStringWithLength (const char *cstr, size_t cstr_len)
{
- if (cstr)
+ if (cstr != nullptr)
{
const size_t trimmed_len = std::min<size_t> (strlen (cstr), cstr_len);
return GetConstCStringWithLength (cstr, trimmed_len);
@@ -253,7 +260,7 @@ Stream&
lldb_private::operator << (Stream& s, const ConstString& str)
{
const char *cstr = str.GetCString();
- if (cstr)
+ if (cstr != nullptr)
s << cstr;
return s;
@@ -265,8 +272,25 @@ ConstString::GetLength () const
return StringPool().GetConstCStringLength (m_string);
}
+bool
+ConstString::Equals(const ConstString &lhs, const ConstString &rhs, const bool case_sensitive)
+{
+ if (lhs.m_string == rhs.m_string)
+ return true;
+
+ // Since the pointers weren't equal, and identical ConstStrings always have identical pointers,
+ // the result must be false for case sensitive equality test.
+ if (case_sensitive)
+ return false;
+
+ // perform case insensitive equality test
+ llvm::StringRef lhs_string_ref(lhs.m_string, StringPool().GetConstCStringLength(lhs.m_string));
+ llvm::StringRef rhs_string_ref(rhs.m_string, StringPool().GetConstCStringLength(rhs.m_string));
+ return lhs_string_ref.equals_lower(rhs_string_ref);
+}
+
int
-ConstString::Compare (const ConstString& lhs, const ConstString& rhs)
+ConstString::Compare(const ConstString &lhs, const ConstString &rhs, const bool case_sensitive)
{
// If the iterators are the same, this is the same string
const char *lhs_cstr = lhs.m_string;
@@ -277,22 +301,30 @@ ConstString::Compare (const ConstString& lhs, const ConstString& rhs)
{
llvm::StringRef lhs_string_ref (lhs_cstr, StringPool().GetConstCStringLength (lhs_cstr));
llvm::StringRef rhs_string_ref (rhs_cstr, StringPool().GetConstCStringLength (rhs_cstr));
- return lhs_string_ref.compare(rhs_string_ref);
+
+ if (case_sensitive)
+ {
+ return lhs_string_ref.compare(rhs_string_ref);
+ }
+ else
+ {
+ return lhs_string_ref.compare_lower(rhs_string_ref);
+ }
}
if (lhs_cstr)
- return +1; // LHS isn't NULL but RHS is
+ return +1; // LHS isn't nullptr but RHS is
else
- return -1; // LHS is NULL but RHS isn't
+ return -1; // LHS is nullptr but RHS isn't
}
void
ConstString::Dump(Stream *s, const char *fail_value) const
{
- if (s)
+ if (s != nullptr)
{
const char *cstr = AsCString (fail_value);
- if (cstr)
+ if (cstr != nullptr)
s->PutCString (cstr);
}
}
@@ -302,7 +334,7 @@ ConstString::DumpDebug(Stream *s) const
{
const char *cstr = GetCString ();
size_t cstr_len = GetLength();
- // Only print the parens if we have a non-NULL string
+ // Only print the parens if we have a non-nullptr string
const char *parens = cstr ? "\"" : "";
s->Printf("%*p: ConstString, string = %s%s%s, length = %" PRIu64,
static_cast<int>(sizeof(void*) * 2),
diff --git a/source/Core/CxaDemangle.cpp b/source/Core/CxaDemangle.cpp
index 7d21138c2899..62335a9175cd 100644
--- a/source/Core/CxaDemangle.cpp
+++ b/source/Core/CxaDemangle.cpp
@@ -20,6 +20,7 @@
#include "lldb/Host/windows/win32.h" // snprintf
#endif
#include "llvm/Support/Compiler.h" // LLVM_{NOEXCEPT, CONSTEXPR, ALIGNAS}
+#include "lldb/lldb-private.h"
#undef _LIBCPP_EXTERN_TEMPLATE // Avoid warning below
//===-------------------------- cxa_demangle.cpp --------------------------===//
@@ -2262,7 +2263,7 @@ parse_type(const char* first, const char* last, C& db)
break;
}
}
- // drop through
+ LLVM_FALLTHROUGH;
default:
// must check for builtin-types before class-enum-types to avoid
// ambiguities with operator-names
diff --git a/source/Core/DataBufferHeap.cpp b/source/Core/DataBufferHeap.cpp
index ba1314448bbd..4e5389e053e9 100644
--- a/source/Core/DataBufferHeap.cpp
+++ b/source/Core/DataBufferHeap.cpp
@@ -9,6 +9,11 @@
#include "lldb/Core/DataBufferHeap.h"
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
using namespace lldb_private;
//----------------------------------------------------------------------
@@ -44,32 +49,26 @@ DataBufferHeap::DataBufferHeap (const void *src, lldb::offset_t src_len) :
// Virtual destructor since this class inherits from a pure virtual
// base class.
//----------------------------------------------------------------------
-DataBufferHeap::~DataBufferHeap ()
-{
-}
+DataBufferHeap::~DataBufferHeap() = default;
//----------------------------------------------------------------------
-// Return a pointer to the bytes owned by this object, or NULL if
+// Return a pointer to the bytes owned by this object, or nullptr if
// the object contains no bytes.
//----------------------------------------------------------------------
uint8_t *
DataBufferHeap::GetBytes ()
{
- if (m_data.empty())
- return NULL;
- return &m_data[0];
+ return (m_data.empty() ? nullptr : m_data.data());
}
//----------------------------------------------------------------------
-// Return a const pointer to the bytes owned by this object, or NULL
+// Return a const pointer to the bytes owned by this object, or nullptr
// if the object contains no bytes.
//----------------------------------------------------------------------
const uint8_t *
DataBufferHeap::GetBytes () const
{
- if (m_data.empty())
- return NULL;
- return &m_data[0];
+ return (m_data.empty() ? nullptr : m_data.data());
}
//----------------------------------------------------------------------
@@ -81,7 +80,6 @@ DataBufferHeap::GetByteSize () const
return m_data.size();
}
-
//----------------------------------------------------------------------
// Sets the number of bytes that this object should be able to
// contain. This can be used prior to copying data into the buffer.
diff --git a/source/Core/DataBufferMemoryMap.cpp b/source/Core/DataBufferMemoryMap.cpp
index b3211b35af85..48fe9e58d07d 100644
--- a/source/Core/DataBufferMemoryMap.cpp
+++ b/source/Core/DataBufferMemoryMap.cpp
@@ -7,19 +7,44 @@
//
//===----------------------------------------------------------------------===//
-
-#include <errno.h>
+// C Includes
#include <fcntl.h>
-#include <limits.h>
#include <sys/stat.h>
#ifdef _WIN32
#include "lldb/Host/windows/windows.h"
#else
#include <sys/mman.h>
-#endif
+#define MAP_EXTRA_HOST_READ_FLAGS 0
+
+#if defined (__APPLE__)
+//----------------------------------------------------------------------
+// Newer versions of MacOSX have a flag that will allow us to read from
+// binaries whose code signature is invalid without crashing by using
+// the MAP_RESILIENT_CODESIGN flag. Also if a file from removable media
+// is mapped we can avoid crashing and return zeroes to any pages we try
+// to read if the media becomes unavailable by using the
+// MAP_RESILIENT_MEDIA flag.
+//----------------------------------------------------------------------
+#if defined(MAP_RESILIENT_CODESIGN)
+ #undef MAP_EXTRA_HOST_READ_FLAGS
+ #if defined(MAP_RESILIENT_MEDIA)
+ #define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN | MAP_RESILIENT_MEDIA
+ #else
+ #define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN
+ #endif
+#endif // #if defined(MAP_RESILIENT_CODESIGN)
+#endif // #if defined (__APPLE__)
+
+#endif // #else #ifdef _WIN32
+// C++ Includes
+#include <cerrno>
+#include <climits>
+
+// Other libraries and framework includes
#include "llvm/Support/MathExtras.h"
+// Project includes
#include "lldb/Core/DataBufferMemoryMap.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/File.h"
@@ -34,9 +59,9 @@ using namespace lldb_private;
// Default Constructor
//----------------------------------------------------------------------
DataBufferMemoryMap::DataBufferMemoryMap() :
- m_mmap_addr(NULL),
+ m_mmap_addr(nullptr),
m_mmap_size(0),
- m_data(NULL),
+ m_data(nullptr),
m_size(0)
{
}
@@ -51,7 +76,7 @@ DataBufferMemoryMap::~DataBufferMemoryMap()
}
//----------------------------------------------------------------------
-// Return a pointer to the bytes owned by this object, or NULL if
+// Return a pointer to the bytes owned by this object, or nullptr if
// the object contains no bytes.
//----------------------------------------------------------------------
uint8_t *
@@ -61,7 +86,7 @@ DataBufferMemoryMap::GetBytes()
}
//----------------------------------------------------------------------
-// Return a const pointer to the bytes owned by this object, or NULL
+// Return a const pointer to the bytes owned by this object, or nullptr
// if the object contains no bytes.
//----------------------------------------------------------------------
const uint8_t *
@@ -86,7 +111,7 @@ DataBufferMemoryMap::GetByteSize() const
void
DataBufferMemoryMap::Clear()
{
- if (m_mmap_addr != NULL)
+ if (m_mmap_addr != nullptr)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP));
if (log)
@@ -97,9 +122,9 @@ DataBufferMemoryMap::Clear()
#else
::munmap((void *)m_mmap_addr, m_mmap_size);
#endif
- m_mmap_addr = NULL;
+ m_mmap_addr = nullptr;
m_mmap_size = 0;
- m_data = NULL;
+ m_data = nullptr;
m_size = 0;
}
}
@@ -118,7 +143,7 @@ DataBufferMemoryMap::MemoryMapFromFileSpec (const FileSpec* filespec,
size_t length,
bool writeable)
{
- if (filespec != NULL)
+ if (filespec != nullptr)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP));
if (log)
@@ -150,7 +175,6 @@ DataBufferMemoryMap::MemoryMapFromFileSpec (const FileSpec* filespec,
return 0;
}
-
#ifdef _WIN32
static size_t win32memmapalignment = 0;
void LoadWin32MemMapAlignment ()
@@ -208,8 +232,8 @@ DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd,
if (length > 0)
{
- HANDLE fileMapping = CreateFileMapping(handle, NULL, writeable ? PAGE_READWRITE : PAGE_READONLY, file_size_high, file_size_low, NULL);
- if (fileMapping != NULL)
+ HANDLE fileMapping = CreateFileMapping(handle, nullptr, writeable ? PAGE_READWRITE : PAGE_READONLY, file_size_high, file_size_low, nullptr);
+ if (fileMapping != nullptr)
{
if (win32memmapalignment == 0) LoadWin32MemMapAlignment();
lldb::offset_t realoffset = offset;
@@ -252,14 +276,16 @@ DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd,
if (length > 0)
{
int prot = PROT_READ;
+ int flags = MAP_PRIVATE;
if (writeable)
prot |= PROT_WRITE;
+ else
+ flags |= MAP_EXTRA_HOST_READ_FLAGS;
- int flags = MAP_PRIVATE;
if (fd_is_file)
flags |= MAP_FILE;
- m_mmap_addr = (uint8_t *)::mmap(NULL, length, prot, flags, fd, offset);
+ m_mmap_addr = (uint8_t *)::mmap(nullptr, length, prot, flags, fd, offset);
Error error;
if (m_mmap_addr == (void*)-1)
@@ -271,13 +297,13 @@ DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd,
size_t page_offset = offset % HostInfo::GetPageSize();
if (page_offset != 0)
{
- m_mmap_addr = (uint8_t *)::mmap(NULL, length + page_offset, prot, flags, fd, offset - page_offset);
+ m_mmap_addr = (uint8_t *)::mmap(nullptr, length + page_offset, prot, flags, fd, offset - page_offset);
if (m_mmap_addr == (void*)-1)
{
// Failed to map file
- m_mmap_addr = NULL;
+ m_mmap_addr = nullptr;
}
- else if (m_mmap_addr != NULL)
+ else if (m_mmap_addr != nullptr)
{
// We recovered and were able to memory map
// after we aligned things to page boundaries
diff --git a/source/Core/DataEncoder.cpp b/source/Core/DataEncoder.cpp
index 040d09647562..3ef829507704 100644
--- a/source/Core/DataEncoder.cpp
+++ b/source/Core/DataEncoder.cpp
@@ -1,4 +1,4 @@
-//===-- DataEncoder.cpp ---------------------------------------*- C++ -*-===//
+//===-- DataEncoder.cpp -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,11 +9,15 @@
#include "lldb/Core/DataEncoder.h"
-#include <assert.h>
-#include <stddef.h>
+// C Includes
+// C++ Includes
+#include <cassert>
+#include <cstddef>
+// Other libraries and framework includes
#include "llvm/Support/MathExtras.h"
+// Project includes
#include "lldb/Core/DataBuffer.h"
#include "lldb/Host/Endian.h"
@@ -25,6 +29,7 @@ WriteInt16(unsigned char* ptr, unsigned offset, uint16_t value)
{
*(uint16_t *)(ptr + offset) = value;
}
+
static inline void
WriteInt32 (unsigned char* ptr, unsigned offset, uint32_t value)
{
@@ -59,11 +64,11 @@ WriteSwappedInt64(unsigned char* ptr, unsigned offset, uint64_t value)
// Default constructor.
//----------------------------------------------------------------------
DataEncoder::DataEncoder () :
- m_start (NULL),
- m_end (NULL),
+ m_start(nullptr),
+ m_end(nullptr),
m_byte_order(endian::InlHostByteOrder()),
- m_addr_size (sizeof(void*)),
- m_data_sp ()
+ m_addr_size(sizeof(void*)),
+ m_data_sp()
{
}
@@ -88,21 +93,16 @@ DataEncoder::DataEncoder (void* data, uint32_t length, ByteOrder endian, uint8_t
// this data.
//----------------------------------------------------------------------
DataEncoder::DataEncoder (const DataBufferSP& data_sp, ByteOrder endian, uint8_t addr_size) :
- m_start (NULL),
- m_end (NULL),
+ m_start(nullptr),
+ m_end(nullptr),
m_byte_order(endian),
- m_addr_size (addr_size),
- m_data_sp ()
+ m_addr_size(addr_size),
+ m_data_sp()
{
SetData (data_sp);
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-DataEncoder::~DataEncoder ()
-{
-}
+DataEncoder::~DataEncoder() = default;
//------------------------------------------------------------------
// Clears the object contents back to a default invalid state, and
@@ -112,8 +112,8 @@ DataEncoder::~DataEncoder ()
void
DataEncoder::Clear ()
{
- m_start = NULL;
- m_end = NULL;
+ m_start = nullptr;
+ m_end = nullptr;
m_byte_order = endian::InlHostByteOrder();
m_addr_size = sizeof(void*);
m_data_sp.reset();
@@ -126,13 +126,13 @@ DataEncoder::Clear ()
size_t
DataEncoder::GetSharedDataOffset () const
{
- if (m_start != NULL)
+ if (m_start != nullptr)
{
const DataBuffer * data = m_data_sp.get();
- if (data != NULL)
+ if (data != nullptr)
{
const uint8_t * data_bytes = data->GetBytes();
- if (data_bytes != NULL)
+ if (data_bytes != nullptr)
{
assert(m_start >= data_bytes);
return m_start - data_bytes;
@@ -157,10 +157,10 @@ DataEncoder::SetData (void *bytes, uint32_t length, ByteOrder endian)
{
m_byte_order = endian;
m_data_sp.reset();
- if (bytes == NULL || length == 0)
+ if (bytes == nullptr || length == 0)
{
- m_start = NULL;
- m_end = NULL;
+ m_start = nullptr;
+ m_end = nullptr;
}
else
{
@@ -187,12 +187,12 @@ DataEncoder::SetData (void *bytes, uint32_t length, ByteOrder endian)
uint32_t
DataEncoder::SetData (const DataBufferSP& data_sp, uint32_t data_offset, uint32_t data_length)
{
- m_start = m_end = NULL;
+ m_start = m_end = nullptr;
if (data_length > 0)
{
m_data_sp = data_sp;
- if (data_sp.get())
+ if (data_sp)
{
const size_t data_size = data_sp->GetByteSize();
if (data_offset < data_size)
@@ -309,7 +309,7 @@ DataEncoder::PutMaxU64 (uint32_t offset, uint32_t byte_size, uint64_t value)
uint32_t
DataEncoder::PutData (uint32_t offset, const void *src, uint32_t src_len)
{
- if (src == NULL || src_len == 0)
+ if (src == nullptr || src_len == 0)
return offset;
if (ValidOffsetForDataOfSize(offset, src_len))
@@ -329,7 +329,7 @@ DataEncoder::PutAddress (uint32_t offset, lldb::addr_t addr)
uint32_t
DataEncoder::PutCString (uint32_t offset, const char *cstr)
{
- if (cstr)
+ if (cstr != nullptr)
return PutData (offset, cstr, strlen(cstr) + 1);
return UINT32_MAX;
}
diff --git a/source/Core/DataExtractor.cpp b/source/Core/DataExtractor.cpp
index dc7857fe9cb7..84446147a363 100644
--- a/source/Core/DataExtractor.cpp
+++ b/source/Core/DataExtractor.cpp
@@ -7,17 +7,16 @@
//
//===----------------------------------------------------------------------===//
-#include <assert.h>
-#include <stddef.h>
-
+// C Includes
+// C++ Includes
#include <bitset>
-#include <limits>
+#include <cassert>
+#include <cstddef>
+#include <cmath>
#include <sstream>
#include <string>
-#include <math.h>
-
-#include "clang/AST/ASTContext.h"
+// Other libraries and framework includes
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
@@ -25,6 +24,9 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MD5.h"
+#include "clang/AST/ASTContext.h"
+
+// Project includes
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/DataBuffer.h"
@@ -125,15 +127,13 @@ ReadSwapInt64(const void* ptr)
}
#define NON_PRINTABLE_CHAR '.'
-//----------------------------------------------------------------------
-// Default constructor.
-//----------------------------------------------------------------------
+
DataExtractor::DataExtractor () :
- m_start (NULL),
- m_end (NULL),
+ m_start(nullptr),
+ m_end(nullptr),
m_byte_order(endian::InlHostByteOrder()),
- m_addr_size (sizeof(void *)),
- m_data_sp (),
+ m_addr_size(sizeof(void *)),
+ m_data_sp(),
m_target_byte_size(1)
{
}
@@ -163,11 +163,11 @@ DataExtractor::DataExtractor (const void* data, offset_t length, ByteOrder endia
// this data.
//----------------------------------------------------------------------
DataExtractor::DataExtractor (const DataBufferSP& data_sp, ByteOrder endian, uint32_t addr_size, uint32_t target_byte_size/*=1*/) :
- m_start (NULL),
- m_end (NULL),
+ m_start(nullptr),
+ m_end(nullptr),
m_byte_order(endian),
- m_addr_size (addr_size),
- m_data_sp (),
+ m_addr_size(addr_size),
+ m_data_sp(),
m_target_byte_size(target_byte_size)
{
#ifdef LLDB_CONFIGURATION_DEBUG
@@ -184,8 +184,8 @@ DataExtractor::DataExtractor (const DataBufferSP& data_sp, ByteOrder endian, uin
// swap and address size settings are copied from "data".
//----------------------------------------------------------------------
DataExtractor::DataExtractor (const DataExtractor& data, offset_t offset, offset_t length, uint32_t target_byte_size/*=1*/) :
- m_start(NULL),
- m_end(NULL),
+ m_start(nullptr),
+ m_end(nullptr),
m_byte_order(data.m_byte_order),
m_addr_size(data.m_addr_size),
m_data_sp(),
@@ -233,12 +233,7 @@ DataExtractor::operator= (const DataExtractor& rhs)
return *this;
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-DataExtractor::~DataExtractor ()
-{
-}
+DataExtractor::~DataExtractor() = default;
//------------------------------------------------------------------
// Clears the object contents back to a default invalid state, and
@@ -248,8 +243,8 @@ DataExtractor::~DataExtractor ()
void
DataExtractor::Clear ()
{
- m_start = NULL;
- m_end = NULL;
+ m_start = nullptr;
+ m_end = nullptr;
m_byte_order = endian::InlHostByteOrder();
m_addr_size = sizeof(void *);
m_data_sp.reset();
@@ -262,13 +257,13 @@ DataExtractor::Clear ()
size_t
DataExtractor::GetSharedDataOffset () const
{
- if (m_start != NULL)
+ if (m_start != nullptr)
{
const DataBuffer * data = m_data_sp.get();
- if (data != NULL)
+ if (data != nullptr)
{
const uint8_t * data_bytes = data->GetBytes();
- if (data_bytes != NULL)
+ if (data_bytes != nullptr)
{
assert(m_start >= data_bytes);
return m_start - data_bytes;
@@ -293,10 +288,10 @@ DataExtractor::SetData (const void *bytes, offset_t length, ByteOrder endian)
{
m_byte_order = endian;
m_data_sp.reset();
- if (bytes == NULL || length == 0)
+ if (bytes == nullptr || length == 0)
{
- m_start = NULL;
- m_end = NULL;
+ m_start = nullptr;
+ m_end = nullptr;
}
else
{
@@ -328,7 +323,7 @@ DataExtractor::SetData (const DataExtractor& data, offset_t data_offset, offset_
assert (m_addr_size == 4 || m_addr_size == 8);
#endif
// If "data" contains shared pointer to data, then we can use that
- if (data.m_data_sp.get())
+ if (data.m_data_sp)
{
m_byte_order = data.m_byte_order;
return SetData(data.m_data_sp, data.GetSharedDataOffset() + data_offset, data_length);
@@ -361,12 +356,12 @@ DataExtractor::SetData (const DataExtractor& data, offset_t data_offset, offset_
lldb::offset_t
DataExtractor::SetData (const DataBufferSP& data_sp, offset_t data_offset, offset_t data_length)
{
- m_start = m_end = NULL;
+ m_start = m_end = nullptr;
if (data_length > 0)
{
m_data_sp = data_sp;
- if (data_sp.get())
+ if (data_sp)
{
const size_t data_size = data_sp->GetByteSize();
if (data_offset < data_size)
@@ -412,8 +407,8 @@ DataExtractor::GetU8 (offset_t *offset_ptr) const
// offset pointed to by "offset_ptr". The extracted data is copied into
// "dst".
//
-// RETURNS the non-NULL buffer pointer upon successful extraction of
-// all the requested bytes, or NULL when the data is not available in
+// RETURNS the non-nullptr buffer pointer upon successful extraction of
+// all the requested bytes, or nullptr when the data is not available in
// the buffer due to being out of bounds, or insufficient data.
//----------------------------------------------------------------------
void *
@@ -424,10 +419,10 @@ DataExtractor::GetU8 (offset_t *offset_ptr, void *dst, uint32_t count) const
{
// Copy the data into the buffer
memcpy (dst, data, count);
- // Return a non-NULL pointer to the converted data as an indicator of success
+ // Return a non-nullptr pointer to the converted data as an indicator of success
return dst;
}
- return NULL;
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -487,14 +482,13 @@ DataExtractor::GetU64_unchecked (offset_t *offset_ptr) const
return val;
}
-
//----------------------------------------------------------------------
// Extract "count" uint16_t values from the binary data and update
// the offset pointed to by "offset_ptr". The extracted data is
// copied into "dst".
//
-// RETURNS the non-NULL buffer pointer upon successful extraction of
-// all the requested bytes, or NULL when the data is not available
+// RETURNS the non-nullptr buffer pointer upon successful extraction of
+// all the requested bytes, or nullptr when the data is not available
// in the buffer due to being out of bounds, or insufficient data.
//----------------------------------------------------------------------
void *
@@ -520,10 +514,10 @@ DataExtractor::GetU16 (offset_t *offset_ptr, void *void_dst, uint32_t count) con
{
memcpy (void_dst, src, src_size);
}
- // Return a non-NULL pointer to the converted data as an indicator of success
+ // Return a non-nullptr pointer to the converted data as an indicator of success
return void_dst;
}
- return NULL;
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -556,8 +550,8 @@ DataExtractor::GetU32 (offset_t *offset_ptr) const
// the offset pointed to by "offset_ptr". The extracted data is
// copied into "dst".
//
-// RETURNS the non-NULL buffer pointer upon successful extraction of
-// all the requested bytes, or NULL when the data is not available
+// RETURNS the non-nullptr buffer pointer upon successful extraction of
+// all the requested bytes, or nullptr when the data is not available
// in the buffer due to being out of bounds, or insufficient data.
//----------------------------------------------------------------------
void *
@@ -583,10 +577,10 @@ DataExtractor::GetU32 (offset_t *offset_ptr, void *void_dst, uint32_t count) con
{
memcpy (void_dst, src, src_size);
}
- // Return a non-NULL pointer to the converted data as an indicator of success
+ // Return a non-nullptr pointer to the converted data as an indicator of success
return void_dst;
}
- return NULL;
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -644,10 +638,10 @@ DataExtractor::GetU64 (offset_t *offset_ptr, void *void_dst, uint32_t count) con
{
memcpy (void_dst, src, src_size);
}
- // Return a non-NULL pointer to the converted data as an indicator of success
+ // Return a non-nullptr pointer to the converted data as an indicator of success
return void_dst;
}
- return NULL;
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -739,8 +733,11 @@ DataExtractor::GetMaxU64Bitfield (offset_t *offset_ptr, size_t size, uint32_t bi
uint64_t uval64 = GetMaxU64 (offset_ptr, size);
if (bitfield_bit_size > 0)
{
- if (bitfield_bit_offset > 0)
- uval64 >>= bitfield_bit_offset;
+ int32_t lsbcount = bitfield_bit_offset;
+ if (m_byte_order == eByteOrderBig)
+ lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
+ if (lsbcount > 0)
+ uval64 >>= lsbcount;
uint64_t bitfield_mask = ((1ul << bitfield_bit_size) - 1);
if (!bitfield_mask && bitfield_bit_offset == 0 && bitfield_bit_size == 64)
return uval64;
@@ -755,8 +752,11 @@ DataExtractor::GetMaxS64Bitfield (offset_t *offset_ptr, size_t size, uint32_t bi
int64_t sval64 = GetMaxS64 (offset_ptr, size);
if (bitfield_bit_size > 0)
{
- if (bitfield_bit_offset > 0)
- sval64 >>= bitfield_bit_offset;
+ int32_t lsbcount = bitfield_bit_offset;
+ if (m_byte_order == eByteOrderBig)
+ lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
+ if (lsbcount > 0)
+ sval64 >>= lsbcount;
uint64_t bitfield_mask = (((uint64_t)1) << bitfield_bit_size) - 1;
sval64 &= bitfield_mask;
// sign extend if needed
@@ -780,7 +780,7 @@ DataExtractor::GetFloat (offset_t *offset_ptr) const
{
const uint8_t *src_data = (const uint8_t *)src;
uint8_t *dst_data = (uint8_t *)&val;
- for (size_t i=0; i<sizeof(float_type); ++i)
+ for (size_t i = 0; i < sizeof(float_type); ++i)
dst_data[sizeof(float_type) - 1 - i] = src_data[i];
}
else
@@ -804,7 +804,7 @@ DataExtractor::GetDouble (offset_t *offset_ptr) const
{
const uint8_t *src_data = (const uint8_t *)src;
uint8_t *dst_data = (uint8_t *)&val;
- for (size_t i=0; i<sizeof(float_type); ++i)
+ for (size_t i = 0; i < sizeof(float_type); ++i)
dst_data[sizeof(float_type) - 1 - i] = src_data[i];
}
else
@@ -828,7 +828,6 @@ DataExtractor::GetLongDouble (offset_t *offset_ptr) const
return val;
}
-
//------------------------------------------------------------------
// Extract a single address from the data and update the offset
// pointed to by "offset_ptr". The size of the extracted address
@@ -941,7 +940,7 @@ DataExtractor::GetGNUEHPointer (offset_t *offset_ptr, uint32_t eh_ptr_enc, lldb:
break;
default:
- break;
+ break;
}
// Decode the value part
@@ -963,9 +962,9 @@ DataExtractor::GetGNUEHPointer (offset_t *offset_ptr, uint32_t eh_ptr_enc, lldb:
case DW_EH_PE_sdata4 : addressValue = (int32_t)GetU32(offset_ptr); break;
case DW_EH_PE_sdata8 : addressValue = (int64_t)GetU64(offset_ptr); break;
default:
- // Unhandled encoding type
- assert(eh_ptr_enc);
- break;
+ // Unhandled encoding type
+ assert(eh_ptr_enc);
+ break;
}
// Since we promote everything to 64 bit, we may need to sign extend
@@ -993,7 +992,7 @@ DataExtractor::ExtractBytes (offset_t offset, offset_t length, ByteOrder dst_byt
assert (length == 1 || length == 2 || length == 4 || length == 8 ||
length == 10 || length == 16 || length == 32);
- for (uint32_t i=0; i<length; ++i)
+ for (uint32_t i = 0; i < length; ++i)
((uint8_t*)dst)[i] = src[length - i - 1];
}
else
@@ -1033,7 +1032,7 @@ DataExtractor::CopyByteOrderedData (offset_t src_offset,
assert (m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle);
// Validate the destination info
- assert (dst_void_ptr != NULL);
+ assert(dst_void_ptr != nullptr);
assert (dst_len > 0);
assert (dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle);
@@ -1047,7 +1046,6 @@ DataExtractor::CopyByteOrderedData (offset_t src_offset,
!(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle))
return 0;
- uint32_t i;
uint8_t* dst = (uint8_t*)dst_void_ptr;
const uint8_t* src = (const uint8_t *)PeekData (src_offset, src_len);
if (src)
@@ -1070,7 +1068,7 @@ DataExtractor::CopyByteOrderedData (offset_t src_offset,
}
else
{
- for (i=0; i<src_len; ++i)
+ for (uint32_t i = 0; i < src_len; ++i)
dst[i+num_zeroes] = src[src_len - 1 - i];
}
}
@@ -1079,7 +1077,7 @@ DataExtractor::CopyByteOrderedData (offset_t src_offset,
// Little endian destination, so we lead the value bytes
if (m_byte_order == eByteOrderBig)
{
- for (i=0; i<src_len; ++i)
+ for (uint32_t i = 0; i < src_len; ++i)
dst[i] = src[src_len - 1 - i];
}
else
@@ -1107,7 +1105,7 @@ DataExtractor::CopyByteOrderedData (offset_t src_offset,
else
{
// Big endian dst, with little endian src
- for (i=0; i<dst_len; ++i)
+ for (uint32_t i = 0; i < dst_len; ++i)
dst[i] = src[dst_len - 1 - i];
}
}
@@ -1117,7 +1115,7 @@ DataExtractor::CopyByteOrderedData (offset_t src_offset,
if (m_byte_order == eByteOrderBig)
{
// Little endian dst, with big endian src
- for (i=0; i<dst_len; ++i)
+ for (uint32_t i = 0; i < dst_len; ++i)
dst[i] = src[src_len - 1 - i];
}
else
@@ -1128,12 +1126,10 @@ DataExtractor::CopyByteOrderedData (offset_t src_offset,
}
return dst_len;
}
-
}
return 0;
}
-
//----------------------------------------------------------------------
// Extracts a variable length NULL terminated C string from
// the data at the offset pointed to by "offset_ptr". The
@@ -1142,7 +1138,7 @@ DataExtractor::CopyByteOrderedData (offset_t src_offset,
//
// If the offset pointed to by "offset_ptr" is out of bounds, or if
// "length" is non-zero and there aren't enough available
-// bytes, NULL will be returned and "offset_ptr" will not be
+// bytes, nullptr will be returned and "offset_ptr" will not be
// updated.
//----------------------------------------------------------------------
const char*
@@ -1166,11 +1162,11 @@ DataExtractor::GetCStr (offset_t *offset_ptr) const
}
// We reached the end of the data without finding a NULL C string
- // terminator. Fall through and return NULL otherwise anyone that
+ // terminator. Fall through and return nullptr otherwise anyone that
// would have used the result as a C string can wander into
// unknown memory...
}
- return NULL;
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -1181,23 +1177,23 @@ DataExtractor::GetCStr (offset_t *offset_ptr) const
//
// If the offset pointed to by "offset_ptr" is out of bounds, or if
// the offset plus the length of the field is out of bounds, or if the
-// field does not contain a NULL terminator byte, NULL will be returned
+// field does not contain a NULL terminator byte, nullptr will be returned
// and "offset_ptr" will not be updated.
//----------------------------------------------------------------------
const char*
DataExtractor::GetCStr (offset_t *offset_ptr, offset_t len) const
{
const char *cstr = (const char *)PeekData (*offset_ptr, len);
- if (cstr)
+ if (cstr != nullptr)
{
- if (memchr (cstr, '\0', len) == NULL)
+ if (memchr(cstr, '\0', len) == nullptr)
{
- return NULL;
+ return nullptr;
}
*offset_ptr += len;
return cstr;
}
- return NULL;
+ return nullptr;
}
//------------------------------------------------------------------
@@ -1206,7 +1202,7 @@ DataExtractor::GetCStr (offset_t *offset_ptr, offset_t len) const
// object's data, only "offset" is verified to be a valid offset.
//
// Returns a valid C string pointer if "offset" is a valid offset in
-// this object's data, else NULL is returned.
+// this object's data, else nullptr is returned.
//------------------------------------------------------------------
const char *
DataExtractor::PeekCStr (offset_t offset) const
@@ -1226,7 +1222,7 @@ uint64_t
DataExtractor::GetULEB128 (offset_t *offset_ptr) const
{
const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
- if (src == NULL)
+ if (src == nullptr)
return 0;
const uint8_t *end = m_end;
@@ -1241,7 +1237,7 @@ DataExtractor::GetULEB128 (offset_t *offset_ptr) const
while (src < end)
{
uint8_t byte = *src++;
- result |= (byte & 0x7f) << shift;
+ result |= (uint64_t)(byte & 0x7f) << shift;
if ((byte & 0x80) == 0)
break;
shift += 7;
@@ -1266,7 +1262,7 @@ int64_t
DataExtractor::GetSLEB128 (offset_t *offset_ptr) const
{
const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
- if (src == NULL)
+ if (src == nullptr)
return 0;
const uint8_t *end = m_end;
@@ -1284,7 +1280,7 @@ DataExtractor::GetSLEB128 (offset_t *offset_ptr) const
{
bytecount++;
byte = *src++;
- result |= (byte & 0x7f) << shift;
+ result |= (int64_t)(byte & 0x7f) << shift;
shift += 7;
if ((byte & 0x80) == 0)
break;
@@ -1313,7 +1309,7 @@ DataExtractor::Skip_LEB128 (offset_t *offset_ptr) const
{
uint32_t bytes_consumed = 0;
const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
- if (src == NULL)
+ if (src == nullptr)
return 0;
const uint8_t *end = m_end;
@@ -1435,7 +1431,7 @@ DataExtractor::Dump (Stream *s,
uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the shift amount to apply to a bitfield
ExecutionContextScope *exe_scope) const
{
- if (s == NULL)
+ if (s == nullptr)
return start_offset;
if (item_format == eFormatPointer)
@@ -1453,7 +1449,7 @@ DataExtractor::Dump (Stream *s,
target_sp = exe_scope->CalculateTarget();
if (target_sp)
{
- DisassemblerSP disassembler_sp (Disassembler::FindPlugin(target_sp->GetArchitecture(), NULL, NULL));
+ DisassemblerSP disassembler_sp(Disassembler::FindPlugin(target_sp->GetArchitecture(), nullptr, nullptr));
if (disassembler_sp)
{
lldb::addr_t addr = base_addr + start_offset;
@@ -1479,10 +1475,6 @@ DataExtractor::Dump (Stream *s,
ExecutionContext exe_ctx;
exe_scope->CalculateExecutionContext(exe_ctx);
disassembler_sp->GetInstructionList().Dump (s, show_address, show_bytes, &exe_ctx);
-
- // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
- // I'll fix that but for now, just clear the list and it will go away nicely.
- disassembler_sp->GetInstructionList().Clear();
}
}
}
@@ -1515,16 +1507,14 @@ DataExtractor::Dump (Stream *s,
line_start_offset = offset;
}
- else
- if (item_format != eFormatChar &&
- item_format != eFormatCharPrintable &&
- item_format != eFormatCharArray &&
- count > 0)
+ else if (item_format != eFormatChar &&
+ item_format != eFormatCharPrintable &&
+ item_format != eFormatCharArray &&
+ count > 0)
{
s->PutChar(' ');
}
- uint32_t i;
switch (item_format)
{
case eFormatBoolean:
@@ -1545,7 +1535,7 @@ DataExtractor::Dump (Stream *s,
// earlier C++ libraries
std::string binary_value(64, '0');
std::bitset<64> bits(uval64);
- for (i = 0; i < 64; ++i)
+ for (uint32_t i = 0; i < 64; ++i)
if (bits[i])
binary_value[64 - 1 - i] = '1';
if (item_bit_size > 0)
@@ -1563,7 +1553,7 @@ DataExtractor::Dump (Stream *s,
case eFormatBytes:
case eFormatBytesWithASCII:
- for (i=0; i<item_byte_size; ++i)
+ for (uint32_t i = 0; i < item_byte_size; ++i)
{
s->Printf ("%2.2x", GetU8(&offset));
}
@@ -1656,7 +1646,7 @@ DataExtractor::Dump (Stream *s,
{
uint64_t uval64 = GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset);
s->PutChar('\'');
- for (i=0; i<item_byte_size; ++i)
+ for (uint32_t i = 0; i < item_byte_size; ++i)
{
uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8));
if (isprint(ch))
@@ -2079,23 +2069,20 @@ DataExtractor::Dump (Stream *s,
// output information. "num_per_line" objects of type "type" will
// be dumped with the option to override the format for each object
// with "type_format". "type_format" is a printf style formatting
-// string. If "type_format" is NULL, then an appropriate format
+// string. If "type_format" is nullptr, then an appropriate format
// string will be used for the supplied "type". If the stream "s"
-// is NULL, then the output will be send to Log().
+// is nullptr, then the output will be send to Log().
//----------------------------------------------------------------------
lldb::offset_t
-DataExtractor::PutToLog
-(
- Log *log,
- offset_t start_offset,
- offset_t length,
- uint64_t base_addr,
- uint32_t num_per_line,
- DataExtractor::Type type,
- const char *format
-) const
-{
- if (log == NULL)
+DataExtractor::PutToLog(Log *log,
+ offset_t start_offset,
+ offset_t length,
+ uint64_t base_addr,
+ uint32_t num_per_line,
+ DataExtractor::Type type,
+ const char *format) const
+{
+ if (log == nullptr)
return start_offset;
offset_t offset;
@@ -2185,7 +2172,7 @@ DataExtractor::DumpHexBytes (Stream *s,
size_t
DataExtractor::Copy (DataExtractor &dest_data) const
{
- if (m_data_sp.get())
+ if (m_data_sp)
{
// we can pass along the SP to the data
dest_data.SetData(m_data_sp);
@@ -2213,10 +2200,10 @@ DataExtractor::Append(DataExtractor& rhs)
size_t bytes = GetByteSize() + rhs.GetByteSize();
- DataBufferHeap *buffer_heap_ptr = NULL;
+ DataBufferHeap *buffer_heap_ptr = nullptr;
DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
- if (buffer_sp.get() == NULL || buffer_heap_ptr == NULL)
+ if (!buffer_sp || buffer_heap_ptr == nullptr)
return false;
uint8_t* bytes_ptr = buffer_heap_ptr->GetBytes();
@@ -2232,7 +2219,7 @@ DataExtractor::Append(DataExtractor& rhs)
bool
DataExtractor::Append(void* buf, offset_t length)
{
- if (buf == NULL)
+ if (buf == nullptr)
return false;
if (length == 0)
@@ -2240,10 +2227,10 @@ DataExtractor::Append(void* buf, offset_t length)
size_t bytes = GetByteSize() + length;
- DataBufferHeap *buffer_heap_ptr = NULL;
+ DataBufferHeap *buffer_heap_ptr = nullptr;
DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
- if (buffer_sp.get() == NULL || buffer_heap_ptr == NULL)
+ if (!buffer_sp || buffer_heap_ptr == nullptr)
return false;
uint8_t* bytes_ptr = buffer_heap_ptr->GetBytes();
@@ -2280,4 +2267,3 @@ DataExtractor::Checksum (llvm::SmallVectorImpl<uint8_t> &dest,
result+16,
dest.begin());
}
-
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index d36800e20bc0..34608d0193fc 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -9,10 +9,16 @@
#include "lldb/Core/Debugger.h"
+// C Includes
+// C++ Includes
#include <map>
+#include <mutex>
+// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DynamicLibrary.h"
+// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Module.h"
@@ -54,34 +60,17 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/AnsiTerminal.h"
-#include "llvm/Support/DynamicLibrary.h"
-
using namespace lldb;
using namespace lldb_private;
-
static lldb::user_id_t g_unique_id = 1;
static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
#pragma mark Static Functions
-static Mutex &
-GetDebuggerListMutex ()
-{
- static Mutex g_mutex(Mutex::eMutexTypeRecursive);
- return g_mutex;
-}
-
typedef std::vector<DebuggerSP> DebuggerList;
-
-static DebuggerList &
-GetDebuggerList()
-{
- // hide the static debugger list inside a singleton accessor to avoid
- // global init constructors
- static DebuggerList g_list;
- return g_list;
-}
+static std::recursive_mutex *g_debugger_list_mutex_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
+static DebuggerList *g_debugger_list_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
OptionEnumValueElement
g_show_disassembly_enum_values[] =
@@ -90,7 +79,7 @@ g_show_disassembly_enum_values[] =
{ Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo", "Show disassembly when there is no debug information."},
{ Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
{ Debugger::eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."},
- { 0, NULL, NULL }
+ { 0, nullptr, nullptr }
};
OptionEnumValueElement
@@ -99,7 +88,7 @@ g_language_enumerators[] =
{ eScriptLanguageNone, "none", "Disable scripting languages."},
{ eScriptLanguagePython, "python", "Select python as the default scripting language."},
{ eScriptLanguageDefault, "default", "Select the lldb default as the default scripting language."},
- { 0, NULL, NULL }
+ { 0, nullptr, nullptr }
};
#define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
@@ -140,30 +129,29 @@ g_language_enumerators[] =
// lldb's original format for disassembly would look like this format string -
// {${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}:
-
static PropertyDefinition
g_properties[] =
{
-{ "auto-confirm", OptionValue::eTypeBoolean , true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
-{ "disassembly-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_DISASSEMBLY_FORMAT, NULL, "The default disassembly format string to use when disassembling instruction sequences." },
-{ "frame-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." },
-{ "notify-void", OptionValue::eTypeBoolean , true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
-{ "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
-{ "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
-{ "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
-{ "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoDebugInfo, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
-{ "stop-line-count-after", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come after the current source line when displaying a stopped context." },
-{ "stop-line-count-before", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come before the current source line when displaying a stopped context." },
-{ "term-width", OptionValue::eTypeSInt64 , true, 80 , NULL, NULL, "The maximum number of columns to use for displaying text." },
-{ "thread-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
-{ "use-external-editor", OptionValue::eTypeBoolean , true, false, NULL, NULL, "Whether to use an external editor or not." },
-{ "use-color", OptionValue::eTypeBoolean , true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
-{ "auto-one-line-summaries", OptionValue::eTypeBoolean , true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
-{ "auto-indent", OptionValue::eTypeBoolean , true, true , NULL, NULL, "If true, LLDB will auto indent/outdent code. Currently only supported in the REPL (default: true)." },
-{ "print-decls", OptionValue::eTypeBoolean , true, true , NULL, NULL, "If true, LLDB will print the values of variables declared in an expression. Currently only supported in the REPL (default: true)." },
-{ "tab-size", OptionValue::eTypeUInt64 , true, 4 , NULL, NULL, "The tab size to use when indenting code in multi-line input mode (default: 4)." },
-{ "escape-non-printables", OptionValue::eTypeBoolean , true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
-{ NULL, OptionValue::eTypeInvalid , true, 0 , NULL, NULL, NULL }
+{ "auto-confirm", OptionValue::eTypeBoolean , true, false, nullptr, nullptr, "If true all confirmation prompts will receive their default reply." },
+{ "disassembly-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_DISASSEMBLY_FORMAT, nullptr, "The default disassembly format string to use when disassembling instruction sequences." },
+{ "frame-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_FRAME_FORMAT, nullptr, "The default frame format string to use when displaying stack frame information for threads." },
+{ "notify-void", OptionValue::eTypeBoolean , true, false, nullptr, nullptr, "Notify the user explicitly if an expression returns void (default: false)." },
+{ "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", nullptr, "The debugger command line prompt displayed for the user." },
+{ "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, nullptr, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
+{ "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , nullptr, nullptr, "The number of disassembly lines to show when displaying a stopped context." },
+{ "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoDebugInfo, nullptr, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
+{ "stop-line-count-after", OptionValue::eTypeSInt64 , true, 3 , nullptr, nullptr, "The number of sources lines to display that come after the current source line when displaying a stopped context." },
+{ "stop-line-count-before", OptionValue::eTypeSInt64 , true, 3 , nullptr, nullptr, "The number of sources lines to display that come before the current source line when displaying a stopped context." },
+{ "term-width", OptionValue::eTypeSInt64 , true, 80 , nullptr, nullptr, "The maximum number of columns to use for displaying text." },
+{ "thread-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_THREAD_FORMAT, nullptr, "The default thread format string to use when displaying thread information." },
+{ "use-external-editor", OptionValue::eTypeBoolean , true, false, nullptr, nullptr, "Whether to use an external editor or not." },
+{ "use-color", OptionValue::eTypeBoolean , true, true , nullptr, nullptr, "Whether to use Ansi color codes or not." },
+{ "auto-one-line-summaries", OptionValue::eTypeBoolean , true, true, nullptr, nullptr, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
+{ "auto-indent", OptionValue::eTypeBoolean , true, true , nullptr, nullptr, "If true, LLDB will auto indent/outdent code. Currently only supported in the REPL (default: true)." },
+{ "print-decls", OptionValue::eTypeBoolean , true, true , nullptr, nullptr, "If true, LLDB will print the values of variables declared in an expression. Currently only supported in the REPL (default: true)." },
+{ "tab-size", OptionValue::eTypeUInt64 , true, 4 , nullptr, nullptr, "The tab size to use when indenting code in multi-line input mode (default: 4)." },
+{ "escape-non-printables", OptionValue::eTypeBoolean , true, true, nullptr, nullptr, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
+{ nullptr, OptionValue::eTypeInvalid , true, 0 , nullptr, nullptr, nullptr }
};
enum
@@ -189,7 +177,7 @@ enum
ePropertyEscapeNonPrintables
};
-LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL;
+LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr;
Error
Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
@@ -258,42 +246,42 @@ bool
Debugger::GetAutoConfirm () const
{
const uint32_t idx = ePropertyAutoConfirm;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
const FormatEntity::Entry *
Debugger::GetDisassemblyFormat() const
{
const uint32_t idx = ePropertyDisassemblyFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
const FormatEntity::Entry *
Debugger::GetFrameFormat() const
{
const uint32_t idx = ePropertyFrameFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
bool
Debugger::GetNotifyVoid () const
{
const uint32_t idx = ePropertyNotiftVoid;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
const char *
Debugger::GetPrompt() const
{
const uint32_t idx = ePropertyPrompt;
- return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
+ return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, g_properties[idx].default_cstr_value);
}
void
Debugger::SetPrompt(const char *p)
{
const uint32_t idx = ePropertyPrompt;
- m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
+ m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
const char *new_prompt = GetPrompt();
std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
if (str.length())
@@ -305,63 +293,63 @@ const FormatEntity::Entry *
Debugger::GetThreadFormat() const
{
const uint32_t idx = ePropertyThreadFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
lldb::ScriptLanguage
Debugger::GetScriptLanguage() const
{
const uint32_t idx = ePropertyScriptLanguage;
- return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
+ return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
}
bool
Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
{
const uint32_t idx = ePropertyScriptLanguage;
- return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
+ return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, script_lang);
}
uint32_t
Debugger::GetTerminalWidth () const
{
const uint32_t idx = ePropertyTerminalWidth;
- return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
+ return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value);
}
bool
Debugger::SetTerminalWidth (uint32_t term_width)
{
const uint32_t idx = ePropertyTerminalWidth;
- return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
+ return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width);
}
bool
Debugger::GetUseExternalEditor () const
{
const uint32_t idx = ePropertyUseExternalEditor;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
bool
Debugger::SetUseExternalEditor (bool b)
{
const uint32_t idx = ePropertyUseExternalEditor;
- return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
+ return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
bool
Debugger::GetUseColor () const
{
const uint32_t idx = ePropertyUseColor;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
bool
Debugger::SetUseColor (bool b)
{
const uint32_t idx = ePropertyUseColor;
- bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
+ bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
SetPrompt (GetPrompt());
return ret;
}
@@ -370,80 +358,79 @@ uint32_t
Debugger::GetStopSourceLineCount (bool before) const
{
const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
- return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
+ return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value);
}
Debugger::StopDisassemblyType
Debugger::GetStopDisassemblyDisplay () const
{
const uint32_t idx = ePropertyStopDisassemblyDisplay;
- return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
+ return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
}
uint32_t
Debugger::GetDisassemblyLineCount () const
{
const uint32_t idx = ePropertyStopDisassemblyCount;
- return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
+ return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value);
}
bool
Debugger::GetAutoOneLineSummaries () const
{
const uint32_t idx = ePropertyAutoOneLineSummaries;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}
bool
Debugger::GetEscapeNonPrintables () const
{
const uint32_t idx = ePropertyEscapeNonPrintables;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}
bool
Debugger::GetAutoIndent () const
{
const uint32_t idx = ePropertyAutoIndent;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}
bool
Debugger::SetAutoIndent (bool b)
{
const uint32_t idx = ePropertyAutoIndent;
- return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
+ return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
bool
Debugger::GetPrintDecls () const
{
const uint32_t idx = ePropertyPrintDecls;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}
bool
Debugger::SetPrintDecls (bool b)
{
const uint32_t idx = ePropertyPrintDecls;
- return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
+ return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
uint32_t
Debugger::GetTabSize () const
{
const uint32_t idx = ePropertyTabSize;
- return m_collection_sp->GetPropertyAtIndexAsUInt64 (NULL, idx, g_properties[idx].default_uint_value);
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(nullptr, idx, g_properties[idx].default_uint_value);
}
bool
Debugger::SetTabSize (uint32_t tab_size)
{
const uint32_t idx = ePropertyTabSize;
- return m_collection_sp->SetPropertyAtIndexAsUInt64 (NULL, idx, tab_size);
+ return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, tab_size);
}
-
#pragma mark Debugger
//const DebuggerPropertiesSP &
@@ -453,28 +440,30 @@ Debugger::SetTabSize (uint32_t tab_size)
//}
//
-static bool lldb_initialized = false;
void
Debugger::Initialize(LoadPluginCallbackType load_plugin_callback)
{
- assert(!lldb_initialized && "Debugger::Initialize called more than once!");
-
- lldb_initialized = true;
+ assert(g_debugger_list_ptr == nullptr && "Debugger::Initialize called more than once!");
+ g_debugger_list_mutex_ptr = new std::recursive_mutex();
+ g_debugger_list_ptr = new DebuggerList();
g_load_plugin_callback = load_plugin_callback;
}
void
Debugger::Terminate ()
{
- assert(lldb_initialized && "Debugger::Terminate called without a matching Debugger::Initialize!");
-
- // Clear our master list of debugger objects
- Mutex::Locker locker (GetDebuggerListMutex ());
- auto& debuggers = GetDebuggerList();
- for (const auto& debugger: debuggers)
- debugger->Clear();
+ assert(g_debugger_list_ptr && "Debugger::Terminate called without a matching Debugger::Initialize!");
- debuggers.clear();
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
+ {
+ // Clear our master list of debugger objects
+ {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ for (const auto& debugger: *g_debugger_list_ptr)
+ debugger->Clear();
+ g_debugger_list_ptr->clear();
+ }
+ }
}
void
@@ -512,12 +501,9 @@ Debugger::LoadPlugin (const FileSpec& spec, Error& error)
}
static FileSpec::EnumerateDirectoryResult
-LoadPluginCallback
-(
- void *baton,
- FileSpec::FileType file_type,
- const FileSpec &file_spec
- )
+LoadPluginCallback(void *baton,
+ FileSpec::FileType file_type,
+ const FileSpec &file_spec)
{
Error error;
@@ -551,7 +537,6 @@ LoadPluginCallback
return FileSpec::eEnumerateDirectoryResultNext;
}
-
else if (file_type == FileSpec::eFileTypeUnknown ||
file_type == FileSpec::eFileTypeDirectory ||
file_type == FileSpec::eFileTypeSymbolicLink )
@@ -607,10 +592,10 @@ DebuggerSP
Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
{
DebuggerSP debugger_sp (new Debugger(log_callback, baton));
- if (lldb_initialized)
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
{
- Mutex::Locker locker (GetDebuggerListMutex ());
- GetDebuggerList().push_back(debugger_sp);
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ g_debugger_list_ptr->push_back(debugger_sp);
}
debugger_sp->InstanceInitialize ();
return debugger_sp;
@@ -619,21 +604,20 @@ Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
void
Debugger::Destroy (DebuggerSP &debugger_sp)
{
- if (debugger_sp.get() == NULL)
+ if (!debugger_sp)
return;
debugger_sp->Clear();
- if (lldb_initialized)
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
{
- Mutex::Locker locker (GetDebuggerListMutex ());
- DebuggerList &debugger_list = GetDebuggerList ();
- DebuggerList::iterator pos, end = debugger_list.end();
- for (pos = debugger_list.begin (); pos != end; ++pos)
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
{
if ((*pos).get() == debugger_sp.get())
{
- debugger_list.erase (pos);
+ g_debugger_list_ptr->erase (pos);
return;
}
}
@@ -644,15 +628,13 @@ DebuggerSP
Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
{
DebuggerSP debugger_sp;
- if (lldb_initialized)
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
{
- Mutex::Locker locker (GetDebuggerListMutex ());
- DebuggerList &debugger_list = GetDebuggerList();
- DebuggerList::iterator pos, end = debugger_list.end();
-
- for (pos = debugger_list.begin(); pos != end; ++pos)
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
{
- if ((*pos).get()->m_instance_name == instance_name)
+ if ((*pos)->m_instance_name == instance_name)
{
debugger_sp = *pos;
break;
@@ -666,12 +648,11 @@ TargetSP
Debugger::FindTargetWithProcessID (lldb::pid_t pid)
{
TargetSP target_sp;
- if (lldb_initialized)
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
{
- Mutex::Locker locker (GetDebuggerListMutex ());
- DebuggerList &debugger_list = GetDebuggerList();
- DebuggerList::iterator pos, end = debugger_list.end();
- for (pos = debugger_list.begin(); pos != end; ++pos)
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
{
target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
if (target_sp)
@@ -685,12 +666,11 @@ TargetSP
Debugger::FindTargetWithProcess (Process *process)
{
TargetSP target_sp;
- if (lldb_initialized)
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
{
- Mutex::Locker locker (GetDebuggerListMutex ());
- DebuggerList &debugger_list = GetDebuggerList();
- DebuggerList::iterator pos, end = debugger_list.end();
- for (pos = debugger_list.begin(); pos != end; ++pos)
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
{
target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
if (target_sp)
@@ -706,19 +686,22 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
m_input_file_sp(new StreamFile(stdin, false)),
m_output_file_sp(new StreamFile(stdout, false)),
m_error_file_sp(new StreamFile(stderr, false)),
+ m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
m_terminal_state(),
m_target_list(*this),
m_platform_list(),
- m_listener("lldb.Debugger"),
+ m_listener_sp(Listener::MakeListener("lldb.Debugger")),
m_source_manager_ap(),
m_source_file_cache(),
m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
m_input_reader_stack(),
m_instance_name(),
m_loaded_plugins(),
- m_event_handler_thread (),
- m_io_handler_thread (),
- m_sync_broadcaster (NULL, "lldb.debugger.sync")
+ m_event_handler_thread(),
+ m_io_handler_thread(),
+ m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
+ m_forward_listener_sp(),
+ m_clear_once()
{
char instance_cstr[256];
snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
@@ -728,7 +711,7 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
m_command_interpreter_ap->Initialize ();
// Always add our default platform to the platform list
PlatformSP default_platform_sp (Platform::GetHostPlatform());
- assert (default_platform_sp.get());
+ assert(default_platform_sp);
m_platform_list.Append (default_platform_sp, true);
m_collection_sp->Initialize (g_properties);
@@ -740,14 +723,14 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
ConstString("Platform settings."),
true,
Platform::GetGlobalPlatformProperties()->GetValueProperties());
- if (m_command_interpreter_ap.get())
+ if (m_command_interpreter_ap)
{
m_collection_sp->AppendProperty (ConstString("interpreter"),
ConstString("Settings specify to the debugger's command interpreter."),
true,
m_command_interpreter_ap->GetValueProperties());
}
- OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
+ OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64(nullptr, ePropertyTerminalWidth);
term_width->SetMinimumValue(10);
term_width->SetMaximumValue(1024);
@@ -765,31 +748,44 @@ Debugger::~Debugger ()
void
Debugger::Clear()
{
- ClearIOHandlers();
- StopIOHandlerThread();
- StopEventHandlerThread();
- m_listener.Clear();
- int num_targets = m_target_list.GetNumTargets();
- for (int i = 0; i < num_targets; i++)
- {
- TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
- if (target_sp)
+ //----------------------------------------------------------------------
+ // Make sure we call this function only once. With the C++ global
+ // destructor chain having a list of debuggers and with code that can be
+ // running on other threads, we need to ensure this doesn't happen
+ // multiple times.
+ //
+ // The following functions call Debugger::Clear():
+ // Debugger::~Debugger();
+ // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp);
+ // static void Debugger::Terminate();
+ //----------------------------------------------------------------------
+ std::call_once(m_clear_once, [this]() {
+ ClearIOHandlers();
+ StopIOHandlerThread();
+ StopEventHandlerThread();
+ m_listener_sp->Clear();
+ int num_targets = m_target_list.GetNumTargets();
+ for (int i = 0; i < num_targets; i++)
{
- ProcessSP process_sp (target_sp->GetProcessSP());
- if (process_sp)
- process_sp->Finalize();
- target_sp->Destroy();
+ TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
+ if (target_sp)
+ {
+ ProcessSP process_sp (target_sp->GetProcessSP());
+ if (process_sp)
+ process_sp->Finalize();
+ target_sp->Destroy();
+ }
}
- }
- BroadcasterManager::Clear ();
-
- // Close the input file _before_ we close the input read communications class
- // as it does NOT own the input file, our m_input_file does.
- m_terminal_state.Clear();
- if (m_input_file_sp)
- m_input_file_sp->GetFile().Close ();
-
- m_command_interpreter_ap->Clear();
+ m_broadcaster_manager_sp->Clear ();
+
+ // Close the input file _before_ we close the input read communications class
+ // as it does NOT own the input file, our m_input_file does.
+ m_terminal_state.Clear();
+ if (m_input_file_sp)
+ m_input_file_sp->GetFile().Close ();
+
+ m_command_interpreter_ap->Clear();
+ });
}
bool
@@ -817,7 +813,6 @@ Debugger::SetAsyncExecution (bool async_execution)
m_command_interpreter_ap->SetSynchronous (!async_execution);
}
-
void
Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
{
@@ -827,7 +822,7 @@ Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
File &in_file = m_input_file_sp->GetFile();
- if (in_file.IsValid() == false)
+ if (!in_file.IsValid())
in_file.SetStream (stdin, true);
// Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
@@ -843,7 +838,7 @@ Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
File &out_file = m_output_file_sp->GetFile();
- if (out_file.IsValid() == false)
+ if (!out_file.IsValid())
out_file.SetStream (stdout, false);
// do not create the ScriptInterpreter just for setting the output file handle
@@ -863,7 +858,7 @@ Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
File &err_file = m_error_file_sp->GetFile();
- if (err_file.IsValid() == false)
+ if (!err_file.IsValid())
err_file.SetStream (stderr, false);
}
@@ -895,14 +890,14 @@ Debugger::GetSelectedExecutionContext ()
{
ProcessSP process_sp (target_sp->GetProcessSP());
exe_ctx.SetProcessSP (process_sp);
- if (process_sp && process_sp->IsRunning() == false)
+ if (process_sp && !process_sp->IsRunning())
{
ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
if (thread_sp)
{
exe_ctx.SetThreadSP (thread_sp);
exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
- if (exe_ctx.GetFramePtr() == NULL)
+ if (exe_ctx.GetFramePtr() == nullptr)
exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
}
}
@@ -911,40 +906,40 @@ Debugger::GetSelectedExecutionContext ()
}
void
-Debugger::DispatchInputInterrupt ()
+Debugger::DispatchInputInterrupt()
{
- Mutex::Locker locker (m_input_reader_stack.GetMutex());
- IOHandlerSP reader_sp (m_input_reader_stack.Top());
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ IOHandlerSP reader_sp(m_input_reader_stack.Top());
if (reader_sp)
reader_sp->Interrupt();
}
void
-Debugger::DispatchInputEndOfFile ()
+Debugger::DispatchInputEndOfFile()
{
- Mutex::Locker locker (m_input_reader_stack.GetMutex());
- IOHandlerSP reader_sp (m_input_reader_stack.Top());
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ IOHandlerSP reader_sp(m_input_reader_stack.Top());
if (reader_sp)
reader_sp->GotEOF();
}
void
-Debugger::ClearIOHandlers ()
+Debugger::ClearIOHandlers()
{
// The bottom input reader should be the main debugger input reader. We do not want to close that one here.
- Mutex::Locker locker (m_input_reader_stack.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
while (m_input_reader_stack.GetSize() > 1)
{
- IOHandlerSP reader_sp (m_input_reader_stack.Top());
+ IOHandlerSP reader_sp(m_input_reader_stack.Top());
if (reader_sp)
- PopIOHandler (reader_sp);
+ PopIOHandler(reader_sp);
}
}
void
Debugger::ExecuteIOHandlers()
{
- while (1)
+ while (true)
{
IOHandlerSP reader_sp(m_input_reader_stack.Top());
if (!reader_sp)
@@ -953,7 +948,7 @@ Debugger::ExecuteIOHandlers()
reader_sp->Run();
// Remove all input readers that are done from the top of the stack
- while (1)
+ while (true)
{
IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
if (top_reader_sp && top_reader_sp->GetIsDone())
@@ -1018,7 +1013,7 @@ Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
break;
}
- while (1)
+ while (true)
{
top_reader_sp = m_input_reader_stack.Top();
if (top_reader_sp && top_reader_sp->GetIsDone())
@@ -1030,16 +1025,16 @@ Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
}
void
-Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
+Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
{
// Before an IOHandler runs, it must have in/out/err streams.
// This function is called when one ore more of the streams
- // are NULL. We use the top input reader's in/out/err streams,
+ // are nullptr. We use the top input reader's in/out/err streams,
// or fall back to the debugger file handles, or we fall back
// onto stdin/stdout/stderr as a last resort.
-
- Mutex::Locker locker (m_input_reader_stack.GetMutex());
- IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
+
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
// If no STDIN has been set, then set it appropriately
if (!in)
{
@@ -1047,7 +1042,7 @@ Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out,
in = top_reader_sp->GetInputStreamFile();
else
in = GetInputFile();
-
+
// If there is nothing, use stdin
if (!in)
in = StreamFileSP(new StreamFile(stdin, false));
@@ -1059,7 +1054,7 @@ Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out,
out = top_reader_sp->GetOutputStreamFile();
else
out = GetOutputFile();
-
+
// If there is nothing, use stdout
if (!out)
out = StreamFileSP(new StreamFile(stdout, false));
@@ -1071,31 +1066,30 @@ Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out,
err = top_reader_sp->GetErrorStreamFile();
else
err = GetErrorFile();
-
+
// If there is nothing, use stderr
if (!err)
err = StreamFileSP(new StreamFile(stdout, false));
-
}
}
void
-Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
+Debugger::PushIOHandler(const IOHandlerSP &reader_sp)
{
if (!reader_sp)
return;
-
- Mutex::Locker locker (m_input_reader_stack.GetMutex());
+
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
// Get the current top input reader...
- IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
-
+ IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
+
// Don't push the same IO handler twice...
if (reader_sp == top_reader_sp)
return;
// Push our new input reader
- m_input_reader_stack.Push (reader_sp);
+ m_input_reader_stack.Push(reader_sp);
reader_sp->Activate();
// Interrupt the top input reader to it will exit its Run() function
@@ -1108,12 +1102,12 @@ Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
}
bool
-Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
+Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp)
{
- if (! pop_reader_sp)
+ if (!pop_reader_sp)
return false;
- Mutex::Locker locker (m_input_reader_stack.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
// The reader on the stop of the stack is done, so let the next
// read on the stack refresh its prompt and if there is one...
@@ -1127,7 +1121,7 @@ Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
reader_sp->Deactivate();
reader_sp->Cancel();
- m_input_reader_stack.Pop ();
+ m_input_reader_stack.Pop();
reader_sp = m_input_reader_stack.Top();
if (reader_sp)
@@ -1151,10 +1145,10 @@ Debugger::GetAsyncErrorStream ()
size_t
Debugger::GetNumDebuggers()
{
- if (lldb_initialized)
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
{
- Mutex::Locker locker (GetDebuggerListMutex ());
- return GetDebuggerList().size();
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ return g_debugger_list_ptr->size();
}
return 0;
}
@@ -1164,13 +1158,11 @@ Debugger::GetDebuggerAtIndex (size_t index)
{
DebuggerSP debugger_sp;
- if (lldb_initialized)
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
{
- Mutex::Locker locker (GetDebuggerListMutex ());
- DebuggerList &debugger_list = GetDebuggerList();
-
- if (index < debugger_list.size())
- debugger_sp = debugger_list[index];
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ if (index < g_debugger_list_ptr->size())
+ debugger_sp = g_debugger_list_ptr->at(index);
}
return debugger_sp;
@@ -1181,14 +1173,13 @@ Debugger::FindDebuggerWithID (lldb::user_id_t id)
{
DebuggerSP debugger_sp;
- if (lldb_initialized)
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
{
- Mutex::Locker locker (GetDebuggerListMutex ());
- DebuggerList &debugger_list = GetDebuggerList();
- DebuggerList::iterator pos, end = debugger_list.end();
- for (pos = debugger_list.begin(); pos != end; ++pos)
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
{
- if ((*pos).get()->GetID() == id)
+ if ((*pos)->GetID() == id)
{
debugger_sp = *pos;
break;
@@ -1202,7 +1193,7 @@ Debugger::FindDebuggerWithID (lldb::user_id_t id)
static void
TestPromptFormats (StackFrame *frame)
{
- if (frame == NULL)
+ if (frame == nullptr)
return;
StreamString s;
@@ -1277,11 +1268,11 @@ Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format,
{
FormatEntity::Entry format_entry;
- if (format == NULL)
+ if (format == nullptr)
{
- if (exe_ctx != NULL && exe_ctx->HasTargetScope())
+ if (exe_ctx != nullptr && exe_ctx->HasTargetScope())
format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
- if (format == NULL)
+ if (format == nullptr)
{
FormatEntity::Parse("${addr}: ", format_entry);
format = &format_entry;
@@ -1313,14 +1304,13 @@ Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format,
// has no Function or Symbol -- if SymbolContext had an IsValid() method, it
// would return false. But we do get a prev_sc pointer.
if ((sc && (sc->function || sc->symbol))
- && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL))
+ && prev_sc && (prev_sc->function == nullptr && prev_sc->symbol == nullptr))
{
initial_function = true;
}
- return FormatEntity::Format(*format, s, sc, exe_ctx, addr, NULL, function_changed, initial_function);
+ return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr, function_changed, initial_function);
}
-
void
Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
{
@@ -1340,7 +1330,7 @@ Debugger::EnableLog (const char *channel, const char **categories, const char *l
// For now when using the callback mode you always get thread & timestamp.
log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
}
- else if (log_file == NULL || *log_file == '\0')
+ else if (log_file == nullptr || *log_file == '\0')
{
log_stream_sp = GetOutputFile();
}
@@ -1360,7 +1350,7 @@ Debugger::EnableLog (const char *channel, const char **categories, const char *l
m_log_streams[log_file] = log_stream_sp;
}
}
- assert (log_stream_sp.get());
+ assert(log_stream_sp);
if (log_options == 0)
log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
@@ -1371,13 +1361,11 @@ Debugger::EnableLog (const char *channel, const char **categories, const char *l
SourceManager &
Debugger::GetSourceManager ()
{
- if (m_source_manager_ap.get() == NULL)
+ if (!m_source_manager_ap)
m_source_manager_ap.reset (new SourceManager (shared_from_this()));
return *m_source_manager_ap;
}
-
-
// This function handles events that were broadcast by the process.
void
Debugger::HandleBreakpointEvent (const EventSP &event_sp)
@@ -1428,13 +1416,13 @@ size_t
Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
{
size_t total_bytes = 0;
- if (stream == NULL)
+ if (stream == nullptr)
stream = GetOutputFile().get();
if (stream)
{
// The process has stuff waiting for stdout; get it and write it out to the appropriate place.
- if (process == NULL)
+ if (process == nullptr)
{
TargetSP target_sp = GetTargetList().GetSelectedTarget();
if (target_sp)
@@ -1460,13 +1448,13 @@ size_t
Debugger::GetProcessSTDERR (Process *process, Stream *stream)
{
size_t total_bytes = 0;
- if (stream == NULL)
+ if (stream == nullptr)
stream = GetOutputFile().get();
if (stream)
{
// The process has stuff waiting for stderr; get it and write it out to the appropriate place.
- if (process == NULL)
+ if (process == nullptr)
{
TargetSP target_sp = GetTargetList().GetSelectedTarget();
if (target_sp)
@@ -1588,7 +1576,7 @@ Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
void
Debugger::DefaultEventHandler()
{
- Listener& listener(GetListener());
+ ListenerSP listener_sp(GetListener());
ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
@@ -1604,10 +1592,10 @@ Debugger::DefaultEventHandler()
Thread::eBroadcastBitStackChanged |
Thread::eBroadcastBitThreadSelected );
- listener.StartListeningForEventSpec (*this, target_event_spec);
- listener.StartListeningForEventSpec (*this, process_event_spec);
- listener.StartListeningForEventSpec (*this, thread_event_spec);
- listener.StartListeningForEvents (m_command_interpreter_ap.get(),
+ listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, target_event_spec);
+ listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, process_event_spec);
+ listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, thread_event_spec);
+ listener_sp->StartListeningForEvents (m_command_interpreter_ap.get(),
CommandInterpreter::eBroadcastBitQuitCommandReceived |
CommandInterpreter::eBroadcastBitAsynchronousOutputData |
CommandInterpreter::eBroadcastBitAsynchronousErrorData );
@@ -1620,7 +1608,7 @@ Debugger::DefaultEventHandler()
while (!done)
{
EventSP event_sp;
- if (listener.WaitForEvent(NULL, event_sp))
+ if (listener_sp->WaitForEvent(nullptr, event_sp))
{
if (event_sp)
{
@@ -1702,21 +1690,22 @@ Debugger::StartEventHandlerThread()
// it is up and running and listening to events before we return from
// this function. We do this by listening to events for the
// eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
- Listener listener("lldb.debugger.event-handler");
- listener.StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
+ ListenerSP listener_sp(Listener::MakeListener("lldb.debugger.event-handler"));
+ listener_sp->StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
// Use larger 8MB stack for this thread
- m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread,
+ m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler",
+ EventHandlerThread,
this,
- NULL,
+ nullptr,
g_debugger_event_thread_stack_bytes);
// Make sure DefaultEventHandler() is running and listening to events before we return
// from this function. We are only listening for events of type
// eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
- // to wait an infinite amount of time for it (NULL timeout as the first parameter)
+ // to wait an infinite amount of time for it (nullptr timeout as the first parameter)
lldb::EventSP event_sp;
- listener.WaitForEvent(NULL, event_sp);
+ listener_sp->WaitForEvent(nullptr, event_sp);
}
return m_event_handler_thread.IsJoinable();
}
@@ -1731,7 +1720,6 @@ Debugger::StopEventHandlerThread()
}
}
-
lldb::thread_result_t
Debugger::IOHandlerThread (lldb::thread_arg_t arg)
{
@@ -1751,11 +1739,11 @@ bool
Debugger::StartIOHandlerThread()
{
if (!m_io_handler_thread.IsJoinable())
- m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler",
- IOHandlerThread,
- this,
- NULL,
- 8*1024*1024); // Use larger 8MB stack for this thread
+ m_io_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.io-handler",
+ IOHandlerThread,
+ this,
+ nullptr,
+ 8*1024*1024); // Use larger 8MB stack for this thread
return m_io_handler_thread.IsJoinable();
}
@@ -1817,9 +1805,9 @@ Debugger::RunREPL (LanguageType language, const char *repl_options)
{
language = *repl_languages.begin();
}
- else if (repl_languages.size() == 0)
+ else if (repl_languages.empty())
{
- err.SetErrorStringWithFormat("LLDB isn't configured with support support for any REPLs.");
+ err.SetErrorStringWithFormat("LLDB isn't configured with REPL support for any languages.");
return err;
}
else
@@ -1849,4 +1837,3 @@ Debugger::RunREPL (LanguageType language, const char *repl_options)
return err;
}
-
diff --git a/source/Core/Disassembler.cpp b/source/Core/Disassembler.cpp
index bb5f106ca611..1e6a245261bb 100644
--- a/source/Core/Disassembler.cpp
+++ b/source/Core/Disassembler.cpp
@@ -11,18 +11,21 @@
// C Includes
// C++ Includes
+#include <cstdio>
+#include <cstring>
+
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Core/Error.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Core/Error.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Interpreter/OptionValue.h"
#include "lldb/Interpreter/OptionValueArray.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
@@ -35,13 +38,13 @@
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
+#include "lldb/lldb-private.h"
#define DEFAULT_DISASM_BYTE_SIZE 32
using namespace lldb;
using namespace lldb_private;
-
DisassemblerSP
Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name)
{
@@ -50,7 +53,7 @@ Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *
arch.GetArchitectureName(),
plugin_name);
- DisassemblerCreateInstance create_callback = NULL;
+ DisassemblerCreateInstance create_callback = nullptr;
if (plugin_name)
{
@@ -60,17 +63,17 @@ Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *
{
DisassemblerSP disassembler_sp(create_callback(arch, flavor));
- if (disassembler_sp.get())
+ if (disassembler_sp)
return disassembler_sp;
}
}
else
{
- for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != nullptr; ++idx)
{
DisassemblerSP disassembler_sp(create_callback(arch, flavor));
- if (disassembler_sp.get())
+ if (disassembler_sp)
return disassembler_sp;
}
}
@@ -80,7 +83,7 @@ Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *
DisassemblerSP
Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name)
{
- if (target_sp && flavor == NULL)
+ if (target_sp && flavor == nullptr)
{
// FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now
// we only support flavors on x86 & x86_64,
@@ -91,7 +94,6 @@ Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch
return FindPlugin(arch, flavor, plugin_name);
}
-
static void
ResolveAddress (const ExecutionContext &exe_ctx,
const Address &addr,
@@ -122,19 +124,16 @@ ResolveAddress (const ExecutionContext &exe_ctx,
}
size_t
-Disassembler::Disassemble
-(
- Debugger &debugger,
- const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const ExecutionContext &exe_ctx,
- SymbolContextList &sc_list,
- uint32_t num_instructions,
- uint32_t num_mixed_context_lines,
- uint32_t options,
- Stream &strm
-)
+Disassembler::Disassemble(Debugger &debugger,
+ const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const ExecutionContext &exe_ctx,
+ SymbolContextList &sc_list,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ uint32_t options,
+ Stream &strm)
{
size_t success_count = 0;
const size_t count = sc_list.GetSize();
@@ -142,9 +141,9 @@ Disassembler::Disassemble
AddressRange range;
const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
const bool use_inline_block_range = true;
- for (size_t i=0; i<count; ++i)
+ for (size_t i = 0; i < count; ++i)
{
- if (sc_list.GetContextAtIndex(i, sc) == false)
+ if (!sc_list.GetContextAtIndex(i, sc))
break;
for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx)
{
@@ -168,20 +167,17 @@ Disassembler::Disassemble
}
bool
-Disassembler::Disassemble
-(
- Debugger &debugger,
- const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const ExecutionContext &exe_ctx,
- const ConstString &name,
- Module *module,
- uint32_t num_instructions,
- uint32_t num_mixed_context_lines,
- uint32_t options,
- Stream &strm
-)
+Disassembler::Disassemble(Debugger &debugger,
+ const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const ExecutionContext &exe_ctx,
+ const ConstString &name,
+ Module *module,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ uint32_t options,
+ Stream &strm)
{
SymbolContextList sc_list;
if (name)
@@ -190,13 +186,13 @@ Disassembler::Disassemble
const bool include_inlines = true;
if (module)
{
- module->FindFunctions (name,
- NULL,
- eFunctionNameTypeAuto,
- include_symbols,
- include_inlines,
- true,
- sc_list);
+ module->FindFunctions(name,
+ nullptr,
+ eFunctionNameTypeAuto,
+ include_symbols,
+ include_inlines,
+ true,
+ sc_list);
}
else if (exe_ctx.GetTargetPtr())
{
@@ -225,17 +221,13 @@ Disassembler::Disassemble
return false;
}
-
lldb::DisassemblerSP
-Disassembler::DisassembleRange
-(
- const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const ExecutionContext &exe_ctx,
- const AddressRange &range,
- bool prefer_file_cache
-)
+Disassembler::DisassembleRange(const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const ExecutionContext &exe_ctx,
+ const AddressRange &range,
+ bool prefer_file_cache)
{
lldb::DisassemblerSP disasm_sp;
if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
@@ -244,7 +236,7 @@ Disassembler::DisassembleRange
if (disasm_sp)
{
- size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL, prefer_file_cache);
+ size_t bytes_disassembled = disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache);
if (bytes_disassembled == 0)
disasm_sp.reset();
}
@@ -284,27 +276,23 @@ Disassembler::DisassembleBytes (const ArchSpec &arch,
return disasm_sp;
}
-
bool
-Disassembler::Disassemble
-(
- Debugger &debugger,
- const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const ExecutionContext &exe_ctx,
- const AddressRange &disasm_range,
- uint32_t num_instructions,
- uint32_t num_mixed_context_lines,
- uint32_t options,
- Stream &strm
-)
+Disassembler::Disassemble(Debugger &debugger,
+ const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const ExecutionContext &exe_ctx,
+ const AddressRange &disasm_range,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ uint32_t options,
+ Stream &strm)
{
if (disasm_range.GetByteSize())
{
lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
- if (disasm_sp.get())
+ if (disasm_sp)
{
AddressRange range;
ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
@@ -314,38 +302,24 @@ Disassembler::Disassemble
if (bytes_disassembled == 0)
return false;
- bool result = PrintInstructions (disasm_sp.get(),
- debugger,
- arch,
- exe_ctx,
- num_instructions,
- num_mixed_context_lines,
- options,
- strm);
-
- // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
- // I'll fix that but for now, just clear the list and it will go away nicely.
- disasm_sp->GetInstructionList().Clear();
- return result;
+ return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, num_instructions,
+ num_mixed_context_lines, options, strm);
}
}
return false;
}
bool
-Disassembler::Disassemble
-(
- Debugger &debugger,
- const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const ExecutionContext &exe_ctx,
- const Address &start_address,
- uint32_t num_instructions,
- uint32_t num_mixed_context_lines,
- uint32_t options,
- Stream &strm
-)
+Disassembler::Disassemble(Debugger &debugger,
+ const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const ExecutionContext &exe_ctx,
+ const Address &start_address,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ uint32_t options,
+ Stream &strm)
{
if (num_instructions > 0)
{
@@ -353,7 +327,7 @@ Disassembler::Disassemble
arch,
flavor,
plugin_name));
- if (disasm_sp.get())
+ if (disasm_sp)
{
Address addr;
ResolveAddress (exe_ctx, start_address, addr);
@@ -364,36 +338,17 @@ Disassembler::Disassemble
prefer_file_cache);
if (bytes_disassembled == 0)
return false;
- bool result = PrintInstructions (disasm_sp.get(),
- debugger,
- arch,
- exe_ctx,
- num_instructions,
- num_mixed_context_lines,
- options,
- strm);
-
- // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
- // I'll fix that but for now, just clear the list and it will go away nicely.
- disasm_sp->GetInstructionList().Clear();
- return result;
+ return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, num_instructions,
+ num_mixed_context_lines, options, strm);
}
}
return false;
}
-
-bool
-Disassembler::PrintInstructions
-(
- Disassembler *disasm_ptr,
- Debugger &debugger,
- const ArchSpec &arch,
- const ExecutionContext &exe_ctx,
- uint32_t num_instructions,
- uint32_t num_mixed_context_lines,
- uint32_t options,
- Stream &strm
-)
+
+bool
+Disassembler::PrintInstructions(Disassembler *disasm_ptr, Debugger &debugger, const ArchSpec &arch,
+ const ExecutionContext &exe_ctx, uint32_t num_instructions,
+ uint32_t num_mixed_context_lines, uint32_t options, Stream &strm)
{
// We got some things disassembled...
size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
@@ -406,7 +361,7 @@ Disassembler::PrintInstructions
SymbolContext sc;
SymbolContext prev_sc;
AddressRange sc_range;
- const Address *pc_addr_ptr = NULL;
+ const Address *pc_addr_ptr = nullptr;
StackFrame *frame = exe_ctx.GetFramePtr();
TargetSP target_sp (exe_ctx.GetTargetSP());
@@ -419,7 +374,7 @@ Disassembler::PrintInstructions
const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
const bool use_inline_block_range = false;
- const FormatEntity::Entry *disassembly_format = NULL;
+ const FormatEntity::Entry *disassembly_format = nullptr;
FormatEntity::Entry format;
if (exe_ctx.HasTargetScope())
{
@@ -449,7 +404,7 @@ Disassembler::PrintInstructions
if (resolved_mask)
{
StreamString strmstr;
- Debugger::FormatDisassemblerAddress (disassembly_format, &sc, NULL, &exe_ctx, &addr, strmstr);
+ Debugger::FormatDisassemblerAddress(disassembly_format, &sc, nullptr, &exe_ctx, &addr, strmstr);
size_t cur_line = strmstr.GetSizeOfLastLine();
if (cur_line > address_text_size)
address_text_size = cur_line;
@@ -509,7 +464,7 @@ Disassembler::PrintInstructions
}
const bool show_bytes = (options & eOptionShowBytes) != 0;
- inst->Dump (&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, NULL, address_text_size);
+ inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, nullptr, address_text_size);
strm.EOL();
}
else
@@ -521,20 +476,16 @@ Disassembler::PrintInstructions
return true;
}
-
bool
-Disassembler::Disassemble
-(
- Debugger &debugger,
- const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const ExecutionContext &exe_ctx,
- uint32_t num_instructions,
- uint32_t num_mixed_context_lines,
- uint32_t options,
- Stream &strm
-)
+Disassembler::Disassemble(Debugger &debugger,
+ const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const ExecutionContext &exe_ctx,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ uint32_t options,
+ Stream &strm)
{
AddressRange range;
StackFrame *frame = exe_ctx.GetFramePtr();
@@ -579,9 +530,7 @@ Instruction::Instruction(const Address &address, AddressClass addr_class) :
{
}
-Instruction::~Instruction()
-{
-}
+Instruction::~Instruction() = default;
AddressClass
Instruction::GetAddressClass ()
@@ -664,12 +613,12 @@ Instruction::Dump (lldb_private::Stream *s,
bool
Instruction::DumpEmulation (const ArchSpec &arch)
{
- std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
- if (insn_emulator_ap.get())
- {
- insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
+ std::unique_ptr<EmulateInstruction> insn_emulator_ap(EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr));
+ if (insn_emulator_ap)
+ {
+ insn_emulator_ap->SetInstruction(GetOpcode(), GetAddress(), nullptr);
return insn_emulator_ap->EvaluateInstruction (0);
- }
+ }
return false;
}
@@ -714,7 +663,7 @@ Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type dat
line.clear();
}
- if (line.size() > 0)
+ if (!line.empty())
{
std::string value;
static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
@@ -784,7 +733,7 @@ Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
}
// Try to find a key-value pair in the current line and add it to the dictionary.
- if (line.size() > 0)
+ if (!line.empty())
{
static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
RegularExpression::Match regex_match(2);
@@ -816,7 +765,7 @@ Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
assert (value.size() == 1);
// value is a dictionary
value_sp = ReadDictionary (in_file, out_stream);
- if (value_sp.get() == NULL)
+ if (!value_sp)
{
option_value_sp.reset ();
return option_value_sp;
@@ -827,7 +776,7 @@ Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
assert (value.size() == 1);
// value is an array
value_sp = ReadArray (in_file, out_stream, data_type);
- if (value_sp.get() == NULL)
+ if (!value_sp)
{
option_value_sp.reset ();
return option_value_sp;
@@ -848,8 +797,6 @@ Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
value_sp.reset (new OptionValueString (value.c_str(), ""));
}
-
-
if (const_key == encoding_key)
{
// A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
@@ -876,8 +823,7 @@ Instruction::TestEmulation (Stream *out_stream, const char *file_name)
out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
return false;
}
-
- FILE *test_file = fopen (file_name, "r");
+ FILE *test_file = FileSystem::Fopen(file_name, "r");
if (!test_file)
{
out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
@@ -902,7 +848,7 @@ Instruction::TestEmulation (Stream *out_stream, const char *file_name)
// Read all the test information from the test file into an OptionValueDictionary.
OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
- if (data_dictionary_sp.get() == NULL)
+ if (!data_dictionary_sp)
{
out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
fclose (test_file);
@@ -917,17 +863,16 @@ Instruction::TestEmulation (Stream *out_stream, const char *file_name)
OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
- if (value_sp.get() == NULL)
+ if (!value_sp)
{
out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
return false;
}
SetDescription (value_sp->GetStringValue());
-
-
+
value_sp = data_dictionary->GetValueForKey (triple_key);
- if (value_sp.get() == NULL)
+ if (!value_sp)
{
out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
return false;
@@ -937,8 +882,8 @@ Instruction::TestEmulation (Stream *out_stream, const char *file_name)
arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
bool success = false;
- std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
- if (insn_emulator_ap.get())
+ std::unique_ptr<EmulateInstruction> insn_emulator_ap(EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr));
+ if (insn_emulator_ap)
success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
if (success)
@@ -958,19 +903,18 @@ Instruction::Emulate (const ArchSpec &arch,
EmulateInstruction::ReadRegisterCallback read_reg_callback,
EmulateInstruction::WriteRegisterCallback write_reg_callback)
{
- std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
- if (insn_emulator_ap.get())
- {
- insn_emulator_ap->SetBaton (baton);
- insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
- insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
- return insn_emulator_ap->EvaluateInstruction (evaluate_options);
- }
+ std::unique_ptr<EmulateInstruction> insn_emulator_ap(EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr));
+ if (insn_emulator_ap)
+ {
+ insn_emulator_ap->SetBaton(baton);
+ insn_emulator_ap->SetCallbacks(read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
+ insn_emulator_ap->SetInstruction(GetOpcode(), GetAddress(), nullptr);
+ return insn_emulator_ap->EvaluateInstruction(evaluate_options);
+ }
return false;
}
-
uint32_t
Instruction::GetData (DataExtractor &data)
{
@@ -982,9 +926,7 @@ InstructionList::InstructionList() :
{
}
-InstructionList::~InstructionList()
-{
-}
+InstructionList::~InstructionList() = default;
size_t
InstructionList::GetSize() const
@@ -1008,8 +950,6 @@ InstructionList::GetMaxOpcocdeByteSize () const
return max_inst_size;
}
-
-
InstructionSP
InstructionList::GetInstructionAtIndex (size_t idx) const
{
@@ -1028,7 +968,7 @@ InstructionList::Dump (Stream *s,
const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
collection::const_iterator pos, begin, end;
- const FormatEntity::Entry *disassembly_format = NULL;
+ const FormatEntity::Entry *disassembly_format = nullptr;
FormatEntity::Entry format;
if (exe_ctx && exe_ctx->HasTargetScope())
{
@@ -1046,15 +986,14 @@ InstructionList::Dump (Stream *s,
{
if (pos != begin)
s->EOL();
- (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, NULL, NULL, disassembly_format, 0);
+ (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, nullptr, nullptr, disassembly_format, 0);
}
}
-
void
InstructionList::Clear()
{
- m_instructions.clear();
+ m_instructions.clear();
}
void
@@ -1144,7 +1083,6 @@ InstructionList::GetIndexOfInstructionAtAddress (const Address &address)
return index;
}
-
uint32_t
InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
{
@@ -1163,7 +1101,7 @@ Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
{
Target *target = exe_ctx->GetTargetPtr();
const addr_t byte_size = range.GetByteSize();
- if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
+ if (target == nullptr || byte_size == 0 || !range.GetBaseAddress().IsValid())
return 0;
DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
@@ -1186,7 +1124,8 @@ Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
m_arch.GetByteOrder(),
m_arch.GetAddressByteSize());
const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
- return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file);
+ return DecodeInstructions(range.GetBaseAddress(), data, 0, UINT32_MAX, false,
+ data_from_file);
}
else if (error_strm_ptr)
{
@@ -1212,14 +1151,14 @@ Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
{
m_instruction_list.Clear();
- if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
+ if (exe_ctx == nullptr || num_instructions == 0 || !start.IsValid())
return 0;
Target *target = exe_ctx->GetTargetPtr();
// Calculate the max buffer size we will need in order to disassemble
const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
- if (target == NULL || byte_size == 0)
+ if (target == nullptr || byte_size == 0)
return 0;
DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
@@ -1262,7 +1201,7 @@ Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
m_base_addr(LLDB_INVALID_ADDRESS),
m_flavor ()
{
- if (flavor == NULL)
+ if (flavor == nullptr)
m_flavor.assign("default");
else
m_flavor.assign(flavor);
@@ -1270,10 +1209,7 @@ Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
// If this is an arm variant that can only include thumb (T16, T32)
// instructions, force the arch triple to be "thumbv.." instead of
// "armv..."
- if ((arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb)
- && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m
- || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em
- || arch.GetCore() == ArchSpec::Core::eCore_arm_armv6m))
+ if (arch.IsAlwaysThumbInstructions())
{
std::string thumb_arch_name (arch.GetTriple().getArchName().str());
// Replace "arm" with "thumb" so we get all thumb variants correct
@@ -1286,12 +1222,7 @@ Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
}
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-Disassembler::~Disassembler()
-{
-}
+Disassembler::~Disassembler() = default;
InstructionList &
Disassembler::GetInstructionList ()
@@ -1308,15 +1239,14 @@ Disassembler::GetInstructionList () const
//----------------------------------------------------------------------
// Class PseudoInstruction
//----------------------------------------------------------------------
+
PseudoInstruction::PseudoInstruction () :
Instruction (Address(), eAddressClassUnknown),
m_description ()
{
}
-PseudoInstruction::~PseudoInstruction ()
-{
-}
+PseudoInstruction::~PseudoInstruction() = default;
bool
PseudoInstruction::DoesBranch ()
@@ -1340,7 +1270,6 @@ PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
return m_opcode.GetByteSize();
}
-
void
PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
{
diff --git a/source/Core/DynamicLoader.cpp b/source/Core/DynamicLoader.cpp
index 4d2824c5f334..f41ff4a80c83 100644
--- a/source/Core/DynamicLoader.cpp
+++ b/source/Core/DynamicLoader.cpp
@@ -7,6 +7,10 @@
//
//===----------------------------------------------------------------------===//
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
@@ -22,7 +26,7 @@ using namespace lldb_private;
DynamicLoader*
DynamicLoader::FindPlugin (Process *process, const char *plugin_name)
{
- DynamicLoaderCreateInstance create_callback = NULL;
+ DynamicLoaderCreateInstance create_callback = nullptr;
if (plugin_name)
{
ConstString const_plugin_name(plugin_name);
@@ -30,42 +34,34 @@ DynamicLoader::FindPlugin (Process *process, const char *plugin_name)
if (create_callback)
{
std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true));
- if (instance_ap.get())
+ if (instance_ap)
return instance_ap.release();
}
}
else
{
- for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != nullptr; ++idx)
{
std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false));
- if (instance_ap.get())
+ if (instance_ap)
return instance_ap.release();
}
}
- return NULL;
+ return nullptr;
}
-
-//----------------------------------------------------------------------
-// DynamicLoader constructor
-//----------------------------------------------------------------------
DynamicLoader::DynamicLoader(Process *process) :
m_process (process)
{
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-DynamicLoader::~DynamicLoader()
-{
-}
+DynamicLoader::~DynamicLoader() = default;
//----------------------------------------------------------------------
// Accessosors to the global setting as to whether to stop at image
// (shared library) loading/unloading.
//----------------------------------------------------------------------
+
bool
DynamicLoader::GetStopWhenImagesChange () const
{
@@ -84,7 +80,7 @@ DynamicLoader::GetTargetExecutable()
Target &target = m_process->GetTarget();
ModuleSP executable = target.GetExecutableModule();
- if (executable.get())
+ if (executable)
{
if (executable->GetFileSpec().Exists())
{
@@ -92,7 +88,7 @@ DynamicLoader::GetTargetExecutable()
ModuleSP module_sp (new Module (module_spec));
// Check if the executable has changed and set it to the target executable if they differ.
- if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
+ if (module_sp && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
{
if (module_sp->GetUUID() != executable->GetUUID())
executable.reset();
@@ -102,7 +98,7 @@ DynamicLoader::GetTargetExecutable()
executable.reset();
}
- if (!executable.get())
+ if (!executable)
{
executable = target.GetSharedModule(module_spec);
if (executable.get() != target.GetExecutableModulePointer())
@@ -158,15 +154,14 @@ DynamicLoader::UnloadSectionsCommon(const ModuleSP module)
}
}
-
const SectionList *
DynamicLoader::GetSectionListFromModule(const ModuleSP module) const
{
SectionList *sections = nullptr;
- if (module.get())
+ if (module)
{
ObjectFile *obj_file = module->GetObjectFile();
- if (obj_file)
+ if (obj_file != nullptr)
{
sections = obj_file->GetSectionList();
}
@@ -199,7 +194,7 @@ DynamicLoader::LoadModuleAtAddress(const FileSpec &file,
{
// Try to fetch the load address of the file from the process as we need absolute load
// address to read the file out of the memory instead of a load bias.
- bool is_loaded;
+ bool is_loaded = false;
lldb::addr_t load_addr;
Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr);
if (error.Success() && is_loaded)
@@ -220,7 +215,6 @@ int64_t
DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes)
{
Error error;
-
uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
if (error.Fail())
return -1;
diff --git a/source/Core/EmulateInstruction.cpp b/source/Core/EmulateInstruction.cpp
index 9b6beeb8299a..e46cfb2d8945 100644
--- a/source/Core/EmulateInstruction.cpp
+++ b/source/Core/EmulateInstruction.cpp
@@ -9,6 +9,12 @@
#include "lldb/Core/EmulateInstruction.h"
+// C Includes
+// C++ Includes
+#include <cstring>
+
+// Other libraries and framework includes
+// Project includes
#include "lldb/Core/Address.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
@@ -29,7 +35,7 @@ using namespace lldb_private;
EmulateInstruction*
EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
{
- EmulateInstructionCreateInstance create_callback = NULL;
+ EmulateInstructionCreateInstance create_callback = nullptr;
if (plugin_name)
{
ConstString const_plugin_name (plugin_name);
@@ -43,33 +49,32 @@ EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_
}
else
{
- for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != nullptr; ++idx)
{
EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
if (emulate_insn_ptr)
return emulate_insn_ptr;
}
}
- return NULL;
+ return nullptr;
}
EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
- m_arch (arch),
- m_baton (NULL),
- m_read_mem_callback (&ReadMemoryDefault),
- m_write_mem_callback (&WriteMemoryDefault),
- m_read_reg_callback (&ReadRegisterDefault),
- m_write_reg_callback (&WriteRegisterDefault),
- m_addr (LLDB_INVALID_ADDRESS)
+ m_arch(arch),
+ m_baton(nullptr),
+ m_read_mem_callback(&ReadMemoryDefault),
+ m_write_mem_callback(&WriteMemoryDefault),
+ m_read_reg_callback(&ReadRegisterDefault),
+ m_write_reg_callback(&WriteRegisterDefault),
+ m_addr(LLDB_INVALID_ADDRESS)
{
::memset (&m_opcode, 0, sizeof (m_opcode));
}
-
bool
EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& reg_value)
{
- if (m_read_reg_callback)
+ if (m_read_reg_callback != nullptr)
return m_read_reg_callback (this, m_baton, reg_info, reg_value);
return false;
}
@@ -115,7 +120,7 @@ EmulateInstruction::WriteRegister (const Context &context,
const RegisterInfo *reg_info,
const RegisterValue& reg_value)
{
- if (m_write_reg_callback)
+ if (m_write_reg_callback != nullptr)
return m_write_reg_callback (this, m_baton, context, reg_info, reg_value);
return false;
}
@@ -132,14 +137,12 @@ EmulateInstruction::WriteRegister (const Context &context,
return false;
}
-
bool
EmulateInstruction::WriteRegisterUnsigned (const Context &context,
lldb::RegisterKind reg_kind,
uint32_t reg_num,
uint64_t uint_value)
{
-
RegisterInfo reg_info;
if (GetRegisterInfo(reg_kind, reg_num, reg_info))
{
@@ -155,8 +158,7 @@ EmulateInstruction::WriteRegisterUnsigned (const Context &context,
const RegisterInfo *reg_info,
uint64_t uint_value)
{
-
- if (reg_info)
+ if (reg_info != nullptr)
{
RegisterValue reg_value;
if (reg_value.SetUInt(uint_value, reg_info->byte_size))
@@ -171,7 +173,7 @@ EmulateInstruction::ReadMemory (const Context &context,
void *dst,
size_t dst_len)
{
- if (m_read_mem_callback)
+ if (m_read_mem_callback != nullptr)
return m_read_mem_callback (this, m_baton, context, addr, dst, dst_len) == dst_len;
return false;
}
@@ -202,7 +204,6 @@ EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t add
return uval64;
}
-
bool
EmulateInstruction::WriteMemoryUnsigned (const Context &context,
lldb::addr_t addr,
@@ -213,9 +214,7 @@ EmulateInstruction::WriteMemoryUnsigned (const Context &context,
strm.PutMaxHex64 (uval, uval_byte_size);
size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size);
- if (bytes_written == uval_byte_size)
- return true;
- return false;
+ return (bytes_written == uval_byte_size);
}
bool
@@ -224,12 +223,11 @@ EmulateInstruction::WriteMemory (const Context &context,
const void *src,
size_t src_len)
{
- if (m_write_mem_callback)
+ if (m_write_mem_callback != nullptr)
return m_write_mem_callback (this, m_baton, context, addr, src, src_len) == src_len;
return false;
}
-
void
EmulateInstruction::SetBaton (void *baton)
{
@@ -254,29 +252,24 @@ EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback)
m_read_mem_callback = read_mem_callback;
}
-
void
EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback)
{
m_write_mem_callback = write_mem_callback;
}
-
void
EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback)
{
m_read_reg_callback = read_reg_callback;
}
-
void
EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback)
{
m_write_reg_callback = write_reg_callback;
}
-
-
//
// Read & Write Memory and Registers callback functions.
//
@@ -289,7 +282,7 @@ EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
void *dst,
size_t dst_len)
{
- if (!baton || dst == NULL || dst_len == 0)
+ if (baton == nullptr || dst == nullptr || dst_len == 0)
return 0;
StackFrame *frame = (StackFrame *) baton;
@@ -311,7 +304,7 @@ EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
const void *src,
size_t src_len)
{
- if (!baton || src == NULL || src_len == 0)
+ if (baton == nullptr || src == nullptr || src_len == 0)
return 0;
StackFrame *frame = (StackFrame *) baton;
@@ -332,7 +325,7 @@ EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction,
const RegisterInfo *reg_info,
RegisterValue &reg_value)
{
- if (!baton)
+ if (baton == nullptr)
return false;
StackFrame *frame = (StackFrame *) baton;
@@ -346,7 +339,7 @@ EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
const RegisterInfo *reg_info,
const RegisterValue &reg_value)
{
- if (!baton)
+ if (baton == nullptr)
return false;
StackFrame *frame = (StackFrame *) baton;
@@ -504,45 +497,35 @@ EmulateInstruction::Context::Dump (Stream &strm,
switch (info_type)
{
case eInfoTypeRegisterPlusOffset:
- {
- strm.Printf (" (reg_plus_offset = %s%+" PRId64 ")",
- info.RegisterPlusOffset.reg.name,
- info.RegisterPlusOffset.signed_offset);
- }
+ strm.Printf(" (reg_plus_offset = %s%+" PRId64 ")",
+ info.RegisterPlusOffset.reg.name,
+ info.RegisterPlusOffset.signed_offset);
break;
case eInfoTypeRegisterPlusIndirectOffset:
- {
- strm.Printf (" (reg_plus_reg = %s + %s)",
- info.RegisterPlusIndirectOffset.base_reg.name,
- info.RegisterPlusIndirectOffset.offset_reg.name);
- }
+ strm.Printf(" (reg_plus_reg = %s + %s)",
+ info.RegisterPlusIndirectOffset.base_reg.name,
+ info.RegisterPlusIndirectOffset.offset_reg.name);
break;
case eInfoTypeRegisterToRegisterPlusOffset:
- {
- strm.Printf (" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
- info.RegisterToRegisterPlusOffset.base_reg.name,
- info.RegisterToRegisterPlusOffset.offset,
- info.RegisterToRegisterPlusOffset.data_reg.name);
- }
+ strm.Printf(" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
+ info.RegisterToRegisterPlusOffset.base_reg.name,
+ info.RegisterToRegisterPlusOffset.offset,
+ info.RegisterToRegisterPlusOffset.data_reg.name);
break;
case eInfoTypeRegisterToRegisterPlusIndirectOffset:
- {
- strm.Printf (" (base_and_reg_offset = %s + %s, data_reg = %s)",
- info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
- info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
- info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
- }
+ strm.Printf(" (base_and_reg_offset = %s + %s, data_reg = %s)",
+ info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
+ info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
+ info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
break;
case eInfoTypeRegisterRegisterOperands:
- {
- strm.Printf (" (register to register binary op: %s and %s)",
- info.RegisterRegisterOperands.operand1.name,
- info.RegisterRegisterOperands.operand2.name);
- }
+ strm.Printf(" (register to register binary op: %s and %s)",
+ info.RegisterRegisterOperands.operand1.name,
+ info.RegisterRegisterOperands.operand2.name);
break;
case eInfoTypeOffset:
@@ -599,7 +582,7 @@ EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_ad
m_addr = LLDB_INVALID_ADDRESS;
if (inst_addr.IsValid())
{
- if (target)
+ if (target != nullptr)
m_addr = inst_addr.GetLoadAddress (target);
if (m_addr == LLDB_INVALID_ADDRESS)
m_addr = inst_addr.GetFileAddress ();
@@ -661,12 +644,9 @@ EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const R
return LLDB_INVALID_REGNUM;
}
-
bool
EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
{
unwind_plan.Clear();
return false;
}
-
-
diff --git a/source/Core/Error.cpp b/source/Core/Error.cpp
index ce055826af2c..97c2c4cc5b67 100644
--- a/source/Core/Error.cpp
+++ b/source/Core/Error.cpp
@@ -13,13 +13,15 @@
#endif
// C++ Includes
+#include <cerrno>
+#include <cstdarg>
+
// Other libraries and framework includes
+#include "llvm/ADT/SmallVector.h"
+
// Project includes
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
-#include "llvm/ADT/SmallVector.h"
-#include <cerrno>
-#include <cstdarg>
using namespace lldb;
using namespace lldb_private;
@@ -31,9 +33,6 @@ Error::Error ():
{
}
-//----------------------------------------------------------------------
-// Default constructor
-//----------------------------------------------------------------------
Error::Error(ValueType err, ErrorType type) :
m_code (err),
m_type (type),
@@ -41,12 +40,7 @@ Error::Error(ValueType err, ErrorType type) :
{
}
-Error::Error (const Error &rhs) :
- m_code (rhs.m_code),
- m_type (rhs.m_type),
- m_string (rhs.m_string)
-{
-}
+Error::Error(const Error &rhs) = default;
Error::Error (const char* format, ...):
m_code (0),
@@ -75,7 +69,6 @@ Error::operator = (const Error& rhs)
return *this;
}
-
//----------------------------------------------------------------------
// Assignment operator
//----------------------------------------------------------------------
@@ -88,9 +81,7 @@ Error::operator = (uint32_t err)
return *this;
}
-Error::~Error()
-{
-}
+Error::~Error() = default;
//----------------------------------------------------------------------
// Get the error value as a NULL C string. The error string will be
@@ -101,11 +92,11 @@ const char *
Error::AsCString(const char *default_error_str) const
{
if (Success())
- return NULL;
+ return nullptr;
if (m_string.empty())
{
- const char *s = NULL;
+ const char *s = nullptr;
switch (m_type)
{
case eErrorTypeMachKernel:
@@ -121,7 +112,7 @@ Error::AsCString(const char *default_error_str) const
default:
break;
}
- if (s)
+ if (s != nullptr)
m_string.assign(s);
}
if (m_string.empty())
@@ -129,12 +120,11 @@ Error::AsCString(const char *default_error_str) const
if (default_error_str)
m_string.assign(default_error_str);
else
- return NULL; // User wanted a NULL string back...
+ return nullptr; // User wanted a nullptr string back...
}
return m_string.c_str();
}
-
//----------------------------------------------------------------------
// Clear the error and any cached error string that it might contain.
//----------------------------------------------------------------------
@@ -186,27 +176,27 @@ Error::Fail () const
void
Error::PutToLog (Log *log, const char *format, ...)
{
- char *arg_msg = NULL;
+ char *arg_msg = nullptr;
va_list args;
va_start (args, format);
::vasprintf (&arg_msg, format, args);
va_end (args);
- if (arg_msg != NULL)
+ if (arg_msg != nullptr)
{
if (Fail())
{
const char *err_str = AsCString();
- if (err_str == NULL)
+ if (err_str == nullptr)
err_str = "???";
SetErrorStringWithFormat("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_code);
- if (log)
+ if (log != nullptr)
log->Error("%s", m_string.c_str());
}
else
{
- if (log)
+ if (log != nullptr)
log->Printf("%s err = 0x%8.8x", arg_msg, m_code);
}
::free (arg_msg);
@@ -227,20 +217,20 @@ Error::LogIfError (Log *log, const char *format, ...)
{
if (Fail())
{
- char *arg_msg = NULL;
+ char *arg_msg = nullptr;
va_list args;
va_start (args, format);
::vasprintf (&arg_msg, format, args);
va_end (args);
- if (arg_msg != NULL)
+ if (arg_msg != nullptr)
{
const char *err_str = AsCString();
- if (err_str == NULL)
+ if (err_str == nullptr)
err_str = "???";
SetErrorStringWithFormat("%s err = %s (0x%8.8x)", arg_msg, err_str, m_code);
- if (log)
+ if (log != nullptr)
log->Error("%s", m_string.c_str());
::free (arg_msg);
@@ -273,7 +263,7 @@ Error::SetExpressionErrorWithFormat (lldb::ExpressionResults result, const char
{
int length = 0;
- if (format && format[0])
+ if (format != nullptr && format[0])
{
va_list args;
va_start (args, format);
@@ -333,7 +323,7 @@ Error::SetErrorToGenericError ()
void
Error::SetErrorString (const char *err_str)
{
- if (err_str && err_str[0])
+ if (err_str != nullptr && err_str[0])
{
// If we have an error string, we should always at least have
// an error set to a generic value.
@@ -354,7 +344,7 @@ Error::SetErrorString (const char *err_str)
int
Error::SetErrorStringWithFormat (const char *format, ...)
{
- if (format && format[0])
+ if (format != nullptr && format[0])
{
va_list args;
va_start (args, format);
@@ -372,7 +362,7 @@ Error::SetErrorStringWithFormat (const char *format, ...)
int
Error::SetErrorStringWithVarArg (const char *format, va_list args)
{
- if (format && format[0])
+ if (format != nullptr && format[0])
{
// If we have an error string, we should always at least have
// an error set to a generic value.
@@ -407,7 +397,6 @@ Error::SetErrorStringWithVarArg (const char *format, va_list args)
return 0;
}
-
//----------------------------------------------------------------------
// Returns true if the error code in this object is considered a
// successful return value.
@@ -421,9 +410,5 @@ Error::Success() const
bool
Error::WasInterrupted() const
{
- if (m_type == eErrorTypePOSIX && m_code == EINTR)
- return true;
- else
- return false;
+ return (m_type == eErrorTypePOSIX && m_code == EINTR);
}
-
diff --git a/source/Core/Event.cpp b/source/Core/Event.cpp
index 293a322257ef..6b07e4d91987 100644
--- a/source/Core/Event.cpp
+++ b/source/Core/Event.cpp
@@ -9,6 +9,8 @@
// C Includes
// C++ Includes
+#include <algorithm>
+
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Event.h"
@@ -19,82 +21,89 @@
#include "lldb/Core/Stream.h"
#include "lldb/Host/Endian.h"
#include "lldb/Target/Process.h"
-#include <algorithm>
using namespace lldb;
using namespace lldb_private;
-//----------------------------------------------------------------------
-// Event constructor
-//----------------------------------------------------------------------
Event::Event (Broadcaster *broadcaster, uint32_t event_type, EventData *data) :
- m_broadcaster (broadcaster),
- m_type (event_type),
- m_data_ap (data)
+ m_broadcaster_wp(broadcaster->GetBroadcasterImpl()),
+ m_type(event_type),
+ m_data_sp(data)
{
}
-Event::Event(uint32_t event_type, EventData *data) :
- m_broadcaster (NULL), // Set by the broadcaster when this event gets broadcast
- m_type (event_type),
- m_data_ap (data)
+Event::Event (Broadcaster *broadcaster, uint32_t event_type, const EventDataSP &event_data_sp) :
+ m_broadcaster_wp(broadcaster->GetBroadcasterImpl()),
+ m_type(event_type),
+ m_data_sp(event_data_sp)
{
}
+Event::Event(uint32_t event_type, EventData *data) :
+ m_broadcaster_wp(),
+ m_type(event_type),
+ m_data_sp(data)
+{
+}
-//----------------------------------------------------------------------
-// Event destructor
-//----------------------------------------------------------------------
-Event::~Event ()
+Event::Event(uint32_t event_type, const EventDataSP &event_data_sp) :
+ m_broadcaster_wp(),
+ m_type(event_type),
+ m_data_sp(event_data_sp)
{
}
+Event::~Event() = default;
+
void
Event::Dump (Stream *s) const
{
- if (m_broadcaster)
+ Broadcaster *broadcaster;
+ Broadcaster::BroadcasterImplSP broadcaster_impl_sp(m_broadcaster_wp.lock());
+ if (broadcaster_impl_sp)
+ broadcaster = broadcaster_impl_sp->GetBroadcaster();
+ else
+ broadcaster = nullptr;
+
+ if (broadcaster)
{
StreamString event_name;
- if (m_broadcaster->GetEventNames (event_name, m_type, false))
+ if (broadcaster->GetEventNames (event_name, m_type, false))
s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x (%s), data = ",
static_cast<const void*>(this),
- static_cast<void*>(m_broadcaster),
- m_broadcaster->GetBroadcasterName().GetCString(),
+ static_cast<void*>(broadcaster),
+ broadcaster->GetBroadcasterName().GetCString(),
m_type, event_name.GetString().c_str());
else
s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x, data = ",
static_cast<const void*>(this),
- static_cast<void*>(m_broadcaster),
- m_broadcaster->GetBroadcasterName().GetCString(), m_type);
+ static_cast<void*>(broadcaster),
+ broadcaster->GetBroadcasterName().GetCString(), m_type);
}
else
s->Printf("%p Event: broadcaster = NULL, type = 0x%8.8x, data = ",
static_cast<const void*>(this), m_type);
- if (m_data_ap.get() == NULL)
- s->Printf ("<NULL>");
- else
+ if (m_data_sp)
{
s->PutChar('{');
- m_data_ap->Dump (s);
+ m_data_sp->Dump (s);
s->PutChar('}');
}
+ else
+ s->Printf ("<NULL>");
}
void
Event::DoOnRemoval ()
{
- if (m_data_ap.get())
- m_data_ap->DoOnRemoval (this);
+ if (m_data_sp)
+ m_data_sp->DoOnRemoval (this);
}
-EventData::EventData()
-{
-}
+EventData::EventData() = default;
-EventData::~EventData()
-{
-}
+EventData::~EventData() = default;
void
EventData::Dump (Stream *s) const
@@ -119,9 +128,7 @@ EventDataBytes::EventDataBytes (const void *src, size_t src_len) :
SetBytes (src, src_len);
}
-EventDataBytes::~EventDataBytes()
-{
-}
+EventDataBytes::~EventDataBytes() = default;
const ConstString &
EventDataBytes::GetFlavorString ()
@@ -144,10 +151,10 @@ EventDataBytes::Dump (Stream *s) const
{
s->Printf("\"%s\"", m_bytes.c_str());
}
- else if (m_bytes.size() > 0)
+ else if (!m_bytes.empty())
{
DataExtractor data;
- data.SetData(&m_bytes[0], m_bytes.size(), endian::InlHostByteOrder());
+ data.SetData(m_bytes.data(), m_bytes.size(), endian::InlHostByteOrder());
data.Dump(s, 0, eFormatBytes, 1, m_bytes.size(), 32, LLDB_INVALID_ADDRESS, 0, 0);
}
}
@@ -155,9 +162,7 @@ EventDataBytes::Dump (Stream *s) const
const void *
EventDataBytes::GetBytes() const
{
- if (m_bytes.empty())
- return NULL;
- return &m_bytes[0];
+ return (m_bytes.empty() ? nullptr : m_bytes.data());
}
size_t
@@ -169,7 +174,7 @@ EventDataBytes::GetByteSize() const
void
EventDataBytes::SetBytes (const void *src, size_t src_len)
{
- if (src && src_len > 0)
+ if (src != nullptr && src_len > 0)
m_bytes.assign ((const char *)src, src_len);
else
m_bytes.clear();
@@ -178,27 +183,26 @@ EventDataBytes::SetBytes (const void *src, size_t src_len)
void
EventDataBytes::SetBytesFromCString (const char *cstr)
{
- if (cstr && cstr[0])
+ if (cstr != nullptr && cstr[0])
m_bytes.assign (cstr);
else
m_bytes.clear();
}
-
const void *
EventDataBytes::GetBytesFromEvent (const Event *event_ptr)
{
const EventDataBytes *e = GetEventDataFromEvent (event_ptr);
- if (e)
+ if (e != nullptr)
return e->GetBytes();
- return NULL;
+ return nullptr;
}
size_t
EventDataBytes::GetByteSizeFromEvent (const Event *event_ptr)
{
const EventDataBytes *e = GetEventDataFromEvent (event_ptr);
- if (e)
+ if (e != nullptr)
return e->GetByteSize();
return 0;
}
@@ -206,13 +210,13 @@ EventDataBytes::GetByteSizeFromEvent (const Event *event_ptr)
const EventDataBytes *
EventDataBytes::GetEventDataFromEvent (const Event *event_ptr)
{
- if (event_ptr)
+ if (event_ptr != nullptr)
{
const EventData *event_data = event_ptr->GetData();
if (event_data && event_data->GetFlavor() == EventDataBytes::GetFlavorString())
return static_cast <const EventDataBytes *> (event_data);
}
- return NULL;
+ return nullptr;
}
void
@@ -220,5 +224,3 @@ EventDataBytes::SwapBytes (std::string &new_bytes)
{
m_bytes.swap (new_bytes);
}
-
-
diff --git a/source/Core/FastDemangle.cpp b/source/Core/FastDemangle.cpp
index a27a2f1dbff1..528f7f6bd88d 100644
--- a/source/Core/FastDemangle.cpp
+++ b/source/Core/FastDemangle.cpp
@@ -11,6 +11,8 @@
#include <string.h>
#include <stdlib.h>
+#include "lldb/lldb-private.h"
+
//#define DEBUG_FAILURES 1
//#define DEBUG_SUBSTITUTIONS 1
//#define DEBUG_TEMPLATE_ARGS 1
@@ -1627,7 +1629,7 @@ private:
return Parse('E');
}
--m_read_ptr;
- // fallthrough
+ LLVM_FALLTHROUGH;
case 'w':
case 'c':
case 'a':
@@ -1827,7 +1829,7 @@ private:
if (*m_read_ptr++ == 'r')
return ParseUnresolvedName();
--m_read_ptr;
- // fallthrough
+ LLVM_FALLTHROUGH;
default:
return ParseExpressionPrimary();
}
@@ -2099,7 +2101,7 @@ private:
}
case 'L':
++m_read_ptr;
- // fallthrough
+ LLVM_FALLTHROUGH;
default:
{
if (!ParseUnscopedName(name_state))
@@ -2293,7 +2295,7 @@ private:
m_read_ptr += strlen(m_read_ptr);
break;
}
- // fallthrough
+ LLVM_FALLTHROUGH;
default:
if (first_param)
first_param = false;
@@ -2363,6 +2365,7 @@ private:
Write('(');
Write(m_read_ptr, m_read_end - m_read_ptr);
Write(')');
+ LLVM_FALLTHROUGH;
case '\0':
return true;
default:
diff --git a/source/Core/FileSpecList.cpp b/source/Core/FileSpecList.cpp
index 4b1c991c6be4..cef1bfba41b0 100644
--- a/source/Core/FileSpecList.cpp
+++ b/source/Core/FileSpecList.cpp
@@ -6,35 +6,28 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#include "lldb/Core/FileSpecList.h"
-#include "lldb/Core/Stream.h"
+
+// C Includes
+// C++ Includes
#include <algorithm>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Stream.h"
+
using namespace lldb_private;
using namespace std;
-//------------------------------------------------------------------
-// Default constructor
-//------------------------------------------------------------------
FileSpecList::FileSpecList() :
m_files()
{
}
-//------------------------------------------------------------------
-// Copy constructor
-//------------------------------------------------------------------
-FileSpecList::FileSpecList(const FileSpecList& rhs) :
- m_files(rhs.m_files)
-{
-}
+FileSpecList::FileSpecList(const FileSpecList& rhs) = default;
-//------------------------------------------------------------------
-// Destructor
-//------------------------------------------------------------------
-FileSpecList::~FileSpecList()
-{
-}
+FileSpecList::~FileSpecList() = default;
//------------------------------------------------------------------
// Assignment operator
@@ -104,7 +97,7 @@ FileSpecList::Dump(Stream *s, const char *separator_cstr) const
// "file_spec" starting "start_idx" entries into the file spec list.
//
// Returns the valid index of the file that matches "file_spec" if
-// it is found, else UINT32_MAX is returned.
+// it is found, else std::numeric_limits<uint32_t>::max() is returned.
//------------------------------------------------------------------
size_t
FileSpecList::FindFileIndex (size_t start_idx, const FileSpec &file_spec, bool full, bool remove_dots) const
@@ -119,7 +112,8 @@ FileSpecList::FindFileIndex (size_t start_idx, const FileSpec &file_spec, bool f
{
if (compare_filename_only)
{
- if (m_files[idx].GetFilename() == file_spec.GetFilename())
+ if (ConstString::Equals(m_files[idx].GetFilename(), file_spec.GetFilename(),
+ file_spec.IsCaseSensitive() || m_files[idx].IsCaseSensitive()))
return idx;
}
else
@@ -140,7 +134,6 @@ FileSpecList::FindFileIndex (size_t start_idx, const FileSpec &file_spec, bool f
const FileSpec &
FileSpecList::GetFileSpecAtIndex(size_t idx) const
{
-
if (idx < m_files.size())
return m_files[idx];
static FileSpec g_empty_file_spec;
@@ -152,7 +145,7 @@ FileSpecList::GetFileSpecPointerAtIndex(size_t idx) const
{
if (idx < m_files.size())
return &m_files[idx];
- return NULL;
+ return nullptr;
}
//------------------------------------------------------------------
@@ -207,26 +200,23 @@ FileSpecList::GetFilesMatchingPartialPath (const char *path, bool dir_okay, File
else if (type == FileSpec::eFileTypeDirectory)
{
// Fill the match list with all the files in the directory:
-
}
else
{
return 0;
}
-
}
else
{
ConstString dir_name = path_spec.GetDirectory();
- Constring file_name = GetFilename();
- if (dir_name == NULL)
+ ConstString file_name = GetFilename();
+ if (dir_name == nullptr)
{
// Match files in the CWD.
}
else
{
// Match files in the given directory:
-
}
}
#endif
diff --git a/source/Core/FormatEntity.cpp b/source/Core/FormatEntity.cpp
index 804682f64bd3..e2097cc72b85 100644
--- a/source/Core/FormatEntity.cpp
+++ b/source/Core/FormatEntity.cpp
@@ -9,9 +9,13 @@
#include "lldb/Core/FormatEntity.h"
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+// Project includes
#include "lldb/Core/Address.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -45,7 +49,6 @@
using namespace lldb;
using namespace lldb_private;
-
enum FileKind
{
FileError = 0,
@@ -54,11 +57,11 @@ enum FileKind
Fullpath
};
-#define ENTRY(n,t,f) { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0,0,NULL, false}
-#define ENTRY_VALUE(n,t,f,v) { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, v,0,NULL, false}
-#define ENTRY_CHILDREN(n,t,f,c) { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0,llvm::array_lengthof(c),c, false}
-#define ENTRY_CHILDREN_KEEP_SEP(n,t,f,c) { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0,llvm::array_lengthof(c),c, true}
-#define ENTRY_STRING(n,s) { n, s, FormatEntity::Entry::Type::InsertString, FormatEntity::Entry::FormatType::None, 0,0, NULL, false}
+#define ENTRY(n,t,f) { n, nullptr, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0, 0, nullptr, false}
+#define ENTRY_VALUE(n,t,f,v) { n, nullptr, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, v, 0, nullptr, false}
+#define ENTRY_CHILDREN(n,t,f,c) { n, nullptr, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0, llvm::array_lengthof(c), c, false}
+#define ENTRY_CHILDREN_KEEP_SEP(n,t,f,c) { n, nullptr, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0, llvm::array_lengthof(c), c, true}
+#define ENTRY_STRING(n,s) { n, s, FormatEntity::Entry::Type::InsertString, FormatEntity::Entry::FormatType::None, 0, 0, nullptr, false}
static FormatEntity::Entry::Definition g_string_entry[] =
{
ENTRY("*", ParentString, None)
@@ -80,7 +83,6 @@ static FormatEntity::Entry::Definition g_file_child_entries[] =
static FormatEntity::Entry::Definition g_frame_child_entries[] =
{
-
ENTRY ("index", FrameIndex , UInt32),
ENTRY ("pc" , FrameRegisterPC , UInt64),
ENTRY ("fp" , FrameRegisterFP , UInt64),
@@ -193,7 +195,6 @@ static FormatEntity::Entry::Definition g_ansi_entries[] =
ENTRY_STRING ( "negative" , ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END),
ENTRY_STRING ( "conceal" , ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END),
ENTRY_STRING ( "crossed-out" , ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END),
-
};
static FormatEntity::Entry::Definition g_script_child_entries[] =
@@ -229,12 +230,11 @@ static FormatEntity::Entry::Definition g_top_level_entries[] =
static FormatEntity::Entry::Definition g_root = ENTRY_CHILDREN ("<root>", Root, None, g_top_level_entries);
-
FormatEntity::Entry::Entry (llvm::StringRef s) :
string (s.data(), s.size()),
printf_format (),
children (),
- definition (NULL),
+ definition(nullptr),
type (Type::String),
fmt (lldb::eFormatDefault),
number (0),
@@ -246,7 +246,7 @@ FormatEntity::Entry::Entry (char ch) :
string (1, ch),
printf_format (),
children (),
- definition (NULL),
+ definition(nullptr),
type (Type::String),
fmt (lldb::eFormatDefault),
number (0),
@@ -278,7 +278,6 @@ FormatEntity::Entry::AppendText (const char *cstr)
return AppendText (llvm::StringRef(cstr));
}
-
Error
FormatEntity::Parse (const llvm::StringRef &format_str, Entry &entry)
{
@@ -379,7 +378,6 @@ FormatEntity::Entry::Dump (Stream &s, int depth) const
}
}
-
template <typename T>
static bool RunScriptFormatKeyword(Stream &s,
const SymbolContext *sc,
@@ -436,7 +434,7 @@ DumpAddress (Stream &s,
addr_width = 16;
if (print_file_addr_or_load_addr)
{
- ExecutionContextScope *exe_scope = NULL;
+ ExecutionContextScope *exe_scope = nullptr;
if (exe_ctx)
exe_scope = exe_ctx->GetBestExecutionContextScope();
addr.Dump (&s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
@@ -569,7 +567,7 @@ ScanBracketedRange (llvm::StringRef subpath,
if (separator_index == llvm::StringRef::npos)
{
const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
- index_lower = ::strtoul (index_lower_cstr, NULL, 0);
+ index_lower = ::strtoul(index_lower_cstr, nullptr, 0);
index_higher = index_lower;
if (log)
log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", index_lower);
@@ -578,8 +576,8 @@ ScanBracketedRange (llvm::StringRef subpath,
{
const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
const char *index_higher_cstr = subpath.data() + separator_index + 1;
- index_lower = ::strtoul (index_lower_cstr, NULL, 0);
- index_higher = ::strtoul (index_higher_cstr, NULL, 0);
+ index_lower = ::strtoul(index_lower_cstr, nullptr, 0);
+ index_higher = ::strtoul(index_higher_cstr, nullptr, 0);
if (log)
log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", index_lower, index_higher);
}
@@ -664,7 +662,6 @@ DumpRegister (Stream &s,
return false;
}
-
static ValueObjectSP
ExpandIndexedExpression (ValueObject* valobj,
size_t index,
@@ -729,7 +726,7 @@ DumpValue (Stream &s,
const FormatEntity::Entry &entry,
ValueObject *valobj)
{
- if (valobj == NULL)
+ if (valobj == nullptr)
return false;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
@@ -751,7 +748,7 @@ DumpValue (Stream &s,
case FormatEntity::Entry::Type::ScriptVariableSynthetic:
is_script = true;
- // Fall through
+ LLVM_FALLTHROUGH;
case FormatEntity::Entry::Type::VariableSynthetic:
custom_format = entry.fmt;
val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
@@ -767,15 +764,15 @@ DumpValue (Stream &s,
return false;
}
- if (valobj == NULL)
+ if (valobj == nullptr)
return false;
ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
ValueObject::GetValueForExpressionPathOptions options;
options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().SetSyntheticChildrenTraversal(ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal::Both);
- ValueObject* target = NULL;
- const char* var_name_final_if_array_range = NULL;
+ ValueObject* target = nullptr;
+ const char* var_name_final_if_array_range = nullptr;
size_t close_bracket_index = llvm::StringRef::npos;
int64_t index_lower = -1;
int64_t index_higher = -1;
@@ -844,7 +841,6 @@ DumpValue (Stream &s,
}
}
-
is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
@@ -887,7 +883,7 @@ DumpValue (Stream &s,
}
// TODO use flags for these
- const uint32_t type_info_flags = target->GetCompilerType().GetTypeInfo(NULL);
+ const uint32_t type_info_flags = target->GetCompilerType().GetTypeInfo(nullptr);
bool is_array = (type_info_flags & eTypeIsArray) != 0;
bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
bool is_aggregate = target->GetCompilerType().IsAggregateType();
@@ -1021,7 +1017,7 @@ DumpValue (Stream &s,
}
else
{
- success &= FormatEntity::FormatStringRef(special_directions, s, sc, exe_ctx, NULL, item, false, false);
+ success &= FormatEntity::FormatStringRef(special_directions, s, sc, exe_ctx, nullptr, item, false, false);
}
if (--max_num_children == 0)
@@ -1036,7 +1032,6 @@ DumpValue (Stream &s,
s.PutChar(']');
return success;
}
-
}
static bool
@@ -1044,7 +1039,6 @@ DumpRegister (Stream &s,
StackFrame *frame,
const char *reg_name,
Format format)
-
{
if (frame)
{
@@ -1078,7 +1072,7 @@ FormatThreadExtendedInfoRecurse(const FormatEntity::Entry &entry,
StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);
- if (value.get())
+ if (value)
{
if (value->GetType() == StructuredData::Type::eTypeInteger)
{
@@ -1116,7 +1110,6 @@ FormatThreadExtendedInfoRecurse(const FormatEntity::Entry &entry,
return false;
}
-
static inline bool
IsToken(const char *var_name_begin, const char *var)
{
@@ -1150,8 +1143,8 @@ FormatEntity::FormatStringRef (const llvm::StringRef &format_str,
}
}
return false;
-
}
+
bool
FormatEntity::FormatCString (const char *format,
Stream &s,
@@ -1203,14 +1196,14 @@ FormatEntity::Format (const Entry &entry,
case Entry::Type::Root:
for (const auto &child : entry.children)
{
- if (Format (child,
+ if (!Format(child,
s,
sc,
exe_ctx,
addr,
valobj,
function_changed,
- initial_function) == false)
+ initial_function))
{
return false; // If any item of root fails, then the formatting fails
}
@@ -1242,16 +1235,13 @@ FormatEntity::Format (const Entry &entry,
case Entry::Type::VariableSynthetic:
case Entry::Type::ScriptVariable:
case Entry::Type::ScriptVariableSynthetic:
- if (DumpValue(s, sc, exe_ctx, entry, valobj))
- return true;
- return false;
+ return DumpValue(s, sc, exe_ctx, entry, valobj);
case Entry::Type::AddressFile:
case Entry::Type::AddressLoad:
case Entry::Type::AddressLoadOrFile:
- if (addr && addr->IsValid() && DumpAddress(s, sc, exe_ctx, *addr, entry.type == Entry::Type::AddressLoadOrFile))
- return true;
- return false;
+ return (addr != nullptr && addr->IsValid() &&
+ DumpAddress(s, sc, exe_ctx, *addr, entry.type == Entry::Type::AddressLoadOrFile));
case Entry::Type::ProcessID:
if (exe_ctx)
@@ -1293,7 +1283,6 @@ FormatEntity::Format (const Entry &entry,
}
return false;
-
case Entry::Type::ThreadID:
if (exe_ctx)
{
@@ -1607,7 +1596,6 @@ FormatEntity::Format (const Entry &entry,
}
return false;
-
case Entry::Type::FrameRegisterByName:
if (exe_ctx)
{
@@ -1674,11 +1662,11 @@ FormatEntity::Format (const Entry &entry,
}
else
{
- const char *name = NULL;
+ const char *name = nullptr;
if (sc->function)
- name = sc->function->GetName().AsCString (NULL);
+ name = sc->function->GetName().AsCString(nullptr);
else if (sc->symbol)
- name = sc->symbol->GetName().AsCString (NULL);
+ name = sc->symbol->GetName().AsCString(nullptr);
if (name)
{
s.PutCString(name);
@@ -1765,11 +1753,11 @@ FormatEntity::Format (const Entry &entry,
// Print the function name with arguments in it
if (sc->function)
{
- ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
- const char *cstr = sc->function->GetName().AsCString (NULL);
+ ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
+ const char *cstr = sc->function->GetName().AsCString(nullptr);
if (cstr)
{
- const InlineFunctionInfo *inline_info = NULL;
+ const InlineFunctionInfo *inline_info = nullptr;
VariableListSP variable_list_sp;
bool get_function_vars = true;
if (sc->block)
@@ -1861,7 +1849,7 @@ FormatEntity::Format (const Entry &entry,
var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(exe_scope->CalculateTarget()->TargetProperties::GetPreferDynamicValue(),
exe_scope->CalculateTarget()->TargetProperties::GetEnableSyntheticValue());
if (var_value_sp->GetCompilerType().IsAggregateType() &&
- DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
+ DataVisualization::ShouldPrintAsOneLiner(*var_value_sp))
{
static StringSummaryFormat format(TypeSummaryImpl::Flags()
.SetHideItemNames(false)
@@ -1908,7 +1896,7 @@ FormatEntity::Format (const Entry &entry,
}
else if (sc->symbol)
{
- const char *cstr = sc->symbol->GetName().AsCString (NULL);
+ const char *cstr = sc->symbol->GetName().AsCString(nullptr);
if (cstr)
{
s.PutCString(cstr);
@@ -1936,9 +1924,7 @@ FormatEntity::Format (const Entry &entry,
return false;
case Entry::Type::FunctionLineOffset:
- if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, sc->line_entry.range.GetBaseAddress(), false, false, false))
- return true;
- return false;
+ return (DumpAddressOffsetFromFunction (s, sc, exe_ctx, sc->line_entry.range.GetBaseAddress(), false, false, false));
case Entry::Type::FunctionPCOffset:
if (exe_ctx)
@@ -1953,7 +1939,7 @@ FormatEntity::Format (const Entry &entry,
return false;
case Entry::Type::FunctionChanged:
- return function_changed == true;
+ return function_changed;
case Entry::Type::FunctionIsOptimized:
{
@@ -1966,7 +1952,7 @@ FormatEntity::Format (const Entry &entry,
}
case Entry::Type::FunctionInitial:
- return initial_function == true;
+ return initial_function;
case Entry::Type::LineEntryFile:
if (sc && sc->line_entry.IsValid())
@@ -2008,7 +1994,7 @@ FormatEntity::Format (const Entry &entry,
if (addr && exe_ctx && exe_ctx->GetFramePtr())
{
RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP();
- if (reg_ctx.get())
+ if (reg_ctx)
{
addr_t pc_loadaddr = reg_ctx->GetPC();
if (pc_loadaddr != LLDB_INVALID_ADDRESS)
@@ -2036,7 +2022,7 @@ DumpCommaSeparatedChildEntryNames (Stream &s, const FormatEntity::Entry::Definit
if (parent->children)
{
const size_t n = parent->num_children;
- for (size_t i=0; i<n; ++i)
+ for (size_t i = 0; i < n; ++i)
{
if (i > 0)
s.PutCString(", ");
@@ -2047,7 +2033,6 @@ DumpCommaSeparatedChildEntryNames (Stream &s, const FormatEntity::Entry::Definit
return false;
}
-
static Error
ParseEntry (const llvm::StringRef &format_str,
const FormatEntity::Entry::Definition *parent,
@@ -2060,7 +2045,7 @@ ParseEntry (const llvm::StringRef &format_str,
llvm::StringRef key = format_str.substr(0, sep_pos);
const size_t n = parent->num_children;
- for (size_t i=0; i<n; ++i)
+ for (size_t i = 0; i < n; ++i)
{
const FormatEntity::Entry::Definition *entry_def = parent->children + i;
if (key.equals(entry_def->name) || entry_def->name[0] == '*')
@@ -2143,7 +2128,6 @@ ParseEntry (const llvm::StringRef &format_str,
return error;
}
-
static const FormatEntity::Entry::Definition *
FindEntry (const llvm::StringRef &format_str, const FormatEntity::Entry::Definition *parent, llvm::StringRef &remainder)
{
@@ -2151,7 +2135,7 @@ FindEntry (const llvm::StringRef &format_str, const FormatEntity::Entry::Definit
std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split('.');
const size_t n = parent->num_children;
- for (size_t i=0; i<n; ++i)
+ for (size_t i = 0; i < n; ++i)
{
const FormatEntity::Entry::Definition *entry_def = parent->children + i;
if (p.first.equals(entry_def->name) || entry_def->name[0] == '*')
@@ -2257,14 +2241,14 @@ FormatEntity::ParseInternal (llvm::StringRef &format, Entry &parent_entry, uint3
char oct_str[5] = { 0, 0, 0, 0, 0 };
int i;
- for (i=0; (format[i] >= '0' && format[i] <= '7') && i<4; ++i)
+ for (i = 0; (format[i] >= '0' && format[i] <= '7') && i < 4; ++i)
oct_str[i] = format[i];
// We don't want to consume the last octal character since
// the main for loop will do this for us, so we advance p by
// one less than i (even if i is zero)
format = format.drop_front(i);
- unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
+ unsigned long octal_value = ::strtoul(oct_str, nullptr, 8);
if (octal_value <= UINT8_MAX)
{
parent_entry.AppendChar((char)octal_value);
@@ -2294,7 +2278,7 @@ FormatEntity::ParseInternal (llvm::StringRef &format, Entry &parent_entry, uint3
format = format.drop_front();
}
- unsigned long hex_value = strtoul (hex_str, NULL, 16);
+ unsigned long hex_value = strtoul(hex_str, nullptr, 16);
if (hex_value <= UINT8_MAX)
{
parent_entry.AppendChar((char)hex_value);
@@ -2483,7 +2467,6 @@ FormatEntity::ParseInternal (llvm::StringRef &format, Entry &parent_entry, uint3
return error;
}
-
Error
FormatEntity::ExtractVariableInfo (llvm::StringRef &format_str, llvm::StringRef &variable_name, llvm::StringRef &variable_format)
{
@@ -2556,7 +2539,7 @@ AddMatches (const FormatEntity::Entry::Definition *def,
const size_t n = def->num_children;
if (n > 0)
{
- for (size_t i=0; i<n; ++i)
+ for (size_t i = 0; i < n; ++i)
{
std::string match = prefix.str();
if (match_prefix.empty())
@@ -2566,6 +2549,7 @@ AddMatches (const FormatEntity::Entry::Definition *def,
}
}
}
+
size_t
FormatEntity::AutoComplete (const char *s,
int match_start_point,
diff --git a/source/Core/IOHandler.cpp b/source/Core/IOHandler.cpp
index 47d00e9184cf..bab0263a0c6e 100644
--- a/source/Core/IOHandler.cpp
+++ b/source/Core/IOHandler.cpp
@@ -38,8 +38,18 @@
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/ThreadPlan.h"
+#ifndef LLDB_DISABLE_CURSES
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/StackFrame.h"
+#endif
-
+#ifdef _MSC_VER
+#include <Windows.h>
+#endif
using namespace lldb;
using namespace lldb_private;
@@ -67,7 +77,7 @@ IOHandler::IOHandler (Debugger &debugger,
m_popped (false),
m_flags (flags),
m_type (type),
- m_user_data (NULL),
+ m_user_data(nullptr),
m_done (false),
m_active (false)
{
@@ -83,49 +93,37 @@ IOHandler::~IOHandler() = default;
int
IOHandler::GetInputFD()
{
- if (m_input_sp)
- return m_input_sp->GetFile().GetDescriptor();
- return -1;
+ return (m_input_sp ? m_input_sp->GetFile().GetDescriptor() : -1);
}
int
IOHandler::GetOutputFD()
{
- if (m_output_sp)
- return m_output_sp->GetFile().GetDescriptor();
- return -1;
+ return (m_output_sp ? m_output_sp->GetFile().GetDescriptor() : -1);
}
int
IOHandler::GetErrorFD()
{
- if (m_error_sp)
- return m_error_sp->GetFile().GetDescriptor();
- return -1;
+ return (m_error_sp ? m_error_sp->GetFile().GetDescriptor() : -1);
}
FILE *
IOHandler::GetInputFILE()
{
- if (m_input_sp)
- return m_input_sp->GetFile().GetStream();
- return NULL;
+ return (m_input_sp ? m_input_sp->GetFile().GetStream() : nullptr);
}
FILE *
IOHandler::GetOutputFILE()
{
- if (m_output_sp)
- return m_output_sp->GetFile().GetStream();
- return NULL;
+ return (m_output_sp ? m_output_sp->GetFile().GetStream() : nullptr);
}
FILE *
IOHandler::GetErrorFILE()
{
- if (m_error_sp)
- return m_error_sp->GetFile().GetStream();
- return NULL;
+ return (m_error_sp ? m_error_sp->GetFile().GetStream() : nullptr);
}
StreamFileSP &
@@ -171,13 +169,13 @@ IOHandler::WaitForPop ()
}
void
-IOHandlerStack::PrintAsync (Stream *stream, const char *s, size_t len)
+IOHandlerStack::PrintAsync(Stream *stream, const char *s, size_t len)
{
if (stream)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_top)
- m_top->PrintAsync (stream, s, len);
+ m_top->PrintAsync(stream, s, len);
}
}
@@ -186,9 +184,9 @@ IOHandlerConfirm::IOHandlerConfirm (Debugger &debugger,
bool default_response) :
IOHandlerEditline(debugger,
IOHandler::Type::Confirm,
- NULL, // NULL editline_name means no history loaded/saved
- NULL, // No prompt
- NULL, // No continuation prompt
+ nullptr, // nullptr editline_name means no history loaded/saved
+ nullptr, // No prompt
+ nullptr, // No continuation prompt
false, // Multi-line
false, // Don't colorize the prompt (i.e. the confirm message.)
0,
@@ -204,7 +202,6 @@ IOHandlerConfirm::IOHandlerConfirm (Debugger &debugger,
prompt_stream.Printf(": [y/N] ");
SetPrompt (prompt_stream.GetString().c_str());
-
}
IOHandlerConfirm::~IOHandlerConfirm() = default;
@@ -304,14 +301,14 @@ IOHandlerDelegate::IOHandlerComplete (IOHandler &io_handler,
--word_start;
while (word_start > current_line && !isspace(*word_start))
--word_start;
- CommandCompletions::InvokeCommonCompletionCallbacks (io_handler.GetDebugger().GetCommandInterpreter(),
- CommandCompletions::eVariablePathCompletion,
- word_start,
- skip_first_n_matches,
- max_matches,
- NULL,
- word_complete,
- matches);
+ CommandCompletions::InvokeCommonCompletionCallbacks(io_handler.GetDebugger().GetCommandInterpreter(),
+ CommandCompletions::eVariablePathCompletion,
+ word_start,
+ skip_first_n_matches,
+ max_matches,
+ nullptr,
+ word_complete,
+ matches);
size_t num_matches = matches.GetSize();
if (num_matches > 0)
@@ -382,7 +379,7 @@ IOHandlerEditline::IOHandlerEditline (Debugger &debugger,
m_delegate (delegate),
m_prompt (),
m_continuation_prompt(),
- m_current_lines_ptr (NULL),
+ m_current_lines_ptr(nullptr),
m_base_line_number (line_number_start),
m_curr_line_idx (UINT32_MAX),
m_multi_line (multi_line),
@@ -460,12 +457,12 @@ IOHandlerEditline::GetLine (std::string &line, bool &interrupted)
{
if (GetIsInteractive())
{
- const char *prompt = NULL;
+ const char *prompt = nullptr;
if (m_multi_line && m_curr_line_idx > 0)
prompt = GetContinuationPrompt();
- if (prompt == NULL)
+ if (prompt == nullptr)
prompt = GetPrompt();
if (prompt && prompt[0])
@@ -484,7 +481,7 @@ IOHandlerEditline::GetLine (std::string &line, bool &interrupted)
m_editing = true;
while (!done)
{
- if (fgets(buffer, sizeof(buffer), in) == NULL)
+ if (fgets(buffer, sizeof(buffer), in) == nullptr)
{
const int saved_errno = errno;
if (feof(in))
@@ -532,7 +529,6 @@ IOHandlerEditline::GetLine (std::string &line, bool &interrupted)
#endif
}
-
#ifndef LLDB_DISABLE_LIBEDIT
bool
IOHandlerEditline::IsInputCompleteCallback (Editline *editline,
@@ -587,7 +583,7 @@ IOHandlerEditline::GetPrompt ()
{
#endif
if (m_prompt.empty())
- return NULL;
+ return nullptr;
#ifndef LLDB_DISABLE_LIBEDIT
}
#endif
@@ -603,7 +599,7 @@ IOHandlerEditline::SetPrompt (const char *p)
m_prompt.clear();
#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_ap)
- m_editline_ap->SetPrompt (m_prompt.empty() ? NULL : m_prompt.c_str());
+ m_editline_ap->SetPrompt(m_prompt.empty() ? nullptr : m_prompt.c_str());
#endif
return true;
}
@@ -611,9 +607,7 @@ IOHandlerEditline::SetPrompt (const char *p)
const char *
IOHandlerEditline::GetContinuationPrompt ()
{
- if (m_continuation_prompt.empty())
- return NULL;
- return m_continuation_prompt.c_str();
+ return (m_continuation_prompt.empty() ? nullptr : m_continuation_prompt.c_str());
}
void
@@ -626,7 +620,7 @@ IOHandlerEditline::SetContinuationPrompt (const char *p)
#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_ap)
- m_editline_ap->SetContinuationPrompt (m_continuation_prompt.empty() ? NULL : m_continuation_prompt.c_str());
+ m_editline_ap->SetContinuationPrompt(m_continuation_prompt.empty() ? nullptr : m_continuation_prompt.c_str());
#endif
}
@@ -671,7 +665,7 @@ IOHandlerEditline::GetLines (StringList &lines, bool &interrupted)
{
FILE *out = GetOutputFILE();
if (out)
- ::fprintf(out, "%u%s", m_base_line_number + (uint32_t)lines.GetSize(), GetPrompt() == NULL ? " " : "");
+ ::fprintf(out, "%u%s", m_base_line_number + (uint32_t)lines.GetSize(), GetPrompt() == nullptr ? " " : "");
}
m_curr_line_idx = lines.GetSize();
@@ -783,20 +777,32 @@ IOHandlerEditline::PrintAsync (Stream *stream, const char *s, size_t len)
m_editline_ap->PrintAsync(stream, s, len);
else
#endif
+ {
+ const char *prompt = GetPrompt();
+#ifdef _MSC_VER
+ if (prompt)
+ {
+ // Back up over previous prompt using Windows API
+ CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
+ HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
+ GetConsoleScreenBufferInfo(console_handle, &screen_buffer_info);
+ COORD coord = screen_buffer_info.dwCursorPosition;
+ coord.X -= strlen(prompt);
+ if (coord.X < 0)
+ coord.X = 0;
+ SetConsoleCursorPosition(console_handle, coord);
+ }
+#endif
IOHandler::PrintAsync(stream, s, len);
+ if (prompt)
+ IOHandler::PrintAsync(GetOutputStreamFile().get(), prompt, strlen(prompt));
+ }
}
// we may want curses to be disabled for some builds
// for instance, windows
#ifndef LLDB_DISABLE_CURSES
-#include "lldb/Core/ValueObject.h"
-#include "lldb/Symbol/VariableList.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/StackFrame.h"
-
#define KEY_RETURN 10
#define KEY_ESCAPE 27
@@ -1078,13 +1084,13 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
virtual const char *
WindowDelegateGetHelpText ()
{
- return NULL;
+ return nullptr;
}
virtual KeyHelp *
WindowDelegateGetKeyHelp ()
{
- return NULL;
+ return nullptr;
}
};
@@ -1124,9 +1130,9 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
public:
Window (const char *name) :
m_name (name),
- m_window (NULL),
- m_panel (NULL),
- m_parent (NULL),
+ m_window(nullptr),
+ m_panel(nullptr),
+ m_parent(nullptr),
m_subwindows (),
m_delegate_sp (),
m_curr_active_window_idx (UINT32_MAX),
@@ -1140,9 +1146,9 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
Window (const char *name, WINDOW *w, bool del = true) :
m_name (name),
- m_window (NULL),
- m_panel (NULL),
- m_parent (NULL),
+ m_window(nullptr),
+ m_panel(nullptr),
+ m_parent(nullptr),
m_subwindows (),
m_delegate_sp (),
m_curr_active_window_idx (UINT32_MAX),
@@ -1158,8 +1164,8 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
Window (const char *name, const Rect &bounds) :
m_name (name),
- m_window (NULL),
- m_parent (NULL),
+ m_window(nullptr),
+ m_parent(nullptr),
m_subwindows (),
m_delegate_sp (),
m_curr_active_window_idx (UINT32_MAX),
@@ -1180,7 +1186,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
}
void
- Reset (WINDOW *w = NULL, bool del = true)
+ Reset(WINDOW *w = nullptr, bool del = true)
{
if (m_window == w)
return;
@@ -1188,12 +1194,12 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
if (m_panel)
{
::del_panel (m_panel);
- m_panel = NULL;
+ m_panel = nullptr;
}
if (m_window && m_delete)
{
::delwin (m_window);
- m_window = NULL;
+ m_window = nullptr;
m_delete = false;
}
if (w)
@@ -1415,7 +1421,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
// Window drawing utilities
//----------------------------------------------------------------------
void
- DrawTitleBox (const char *title, const char *bottom_message = NULL)
+ DrawTitleBox(const char *title, const char *bottom_message = nullptr)
{
attr_t attr = 0;
if (IsActive())
@@ -1456,7 +1462,6 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
}
if (attr)
AttributeOff(attr);
-
}
virtual void
@@ -1554,7 +1559,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
Windows subwindows (m_subwindows);
for (auto subwindow_sp : subwindows)
{
- if (subwindow_sp->m_can_activate == false)
+ if (!subwindow_sp->m_can_activate)
{
HandleCharResult result = subwindow_sp->HandleChar(key);
if (result != eKeyNotHandled)
@@ -1569,7 +1574,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
SetActiveWindow (Window *window)
{
const size_t num_subwindows = m_subwindows.size();
- for (size_t i=0; i<num_subwindows; ++i)
+ for (size_t i = 0; i < num_subwindows; ++i)
{
if (m_subwindows[i].get() == window)
{
@@ -1601,7 +1606,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
// Find first window that wants to be active if this window is active
const size_t num_subwindows = m_subwindows.size();
- for (size_t i=0; i<num_subwindows; ++i)
+ for (size_t i = 0; i < num_subwindows; ++i)
{
if (m_subwindows[i]->GetCanBeActive())
{
@@ -1944,7 +1949,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
m_max_submenu_name_length (0),
m_max_submenu_key_name_length (0),
m_selected (0),
- m_parent (NULL),
+ m_parent(nullptr),
m_submenus (),
m_canned_result (MenuActionResult::NotHandled),
m_delegate_sp()
@@ -1965,7 +1970,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
m_max_submenu_name_length (0),
m_max_submenu_key_name_length (0),
m_selected (0),
- m_parent (NULL),
+ m_parent(nullptr),
m_submenus (),
m_canned_result (MenuActionResult::NotHandled),
m_delegate_sp()
@@ -1990,7 +1995,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
m_max_submenu_key_name_length = 0;
Menus &submenus = GetSubmenus();
const size_t num_submenus = submenus.size();
- for (size_t i=0; i<num_submenus; ++i)
+ for (size_t i = 0; i < num_submenus; ++i)
{
Menu *submenu = submenus[i].get();
if (static_cast<size_t>(m_max_submenu_name_length) < submenu->m_name.size())
@@ -2022,7 +2027,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
if (width > 2)
{
width -= 2;
- for (int i=0; i< width; ++i)
+ for (int i = 0; i < width; ++i)
window.PutChar(ACS_HLINE);
}
window.PutChar(ACS_RTEE);
@@ -2097,7 +2102,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
{
window.SetBackground(2);
window.MoveCursor(0, 0);
- for (size_t i=0; i<num_submenus; ++i)
+ for (size_t i = 0; i < num_submenus; ++i)
{
Menu *menu = submenus[i].get();
if (i > 0)
@@ -2121,7 +2126,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
window.Erase();
window.SetBackground(2);
window.Box();
- for (size_t i=0; i<num_submenus; ++i)
+ for (size_t i = 0; i < num_submenus; ++i)
{
const bool is_selected =
(i == static_cast<size_t>(selected_idx));
@@ -2171,7 +2176,6 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
break;
case KEY_RIGHT:
- {
++m_selected;
if (m_selected >= static_cast<int>(num_submenus))
m_selected = 0;
@@ -2180,11 +2184,9 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
else if (!submenus.empty())
run_menu_sp = submenus.front();
result = eKeyHandled;
- }
break;
case KEY_LEFT:
- {
--m_selected;
if (m_selected < 0)
m_selected = num_submenus - 1;
@@ -2193,11 +2195,10 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
else if (!submenus.empty())
run_menu_sp = submenus.front();
result = eKeyHandled;
- }
break;
default:
- for (size_t i=0; i<num_submenus; ++i)
+ for (size_t i = 0; i < num_submenus; ++i)
{
if (submenus[i]->GetKeyValue() == key)
{
@@ -2285,8 +2286,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
return eKeyHandled;
default:
- {
- for (size_t i=0; i<num_submenus; ++i)
+ for (size_t i = 0; i < num_submenus; ++i)
{
Menu *menu = submenus[i].get();
if (menu->GetKeyValue() == key)
@@ -2298,9 +2298,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
return eKeyHandled;
}
}
- }
break;
-
}
}
else if (menu_type == Menu::Type::Separator)
@@ -2314,11 +2312,10 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
public:
Application (FILE *in, FILE *out) :
m_window_sp(),
- m_screen (NULL),
+ m_screen(nullptr),
m_in (in),
m_out (out)
{
-
}
~Application ()
@@ -2328,7 +2325,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
if (m_screen)
{
::delscreen(m_screen);
- m_screen = NULL;
+ m_screen = nullptr;
}
}
@@ -2340,7 +2337,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
#if 0
::initscr();
#else
- m_screen = ::newterm(NULL, m_out, m_in);
+ m_screen = ::newterm(nullptr, m_out, m_in);
#endif
::start_color();
::curs_set(0);
@@ -2369,7 +2366,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
halfdelay(delay_in_tenths_of_a_second); // Poll using some number of tenths of seconds seconds when calling Window::GetChar()
- ListenerSP listener_sp (new Listener ("lldb.IOHandler.curses.Application"));
+ ListenerSP listener_sp (Listener::MakeListener("lldb.IOHandler.curses.Application"));
ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
@@ -2457,7 +2454,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
if (broadcaster_class == broadcaster_class_process)
{
- debugger.GetCommandInterpreter().UpdateExecutionContext(NULL);
+ debugger.GetCommandInterpreter().UpdateExecutionContext(nullptr);
update = true;
continue; // Don't get any key, just update our view
}
@@ -2472,7 +2469,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
switch (key_result)
{
case eKeyHandled:
- debugger.GetCommandInterpreter().UpdateExecutionContext(NULL);
+ debugger.GetCommandInterpreter().UpdateExecutionContext(nullptr);
update = true;
break;
case eKeyNotHandled:
@@ -2556,7 +2553,7 @@ struct Row
if (valobj)
{
const size_t num_children = valobj->GetNumChildren();
- for (size_t i=0; i<num_children; ++i)
+ for (size_t i = 0; i < num_children; ++i)
{
children.push_back(Row (valobj->GetChildAtIndex(i, true), this));
}
@@ -2646,7 +2643,7 @@ class TreeItem;
class TreeDelegate
{
public:
- TreeDelegate() {}
+ TreeDelegate() = default;
virtual ~TreeDelegate() = default;
virtual void TreeDelegateDrawTreeItem (TreeItem &item, Window &window) = 0;
@@ -2659,11 +2656,10 @@ typedef std::shared_ptr<TreeDelegate> TreeDelegateSP;
class TreeItem
{
public:
-
TreeItem (TreeItem *parent, TreeDelegate &delegate, bool might_have_children) :
m_parent (parent),
m_delegate (delegate),
- m_user_data (NULL),
+ m_user_data(nullptr),
m_identifier (0),
m_row_idx (-1),
m_children (),
@@ -2751,7 +2747,7 @@ public:
// The root item must calculate its children,
// or we must calculate the number of children
// if the item is expanded
- if (m_parent == NULL || expanded)
+ if (m_parent == nullptr || expanded)
GetNumChildren();
for (auto &item : m_children)
@@ -2849,7 +2845,7 @@ public:
{
// If we displayed all the rows and item.Draw() returns
// false we are done drawing and can exit this for loop
- if (item.Draw(window, first_visible_row, selected_row_idx, row_idx, num_rows_left) == false)
+ if (!item.Draw(window, first_visible_row, selected_row_idx, row_idx, num_rows_left))
break;
}
}
@@ -2897,7 +2893,7 @@ public:
if (static_cast<uint32_t>(m_row_idx) == row_idx)
return this;
if (m_children.empty())
- return NULL;
+ return nullptr;
if (IsExpanded())
{
for (auto &item : m_children)
@@ -2907,7 +2903,7 @@ public:
return selected_item_ptr;
}
}
- return NULL;
+ return nullptr;
}
void *
@@ -2957,8 +2953,8 @@ public:
TreeWindowDelegate (Debugger &debugger, const TreeDelegateSP &delegate_sp) :
m_debugger (debugger),
m_delegate_sp (delegate_sp),
- m_root (NULL, *delegate_sp, true),
- m_selected_item (NULL),
+ m_root(nullptr, *delegate_sp, true),
+ m_selected_item(nullptr),
m_num_rows (0),
m_selected_row_idx (0),
m_first_visible_row (0),
@@ -3031,12 +3027,11 @@ public:
}
else
{
- m_selected_item = NULL;
+ m_selected_item = nullptr;
}
window.DeferredRefresh();
-
-
+
return true; // Drawing handled
}
@@ -3060,7 +3055,7 @@ public:
{ ' ', "Toggle item expansion" },
{ ',', "Page up" },
{ '.', "Page down" },
- { '\0', NULL }
+ { '\0', nullptr }
};
return g_source_view_key_help;
}
@@ -3205,7 +3200,7 @@ public:
StreamString strm;
const SymbolContext &sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
ExecutionContext exe_ctx (frame_sp);
- if (FormatEntity::Format(m_format, strm, &sc, &exe_ctx, NULL, NULL, false, false))
+ if (FormatEntity::Format(m_format, strm, &sc, &exe_ctx, nullptr, nullptr, false, false))
{
int right_pad = 1;
window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
@@ -3276,7 +3271,7 @@ public:
{
StreamString strm;
ExecutionContext exe_ctx (thread_sp);
- if (FormatEntity::Format (m_format, strm, NULL, &exe_ctx, NULL, NULL, false, false))
+ if (FormatEntity::Format(m_format, strm, nullptr, &exe_ctx, nullptr, nullptr, false, false))
{
int right_pad = 1;
window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
@@ -3310,7 +3305,7 @@ public:
TreeItem t (&item, *m_frame_delegate_sp, false);
size_t num_frames = thread_sp->GetStackFrameCount();
item.Resize (num_frames, t);
- for (size_t i=0; i<num_frames; ++i)
+ for (size_t i = 0; i < num_frames; ++i)
{
item[i].SetUserData(thread_sp.get());
item[i].SetIdentifier(i);
@@ -3335,7 +3330,7 @@ public:
if (thread_sp)
{
ThreadList &thread_list = thread_sp->GetProcess()->GetThreadList();
- Mutex::Locker locker (thread_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(thread_list.GetMutex());
ThreadSP selected_thread_sp = thread_list.GetSelectedThread();
if (selected_thread_sp->GetID() != thread_sp->GetID())
{
@@ -3385,7 +3380,7 @@ public:
{
StreamString strm;
ExecutionContext exe_ctx (process_sp);
- if (FormatEntity::Format (m_format, strm, NULL, &exe_ctx, NULL, NULL, false, false))
+ if (FormatEntity::Format(m_format, strm, nullptr, &exe_ctx, nullptr, nullptr, false, false))
{
int right_pad = 1;
window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
@@ -3417,10 +3412,10 @@ public:
TreeItem t (&item, *m_thread_delegate_sp, false);
ThreadList &threads = process_sp->GetThreadList();
- Mutex::Locker locker (threads.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
size_t num_threads = threads.GetSize();
item.Resize (num_threads, t);
- for (size_t i=0; i<num_threads; ++i)
+ for (size_t i = 0; i < num_threads; ++i)
{
item[i].SetIdentifier(threads.GetThreadAtIndex(i)->GetID());
item[i].SetMightHaveChildren(true);
@@ -3450,7 +3445,7 @@ public:
ValueObjectListDelegate () :
m_valobj_list (),
m_rows (),
- m_selected_row (NULL),
+ m_selected_row(nullptr),
m_selected_row_idx (0),
m_first_visible_row (0),
m_num_rows (0),
@@ -3462,7 +3457,7 @@ public:
ValueObjectListDelegate (ValueObjectList &valobj_list) :
m_valobj_list (valobj_list),
m_rows (),
- m_selected_row (NULL),
+ m_selected_row(nullptr),
m_selected_row_idx (0),
m_first_visible_row (0),
m_num_rows (0),
@@ -3477,15 +3472,15 @@ public:
void
SetValues (ValueObjectList &valobj_list)
{
- m_selected_row = NULL;
+ m_selected_row = nullptr;
m_selected_row_idx = 0;
m_first_visible_row = 0;
m_num_rows = 0;
m_rows.clear();
m_valobj_list = valobj_list;
const size_t num_values = m_valobj_list.GetSize();
- for (size_t i=0; i<num_values; ++i)
- m_rows.push_back(Row(m_valobj_list.GetValueObjectAtIndex(i), NULL));
+ for (size_t i = 0; i < num_values; ++i)
+ m_rows.push_back(Row(m_valobj_list.GetValueObjectAtIndex(i), nullptr));
}
bool
@@ -3560,7 +3555,7 @@ public:
{ ' ', "Toggle item expansion" },
{ ',', "Page up" },
{ '.', "Page down" },
- { '\0', NULL }
+ { '\0', nullptr }
};
return g_source_view_key_help;
}
@@ -3713,10 +3708,10 @@ protected:
{
ValueObject *valobj = row.valobj.get();
- if (valobj == NULL)
+ if (valobj == nullptr)
return false;
- const char *type_name = options.show_types ? valobj->GetTypeName().GetCString() : NULL;
+ const char *type_name = options.show_types ? valobj->GetTypeName().GetCString() : nullptr;
const char *name = valobj->GetName().GetCString();
const char *value = valobj->GetValueAsCString ();
const char *summary = valobj->GetSummaryAsCString ();
@@ -3844,7 +3839,7 @@ protected:
}
}
}
- return NULL;
+ return nullptr;
}
Row *
@@ -3868,7 +3863,7 @@ public:
FrameVariablesWindowDelegate (Debugger &debugger) :
ValueObjectListDelegate (),
m_debugger (debugger),
- m_frame_block (NULL)
+ m_frame_block(nullptr)
{
}
@@ -3885,8 +3880,8 @@ public:
{
ExecutionContext exe_ctx (m_debugger.GetCommandInterpreter().GetExecutionContext());
Process *process = exe_ctx.GetProcessPtr();
- Block *frame_block = NULL;
- StackFrame *frame = NULL;
+ Block *frame_block = nullptr;
+ StackFrame *frame = nullptr;
if (process)
{
@@ -3916,7 +3911,7 @@ public:
{
const DynamicValueType use_dynamic = eDynamicDontRunTarget;
const size_t num_locals = locals->GetSize();
- for (size_t i=0; i<num_locals; ++i)
+ for (size_t i = 0; i < num_locals; ++i)
{
ValueObjectSP value_sp = frame->GetValueObjectForFrameVariable (locals->GetVariableAtIndex(i), use_dynamic);
if (value_sp)
@@ -3926,7 +3921,6 @@ public:
local_values.Append(synthetic_value_sp);
else
local_values.Append(value_sp);
-
}
}
// Update the values
@@ -3936,7 +3930,7 @@ public:
}
else
{
- m_frame_block = NULL;
+ m_frame_block = nullptr;
// Update the values with an empty list if there is no frame
SetValues(local_values);
}
@@ -4121,7 +4115,7 @@ CursesKeyToCString (int ch)
snprintf(g_desc, sizeof(g_desc), "\\x%2.2x", ch);
return g_desc;
}
- return NULL;
+ return nullptr;
}
HelpDialogDelegate::HelpDialogDelegate (const char *text, KeyHelp *key_help_array) :
@@ -4328,7 +4322,7 @@ public:
{ KEY_RIGHT, "Expand" },
{ KEY_PPAGE, "Page up" },
{ KEY_NPAGE, "Page down" },
- { '\0', NULL }
+ { '\0', nullptr }
};
return g_source_view_key_help;
}
@@ -4437,9 +4431,9 @@ public:
submenus.erase (submenus.begin() + 8, submenus.end());
ThreadList &threads = process->GetThreadList();
- Mutex::Locker locker (threads.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
size_t num_threads = threads.GetSize();
- for (size_t i=0; i<num_threads; ++i)
+ for (size_t i = 0; i < num_threads; ++i)
{
ThreadSP thread_sp = threads.GetThreadAtIndex(i);
char menu_char = '\0';
@@ -4456,7 +4450,7 @@ public:
if (queue_name && queue_name[0])
thread_menu_title.Printf (" %s", queue_name);
}
- menu.AddSubmenu (MenuSP (new Menu(thread_menu_title.GetString().c_str(), NULL, menu_char, thread_sp->GetID())));
+ menu.AddSubmenu(MenuSP(new Menu(thread_menu_title.GetString().c_str(), nullptr, menu_char, thread_sp->GetID())));
}
}
else if (submenus.size() > 7)
@@ -4629,7 +4623,7 @@ public:
if (StateIsStoppedState(state, true))
{
StreamString strm;
- if (thread && FormatEntity::Format (m_format, strm, NULL, &exe_ctx, NULL, NULL, false, false))
+ if (thread && FormatEntity::Format(m_format, strm, nullptr, &exe_ctx, nullptr, nullptr, false, false))
{
window.MoveCursor (40, 0);
window.PutCStringTruncated(strm.GetString().c_str(), 1);
@@ -4666,7 +4660,7 @@ public:
m_debugger (debugger),
m_sc (),
m_file_sp (),
- m_disassembly_scope (NULL),
+ m_disassembly_scope(nullptr),
m_disassembly_sp (),
m_disassembly_range (),
m_title (),
@@ -4725,7 +4719,7 @@ public:
{ 'S', "Step in (single instruction)" },
{ ',', "Page up" },
{ '.', "Page down" },
- { '\0', NULL }
+ { '\0', nullptr }
};
return g_source_view_key_help;
}
@@ -4735,7 +4729,7 @@ public:
{
ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = NULL;
+ Thread *thread = nullptr;
bool update_location = false;
if (process)
@@ -4870,7 +4864,7 @@ public:
if (m_disassembly_scope != m_sc.function)
{
m_disassembly_scope = m_sc.function;
- m_disassembly_sp = m_sc.function->GetInstructions (exe_ctx, NULL, prefer_file_cache);
+ m_disassembly_sp = m_sc.function->GetInstructions(exe_ctx, nullptr, prefer_file_cache);
if (m_disassembly_sp)
{
set_selected_line_to_pc = true;
@@ -4891,7 +4885,7 @@ public:
if (m_disassembly_scope != m_sc.symbol)
{
m_disassembly_scope = m_sc.symbol;
- m_disassembly_sp = m_sc.symbol->GetInstructions (exe_ctx, NULL, prefer_file_cache);
+ m_disassembly_sp = m_sc.symbol->GetInstructions(exe_ctx, nullptr, prefer_file_cache);
if (m_disassembly_sp)
{
set_selected_line_to_pc = true;
@@ -4965,7 +4959,7 @@ public:
const attr_t selected_highlight_attr = A_REVERSE;
const attr_t pc_highlight_attr = COLOR_PAIR(1);
- for (size_t i=0; i<num_visible_lines; ++i)
+ for (size_t i = 0; i < num_visible_lines; ++i)
{
const uint32_t curr_line = m_first_visible_line + i;
if (curr_line < num_source_lines)
@@ -5095,7 +5089,7 @@ public:
m_first_visible_line = pc_idx - non_visible_pc_offset;
}
- for (size_t i=0; i<num_visible_lines; ++i)
+ for (size_t i = 0; i < num_visible_lines; ++i)
{
const uint32_t inst_idx = m_first_visible_line + i;
Instruction *inst = insts.GetInstructionAtIndex(inst_idx).get();
@@ -5141,20 +5135,20 @@ public:
const char *operands = inst->GetOperands(&exe_ctx);
const char *comment = inst->GetComment(&exe_ctx);
- if (mnemonic && mnemonic[0] == '\0')
- mnemonic = NULL;
- if (operands && operands[0] == '\0')
- operands = NULL;
- if (comment && comment[0] == '\0')
- comment = NULL;
+ if (mnemonic != nullptr && mnemonic[0] == '\0')
+ mnemonic = nullptr;
+ if (operands != nullptr && operands[0] == '\0')
+ operands = nullptr;
+ if (comment != nullptr && comment[0] == '\0')
+ comment = nullptr;
strm.Clear();
- if (mnemonic && operands && comment)
+ if (mnemonic != nullptr && operands != nullptr && comment != nullptr)
strm.Printf ("%-8s %-25s ; %s", mnemonic, operands, comment);
- else if (mnemonic && operands)
+ else if (mnemonic != nullptr && operands != nullptr)
strm.Printf ("%-8s %s", mnemonic, operands);
- else if (mnemonic)
+ else if (mnemonic != nullptr)
strm.Printf ("%s", mnemonic);
int right_pad = 1;
@@ -5275,14 +5269,15 @@ public:
ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
if (exe_ctx.HasProcessScope() && exe_ctx.GetProcessRef().IsAlive())
{
- BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint (NULL, // Don't limit the breakpoint to certain modules
- m_file_sp->GetFileSpec(), // Source file
- m_selected_line + 1, // Source line number (m_selected_line is zero based)
- eLazyBoolCalculate, // Check inlines using global setting
- eLazyBoolCalculate, // Skip prologue using global setting,
- false, // internal
- false, // request_hardware
- eLazyBoolCalculate); // move_to_nearest_code
+ BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint(nullptr, // Don't limit the breakpoint to certain modules
+ m_file_sp->GetFileSpec(), // Source file
+ m_selected_line + 1, // Source line number (m_selected_line is zero based)
+ 0, // No offset
+ eLazyBoolCalculate, // Check inlines using global setting
+ eLazyBoolCalculate, // Skip prologue using global setting,
+ false, // internal
+ false, // request_hardware
+ eLazyBoolCalculate); // move_to_nearest_code
// Make breakpoint one shot
bp_sp->GetOptions()->SetOneShot(true);
exe_ctx.GetProcessRef().Resume();
@@ -5311,14 +5306,15 @@ public:
ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
if (exe_ctx.HasTargetScope())
{
- BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint (NULL, // Don't limit the breakpoint to certain modules
- m_file_sp->GetFileSpec(), // Source file
- m_selected_line + 1, // Source line number (m_selected_line is zero based)
- eLazyBoolCalculate, // Check inlines using global setting
- eLazyBoolCalculate, // Skip prologue using global setting,
- false, // internal
- false, // request_hardware
- eLazyBoolCalculate); // move_to_nearest_code
+ BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint(nullptr, // Don't limit the breakpoint to certain modules
+ m_file_sp->GetFileSpec(), // Source file
+ m_selected_line + 1, // Source line number (m_selected_line is zero based)
+ 0, // No offset
+ eLazyBoolCalculate, // Check inlines using global setting
+ eLazyBoolCalculate, // Skip prologue using global setting,
+ false, // internal
+ false, // request_hardware
+ eLazyBoolCalculate); // move_to_nearest_code
}
}
else if (m_selected_line < GetNumDisassemblyLines())
@@ -5452,38 +5448,38 @@ IOHandlerCursesGUI::Activate ()
MenuDelegateSP app_menu_delegate_sp = std::static_pointer_cast<MenuDelegate>(app_delegate_sp);
MenuSP lldb_menu_sp(new Menu("LLDB" , "F1", KEY_F(1), ApplicationDelegate::eMenuID_LLDB));
- MenuSP exit_menuitem_sp(new Menu("Exit", NULL, 'x', ApplicationDelegate::eMenuID_LLDBExit));
+ MenuSP exit_menuitem_sp(new Menu("Exit", nullptr, 'x', ApplicationDelegate::eMenuID_LLDBExit));
exit_menuitem_sp->SetCannedResult(MenuActionResult::Quit);
- lldb_menu_sp->AddSubmenu (MenuSP (new Menu("About LLDB", NULL, 'a', ApplicationDelegate::eMenuID_LLDBAbout)));
+ lldb_menu_sp->AddSubmenu (MenuSP (new Menu("About LLDB", nullptr, 'a', ApplicationDelegate::eMenuID_LLDBAbout)));
lldb_menu_sp->AddSubmenu (MenuSP (new Menu(Menu::Type::Separator)));
lldb_menu_sp->AddSubmenu (exit_menuitem_sp);
MenuSP target_menu_sp(new Menu("Target" ,"F2", KEY_F(2), ApplicationDelegate::eMenuID_Target));
- target_menu_sp->AddSubmenu (MenuSP (new Menu("Create", NULL, 'c', ApplicationDelegate::eMenuID_TargetCreate)));
- target_menu_sp->AddSubmenu (MenuSP (new Menu("Delete", NULL, 'd', ApplicationDelegate::eMenuID_TargetDelete)));
+ target_menu_sp->AddSubmenu (MenuSP (new Menu("Create", nullptr, 'c', ApplicationDelegate::eMenuID_TargetCreate)));
+ target_menu_sp->AddSubmenu (MenuSP (new Menu("Delete", nullptr, 'd', ApplicationDelegate::eMenuID_TargetDelete)));
MenuSP process_menu_sp(new Menu("Process", "F3", KEY_F(3), ApplicationDelegate::eMenuID_Process));
- process_menu_sp->AddSubmenu (MenuSP (new Menu("Attach" , NULL, 'a', ApplicationDelegate::eMenuID_ProcessAttach)));
- process_menu_sp->AddSubmenu (MenuSP (new Menu("Detach" , NULL, 'd', ApplicationDelegate::eMenuID_ProcessDetach)));
- process_menu_sp->AddSubmenu (MenuSP (new Menu("Launch" , NULL, 'l', ApplicationDelegate::eMenuID_ProcessLaunch)));
+ process_menu_sp->AddSubmenu (MenuSP (new Menu("Attach" , nullptr, 'a', ApplicationDelegate::eMenuID_ProcessAttach)));
+ process_menu_sp->AddSubmenu (MenuSP (new Menu("Detach" , nullptr, 'd', ApplicationDelegate::eMenuID_ProcessDetach)));
+ process_menu_sp->AddSubmenu (MenuSP (new Menu("Launch" , nullptr, 'l', ApplicationDelegate::eMenuID_ProcessLaunch)));
process_menu_sp->AddSubmenu (MenuSP (new Menu(Menu::Type::Separator)));
- process_menu_sp->AddSubmenu (MenuSP (new Menu("Continue", NULL, 'c', ApplicationDelegate::eMenuID_ProcessContinue)));
- process_menu_sp->AddSubmenu (MenuSP (new Menu("Halt" , NULL, 'h', ApplicationDelegate::eMenuID_ProcessHalt)));
- process_menu_sp->AddSubmenu (MenuSP (new Menu("Kill" , NULL, 'k', ApplicationDelegate::eMenuID_ProcessKill)));
+ process_menu_sp->AddSubmenu (MenuSP (new Menu("Continue", nullptr, 'c', ApplicationDelegate::eMenuID_ProcessContinue)));
+ process_menu_sp->AddSubmenu (MenuSP (new Menu("Halt" , nullptr, 'h', ApplicationDelegate::eMenuID_ProcessHalt)));
+ process_menu_sp->AddSubmenu (MenuSP (new Menu("Kill" , nullptr, 'k', ApplicationDelegate::eMenuID_ProcessKill)));
MenuSP thread_menu_sp(new Menu("Thread", "F4", KEY_F(4), ApplicationDelegate::eMenuID_Thread));
- thread_menu_sp->AddSubmenu (MenuSP (new Menu("Step In" , NULL, 'i', ApplicationDelegate::eMenuID_ThreadStepIn)));
- thread_menu_sp->AddSubmenu (MenuSP (new Menu("Step Over", NULL, 'v', ApplicationDelegate::eMenuID_ThreadStepOver)));
- thread_menu_sp->AddSubmenu (MenuSP (new Menu("Step Out" , NULL, 'o', ApplicationDelegate::eMenuID_ThreadStepOut)));
+ thread_menu_sp->AddSubmenu (MenuSP (new Menu("Step In" , nullptr, 'i', ApplicationDelegate::eMenuID_ThreadStepIn)));
+ thread_menu_sp->AddSubmenu (MenuSP (new Menu("Step Over", nullptr, 'v', ApplicationDelegate::eMenuID_ThreadStepOver)));
+ thread_menu_sp->AddSubmenu (MenuSP (new Menu("Step Out" , nullptr, 'o', ApplicationDelegate::eMenuID_ThreadStepOut)));
MenuSP view_menu_sp(new Menu("View", "F5", KEY_F(5), ApplicationDelegate::eMenuID_View));
- view_menu_sp->AddSubmenu (MenuSP (new Menu("Backtrace", NULL, 'b', ApplicationDelegate::eMenuID_ViewBacktrace)));
- view_menu_sp->AddSubmenu (MenuSP (new Menu("Registers", NULL, 'r', ApplicationDelegate::eMenuID_ViewRegisters)));
- view_menu_sp->AddSubmenu (MenuSP (new Menu("Source" , NULL, 's', ApplicationDelegate::eMenuID_ViewSource)));
- view_menu_sp->AddSubmenu (MenuSP (new Menu("Variables", NULL, 'v', ApplicationDelegate::eMenuID_ViewVariables)));
+ view_menu_sp->AddSubmenu (MenuSP (new Menu("Backtrace", nullptr, 'b', ApplicationDelegate::eMenuID_ViewBacktrace)));
+ view_menu_sp->AddSubmenu (MenuSP (new Menu("Registers", nullptr, 'r', ApplicationDelegate::eMenuID_ViewRegisters)));
+ view_menu_sp->AddSubmenu (MenuSP (new Menu("Source" , nullptr, 's', ApplicationDelegate::eMenuID_ViewSource)));
+ view_menu_sp->AddSubmenu (MenuSP (new Menu("Variables", nullptr, 'v', ApplicationDelegate::eMenuID_ViewVariables)));
MenuSP help_menu_sp(new Menu("Help", "F6", KEY_F(6), ApplicationDelegate::eMenuID_Help));
- help_menu_sp->AddSubmenu (MenuSP (new Menu("GUI Help", NULL, 'g', ApplicationDelegate::eMenuID_HelpGUIHelp)));
+ help_menu_sp->AddSubmenu (MenuSP (new Menu("GUI Help", nullptr, 'g', ApplicationDelegate::eMenuID_HelpGUIHelp)));
m_app_ap->Initialize();
WindowSP &main_window_sp = m_app_ap->GetMainWindow();
diff --git a/source/Core/Listener.cpp b/source/Core/Listener.cpp
index 34475498d48e..15a698784681 100644
--- a/source/Core/Listener.cpp
+++ b/source/Core/Listener.cpp
@@ -11,6 +11,8 @@
// C Includes
// C++ Includes
+#include <algorithm>
+
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Broadcaster.h"
@@ -18,53 +20,72 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Event.h"
#include "lldb/Host/TimeValue.h"
-#include <algorithm>
using namespace lldb;
using namespace lldb_private;
-Listener::Listener(const char *name) :
- m_name (name),
- m_broadcasters(),
- m_broadcasters_mutex (Mutex::eMutexTypeRecursive),
- m_events (),
- m_events_mutex (Mutex::eMutexTypeRecursive),
- m_cond_wait()
+namespace
+{
+ class BroadcasterManagerWPMatcher
+ {
+ public:
+ BroadcasterManagerWPMatcher (BroadcasterManagerSP manager_sp) : m_manager_sp(manager_sp) {}
+ bool operator() (const BroadcasterManagerWP input_wp) const
+ {
+ BroadcasterManagerSP input_sp = input_wp.lock();
+ return (input_sp && input_sp == m_manager_sp);
+ }
+
+ BroadcasterManagerSP m_manager_sp;
+ };
+} // anonymous namespace
+
+Listener::Listener(const char *name)
+ : m_name(name), m_broadcasters(), m_broadcasters_mutex(), m_events(), m_events_mutex(Mutex::eMutexTypeNormal)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
- if (log)
+ if (log != nullptr)
log->Printf ("%p Listener::Listener('%s')",
static_cast<void*>(this), m_name.c_str());
}
Listener::~Listener()
{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
- Mutex::Locker locker (m_broadcasters_mutex);
-
- size_t num_managers = m_broadcaster_managers.size();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- for (size_t i = 0; i < num_managers; i++)
- m_broadcaster_managers[i]->RemoveListener(*this);
+ Clear();
if (log)
- log->Printf ("%p Listener::~Listener('%s')",
- static_cast<void*>(this), m_name.c_str());
- Clear();
+ log->Printf("%p Listener::%s('%s')", static_cast<void *>(this), __FUNCTION__, m_name.c_str());
}
void
Listener::Clear()
{
- Mutex::Locker locker(m_broadcasters_mutex);
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
broadcaster_collection::iterator pos, end = m_broadcasters.end();
for (pos = m_broadcasters.begin(); pos != end; ++pos)
- pos->first->RemoveListener (this, pos->second.event_mask);
- m_broadcasters.clear();
- m_cond_wait.SetValue (false, eBroadcastNever);
+ {
+ Broadcaster::BroadcasterImplSP broadcaster_sp(pos->first.lock());
+ if (broadcaster_sp)
+ broadcaster_sp->RemoveListener (this, pos->second.event_mask);
+ }
m_broadcasters.clear();
+
Mutex::Locker event_locker(m_events_mutex);
m_events.clear();
+ size_t num_managers = m_broadcaster_managers.size();
+
+ for (size_t i = 0; i < num_managers; i++)
+ {
+ BroadcasterManagerSP manager_sp(m_broadcaster_managers[i].lock());
+ if (manager_sp)
+ manager_sp->RemoveListener(this);
+ }
+
+ if (log)
+ log->Printf("%p Listener::%s('%s')", static_cast<void *>(this), __FUNCTION__, m_name.c_str());
}
uint32_t
@@ -75,25 +96,21 @@ Listener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask
// Scope for "locker"
// Tell the broadcaster to add this object as a listener
{
- Mutex::Locker locker(m_broadcasters_mutex);
- m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask)));
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
+ Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl());
+ m_broadcasters.insert(std::make_pair(impl_wp, BroadcasterInfo(event_mask)));
}
- uint32_t acquired_mask = broadcaster->AddListener (this, event_mask);
-
- if (event_mask != acquired_mask)
- {
+ uint32_t acquired_mask = broadcaster->AddListener (this->shared_from_this(), event_mask);
- }
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
- if (log)
+ if (log != nullptr)
log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
static_cast<void*>(this),
static_cast<void*>(broadcaster), event_mask,
acquired_mask, m_name.c_str());
return acquired_mask;
-
}
return 0;
}
@@ -106,14 +123,16 @@ Listener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask
// Scope for "locker"
// Tell the broadcaster to add this object as a listener
{
- Mutex::Locker locker(m_broadcasters_mutex);
- m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask, callback, callback_user_data)));
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
+ Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl());
+ m_broadcasters.insert(std::make_pair(impl_wp,
+ BroadcasterInfo(event_mask, callback, callback_user_data)));
}
- uint32_t acquired_mask = broadcaster->AddListener (this, event_mask);
+ uint32_t acquired_mask = broadcaster->AddListener (this->shared_from_this(), event_mask);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
- if (log)
+ if (log != nullptr)
{
void **pointer = reinterpret_cast<void**>(&callback);
log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x, callback = %p, user_data = %p) acquired_mask = 0x%8.8x for %s",
@@ -135,11 +154,11 @@ Listener::StopListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
{
// Scope for "locker"
{
- Mutex::Locker locker(m_broadcasters_mutex);
- m_broadcasters.erase (broadcaster);
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
+ m_broadcasters.erase (broadcaster->GetBroadcasterImpl());
}
// Remove the broadcaster from our set of broadcasters
- return broadcaster->RemoveListener (this, event_mask);
+ return broadcaster->RemoveListener (this->shared_from_this(), event_mask);
}
return false;
@@ -152,8 +171,8 @@ Listener::BroadcasterWillDestruct (Broadcaster *broadcaster)
{
// Scope for "broadcasters_locker"
{
- Mutex::Locker broadcasters_locker(m_broadcasters_mutex);
- m_broadcasters.erase (broadcaster);
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
+ m_broadcasters.erase (broadcaster->GetBroadcasterImpl());
}
// Scope for "event_locker"
@@ -168,19 +187,18 @@ Listener::BroadcasterWillDestruct (Broadcaster *broadcaster)
else
++pos;
}
-
- if (m_events.empty())
- m_cond_wait.SetValue (false, eBroadcastNever);
-
}
}
void
-Listener::BroadcasterManagerWillDestruct (BroadcasterManager *manager)
+Listener::BroadcasterManagerWillDestruct (BroadcasterManagerSP manager_sp)
{
// Just need to remove this broadcast manager from the list of managers:
broadcaster_manager_collection::iterator iter, end_iter = m_broadcaster_managers.end();
- iter = find(m_broadcaster_managers.begin(), end_iter, manager);
+ BroadcasterManagerWP manager_wp;
+
+ BroadcasterManagerWPMatcher matcher(manager_sp);
+ iter = std::find_if<broadcaster_manager_collection::iterator, BroadcasterManagerWPMatcher>(m_broadcaster_managers.begin(), end_iter, matcher);
if (iter != end_iter)
m_broadcaster_managers.erase (iter);
}
@@ -189,37 +207,31 @@ void
Listener::AddEvent (EventSP &event_sp)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
- if (log)
+ if (log != nullptr)
log->Printf ("%p Listener('%s')::AddEvent (event_sp = {%p})",
static_cast<void*>(this), m_name.c_str(),
static_cast<void*>(event_sp.get()));
- // Scope for "locker"
- {
- Mutex::Locker locker(m_events_mutex);
- m_events.push_back (event_sp);
- }
- m_cond_wait.SetValue (true, eBroadcastAlways);
+ Mutex::Locker locker(m_events_mutex);
+ m_events.push_back (event_sp);
+ m_events_condition.Broadcast();
}
class EventBroadcasterMatches
{
public:
EventBroadcasterMatches (Broadcaster *broadcaster) :
- m_broadcaster (broadcaster) {
+ m_broadcaster (broadcaster)
+ {
}
bool operator() (const EventSP &event_sp) const
{
- if (event_sp->BroadcasterIs(m_broadcaster))
- return true;
- else
- return false;
+ return event_sp->BroadcasterIs(m_broadcaster);
}
private:
Broadcaster *m_broadcaster;
-
};
class EventMatcher
@@ -242,7 +254,7 @@ public:
{
bool found_source = false;
const ConstString &event_broadcaster_name = event_sp->GetBroadcaster()->GetBroadcasterName();
- for (uint32_t i=0; i<m_num_broadcaster_names; ++i)
+ for (uint32_t i = 0; i < m_num_broadcaster_names; ++i)
{
if (m_broadcaster_names[i] == event_broadcaster_name)
{
@@ -266,28 +278,27 @@ private:
const uint32_t m_event_type_mask;
};
-
bool
Listener::FindNextEventInternal
(
- Broadcaster *broadcaster, // NULL for any broadcaster
- const ConstString *broadcaster_names, // NULL for any event
+ Mutex::Locker& lock,
+ Broadcaster *broadcaster, // nullptr for any broadcaster
+ const ConstString *broadcaster_names, // nullptr for any event
uint32_t num_broadcaster_names,
uint32_t event_type_mask,
EventSP &event_sp,
bool remove)
{
+ // NOTE: callers of this function must lock m_events_mutex using a Mutex::Locker
+ // and pass the locker as the first argument. m_events_mutex is no longer recursive.
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
- Mutex::Locker lock(m_events_mutex);
-
if (m_events.empty())
return false;
-
Listener::event_collection::iterator pos = m_events.end();
- if (broadcaster == NULL && broadcaster_names == NULL && event_type_mask == 0)
+ if (broadcaster == nullptr && broadcaster_names == nullptr && event_type_mask == 0)
{
pos = m_events.begin();
}
@@ -300,7 +311,7 @@ Listener::FindNextEventInternal
{
event_sp = *pos;
- if (log)
+ if (log != nullptr)
log->Printf ("%p '%s' Listener::FindNextEventInternal(broadcaster=%p, broadcaster_names=%p[%u], event_type_mask=0x%8.8x, remove=%i) event %p",
static_cast<void*>(this), GetName(),
static_cast<void*>(broadcaster),
@@ -311,20 +322,12 @@ Listener::FindNextEventInternal
if (remove)
{
m_events.erase(pos);
-
- if (m_events.empty())
- m_cond_wait.SetValue (false, eBroadcastNever);
- }
-
- // Unlock the event queue here. We've removed this event and are about to return
- // it so it should be okay to get the next event off the queue here - and it might
- // be useful to do that in the "DoOnRemoval".
- lock.Unlock();
-
- // Don't call DoOnRemoval if you aren't removing the event...
- if (remove)
+ // Unlock the event queue here. We've removed this event and are about to return
+ // it so it should be okay to get the next event off the queue here - and it might
+ // be useful to do that in the "DoOnRemoval".
+ lock.Unlock();
event_sp->DoOnRemoval();
-
+ }
return true;
}
@@ -335,122 +338,105 @@ Listener::FindNextEventInternal
Event *
Listener::PeekAtNextEvent ()
{
+ Mutex::Locker lock(m_events_mutex);
EventSP event_sp;
- if (FindNextEventInternal (NULL, NULL, 0, 0, event_sp, false))
+ if (FindNextEventInternal(lock, nullptr, nullptr, 0, 0, event_sp, false))
return event_sp.get();
- return NULL;
+ return nullptr;
}
Event *
Listener::PeekAtNextEventForBroadcaster (Broadcaster *broadcaster)
{
+ Mutex::Locker lock(m_events_mutex);
EventSP event_sp;
- if (FindNextEventInternal (broadcaster, NULL, 0, 0, event_sp, false))
+ if (FindNextEventInternal(lock, broadcaster, nullptr, 0, 0, event_sp, false))
return event_sp.get();
- return NULL;
+ return nullptr;
}
Event *
Listener::PeekAtNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask)
{
+ Mutex::Locker lock(m_events_mutex);
EventSP event_sp;
- if (FindNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp, false))
+ if (FindNextEventInternal(lock, broadcaster, nullptr, 0, event_type_mask, event_sp, false))
return event_sp.get();
- return NULL;
+ return nullptr;
}
-
bool
-Listener::GetNextEventInternal
-(
- Broadcaster *broadcaster, // NULL for any broadcaster
- const ConstString *broadcaster_names, // NULL for any event
- uint32_t num_broadcaster_names,
- uint32_t event_type_mask,
- EventSP &event_sp
-)
+Listener::GetNextEventInternal(Broadcaster *broadcaster, // nullptr for any broadcaster
+ const ConstString *broadcaster_names, // nullptr for any event
+ uint32_t num_broadcaster_names,
+ uint32_t event_type_mask,
+ EventSP &event_sp)
{
- return FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true);
+ Mutex::Locker lock(m_events_mutex);
+ return FindNextEventInternal (lock, broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true);
}
bool
Listener::GetNextEvent (EventSP &event_sp)
{
- return GetNextEventInternal (NULL, NULL, 0, 0, event_sp);
+ return GetNextEventInternal(nullptr, nullptr, 0, 0, event_sp);
}
-
bool
Listener::GetNextEventForBroadcaster (Broadcaster *broadcaster, EventSP &event_sp)
{
- return GetNextEventInternal (broadcaster, NULL, 0, 0, event_sp);
+ return GetNextEventInternal(broadcaster, nullptr, 0, 0, event_sp);
}
bool
Listener::GetNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask, EventSP &event_sp)
{
- return GetNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp);
+ return GetNextEventInternal(broadcaster, nullptr, 0, event_type_mask, event_sp);
}
-
bool
-Listener::WaitForEventsInternal
-(
- const TimeValue *timeout,
- Broadcaster *broadcaster, // NULL for any broadcaster
- const ConstString *broadcaster_names, // NULL for any event
- uint32_t num_broadcaster_names,
- uint32_t event_type_mask,
- EventSP &event_sp
-)
+Listener::WaitForEventsInternal(const TimeValue *timeout,
+ Broadcaster *broadcaster, // nullptr for any broadcaster
+ const ConstString *broadcaster_names, // nullptr for any event
+ uint32_t num_broadcaster_names,
+ uint32_t event_type_mask,
+ EventSP &event_sp)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
- bool timed_out = false;
-
- if (log)
+ if (log != nullptr)
log->Printf ("%p Listener::WaitForEventsInternal (timeout = { %p }) for %s",
static_cast<void*>(this), static_cast<const void*>(timeout),
m_name.c_str());
- while (1)
- {
- // Note, we don't want to lock the m_events_mutex in the call to GetNextEventInternal, since the DoOnRemoval
- // code might require that new events be serviced. For instance, the Breakpoint Command's
- if (GetNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp))
- return true;
-
- {
- // Reset condition value to false, so we can wait for new events to be
- // added that might meet our current filter
- // But first poll for any new event that might satisfy our condition, and if so consume it,
- // otherwise wait.
-
- Mutex::Locker event_locker(m_events_mutex);
- const bool remove = false;
- if (FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, remove))
- continue;
- else
- m_cond_wait.SetValue (false, eBroadcastNever);
- }
-
- if (m_cond_wait.WaitForValueEqualTo (true, timeout, &timed_out))
- continue;
+ Mutex::Locker lock(m_events_mutex);
- else if (timed_out)
+ while (true)
+ {
+ if (FindNextEventInternal (lock, broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true))
{
- log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
- if (log)
- log->Printf ("%p Listener::WaitForEventsInternal() timed out for %s",
- static_cast<void*>(this), m_name.c_str());
- break;
+ return true;
}
else
{
- log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
- if (log)
- log->Printf ("%p Listener::WaitForEventsInternal() unknown error for %s",
- static_cast<void*>(this), m_name.c_str());
- break;
+ bool timed_out = false;
+ if (m_events_condition.Wait(m_events_mutex, timeout, &timed_out) != 0)
+ {
+ if (timed_out)
+ {
+ log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
+ if (log != nullptr)
+ log->Printf ("%p Listener::WaitForEventsInternal() timed out for %s",
+ static_cast<void*>(this), m_name.c_str());
+ }
+ else
+ {
+ log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
+ if (log != nullptr)
+ log->Printf ("%p Listener::WaitForEventsInternal() unknown error for %s",
+ static_cast<void*>(this), m_name.c_str());
+ }
+ return false;
+ }
}
}
@@ -458,73 +444,47 @@ Listener::WaitForEventsInternal
}
bool
-Listener::WaitForEventForBroadcasterWithType
-(
- const TimeValue *timeout,
- Broadcaster *broadcaster,
- uint32_t event_type_mask,
- EventSP &event_sp
-)
+Listener::WaitForEventForBroadcasterWithType(const TimeValue *timeout,
+ Broadcaster *broadcaster,
+ uint32_t event_type_mask,
+ EventSP &event_sp)
{
- return WaitForEventsInternal (timeout, broadcaster, NULL, 0, event_type_mask, event_sp);
+ return WaitForEventsInternal(timeout, broadcaster, nullptr, 0, event_type_mask, event_sp);
}
bool
-Listener::WaitForEventForBroadcaster
-(
- const TimeValue *timeout,
- Broadcaster *broadcaster,
- EventSP &event_sp
-)
+Listener::WaitForEventForBroadcaster(const TimeValue *timeout,
+ Broadcaster *broadcaster,
+ EventSP &event_sp)
{
- return WaitForEventsInternal (timeout, broadcaster, NULL, 0, 0, event_sp);
+ return WaitForEventsInternal(timeout, broadcaster, nullptr, 0, 0, event_sp);
}
bool
Listener::WaitForEvent (const TimeValue *timeout, EventSP &event_sp)
{
- return WaitForEventsInternal (timeout, NULL, NULL, 0, 0, event_sp);
+ return WaitForEventsInternal(timeout, nullptr, nullptr, 0, 0, event_sp);
}
-//Listener::broadcaster_collection::iterator
-//Listener::FindBroadcasterWithMask (Broadcaster *broadcaster, uint32_t event_mask, bool exact)
-//{
-// broadcaster_collection::iterator pos;
-// broadcaster_collection::iterator end = m_broadcasters.end();
-// for (pos = m_broadcasters.find (broadcaster);
-// pos != end && pos->first == broadcaster;
-// ++pos)
-// {
-// if (exact)
-// {
-// if ((event_mask & pos->second.event_mask) == event_mask)
-// return pos;
-// }
-// else
-// {
-// if (event_mask & pos->second.event_mask)
-// return pos;
-// }
-// }
-// return end;
-//}
-
size_t
Listener::HandleBroadcastEvent (EventSP &event_sp)
{
size_t num_handled = 0;
- Mutex::Locker locker(m_broadcasters_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
Broadcaster *broadcaster = event_sp->GetBroadcaster();
+ if (!broadcaster)
+ return 0;
broadcaster_collection::iterator pos;
broadcaster_collection::iterator end = m_broadcasters.end();
- for (pos = m_broadcasters.find (broadcaster);
- pos != end && pos->first == broadcaster;
+ Broadcaster::BroadcasterImplSP broadcaster_impl_sp(broadcaster->GetBroadcasterImpl());
+ for (pos = m_broadcasters.find (broadcaster_impl_sp);
+ pos != end && pos->first.lock() == broadcaster_impl_sp;
++pos)
{
BroadcasterInfo info = pos->second;
if (event_sp->GetType () & info.event_mask)
{
- if (info.callback != NULL)
+ if (info.callback != nullptr)
{
info.callback (event_sp, info.callback_user_data);
++num_handled;
@@ -535,28 +495,44 @@ Listener::HandleBroadcastEvent (EventSP &event_sp)
}
uint32_t
-Listener::StartListeningForEventSpec (BroadcasterManager &manager,
+Listener::StartListeningForEventSpec (BroadcasterManagerSP manager_sp,
const BroadcastEventSpec &event_spec)
{
+ if (!manager_sp)
+ return 0;
+
// The BroadcasterManager mutex must be locked before m_broadcasters_mutex
// to avoid violating the lock hierarchy (manager before broadcasters).
- Mutex::Locker manager_locker(manager.m_manager_mutex);
- Mutex::Locker locker(m_broadcasters_mutex);
+ std::lock_guard<std::recursive_mutex> manager_guard(manager_sp->m_manager_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
- uint32_t bits_acquired = manager.RegisterListenerForEvents(*this, event_spec);
+ uint32_t bits_acquired = manager_sp->RegisterListenerForEvents(this->shared_from_this(), event_spec);
if (bits_acquired)
- m_broadcaster_managers.push_back(&manager);
-
+ {
+ broadcaster_manager_collection::iterator iter, end_iter = m_broadcaster_managers.end();
+ BroadcasterManagerWP manager_wp(manager_sp);
+ BroadcasterManagerWPMatcher matcher(manager_sp);
+ iter = std::find_if<broadcaster_manager_collection::iterator, BroadcasterManagerWPMatcher>(m_broadcaster_managers.begin(), end_iter, matcher);
+ if (iter == end_iter)
+ m_broadcaster_managers.push_back(manager_wp);
+ }
+
return bits_acquired;
}
bool
-Listener::StopListeningForEventSpec (BroadcasterManager &manager,
+Listener::StopListeningForEventSpec (BroadcasterManagerSP manager_sp,
const BroadcastEventSpec &event_spec)
{
- Mutex::Locker locker(m_broadcasters_mutex);
- return manager.UnregisterListenerForEvents (*this, event_spec);
+ if (!manager_sp)
+ return false;
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
+ return manager_sp->UnregisterListenerForEvents (this->shared_from_this(), event_spec);
}
-
+ListenerSP
+Listener::MakeListener(const char *name)
+{
+ return ListenerSP(new Listener(name));
+}
diff --git a/source/Core/Log.cpp b/source/Core/Log.cpp
index 8d415bdc0e77..a292df3ed525 100644
--- a/source/Core/Log.cpp
+++ b/source/Core/Log.cpp
@@ -8,30 +8,30 @@
//===----------------------------------------------------------------------===//
// C Includes
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-
// C++ Includes
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
#include <map>
+#include <mutex>
#include <string>
// Other libraries and framework includes
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Signals.h"
+
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/Host.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/ThisThread.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Utility/NameMatches.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Signals.h"
using namespace lldb;
using namespace lldb_private;
@@ -49,9 +49,7 @@ Log::Log (const StreamSP &stream_sp) :
{
}
-Log::~Log ()
-{
-}
+Log::~Log() = default;
Flags &
Log::GetOptions()
@@ -149,8 +147,8 @@ Log::VAPrintf(const char *format, va_list args)
if (m_options.Test(LLDB_LOG_OPTION_THREADSAFE))
{
- static Mutex g_LogThreadedMutex(Mutex::eMutexTypeRecursive);
- Mutex::Locker locker(g_LogThreadedMutex);
+ static std::recursive_mutex g_LogThreadedMutex;
+ std::lock_guard<std::recursive_mutex> guard(g_LogThreadedMutex);
stream_sp->PutCString(header.GetString().c_str());
stream_sp->Flush();
}
@@ -178,7 +176,6 @@ Log::Debug(const char *format, ...)
va_end(args);
}
-
//----------------------------------------------------------------------
// Print debug strings if and only if the global debug option is set to
// a non-zero value.
@@ -195,7 +192,6 @@ Log::DebugVerbose(const char *format, ...)
va_end(args);
}
-
//----------------------------------------------------------------------
// Log only if all of the bits are set
//----------------------------------------------------------------------
@@ -223,7 +219,6 @@ Log::Error(const char *format, ...)
va_end(args);
}
-
void
Log::VAError(const char *format, va_list args)
{
@@ -237,7 +232,6 @@ Log::VAError(const char *format, va_list args)
free(arg_msg);
}
-
//----------------------------------------------------------------------
// Printing of errors that ARE fatal. Exit with ERR exit code
// immediately.
@@ -259,7 +253,6 @@ Log::FatalError(int err, const char *format, ...)
::exit(err);
}
-
//----------------------------------------------------------------------
// Printing of warnings that are not fatal only if verbose mode is
// enabled.
@@ -298,6 +291,7 @@ Log::WarningVerbose(const char *format, ...)
Printf("warning: %s", arg_msg);
free(arg_msg);
}
+
//----------------------------------------------------------------------
// Printing of warnings that are not fatal.
//----------------------------------------------------------------------
@@ -323,7 +317,6 @@ typedef CallbackMap::iterator CallbackMapIter;
typedef std::map <ConstString, LogChannelSP> LogChannelMap;
typedef LogChannelMap::iterator LogChannelMapIter;
-
// Surround our callback map with a singleton function so we don't have any
// global initializers.
static CallbackMap &
@@ -401,13 +394,10 @@ Log::EnableLogChannel(lldb::StreamSP &log_stream_sp,
}
void
-Log::EnableAllLogChannels
-(
- StreamSP &log_stream_sp,
- uint32_t log_options,
- const char **categories,
- Stream *feedback_strm
-)
+Log::EnableAllLogChannels(StreamSP &log_stream_sp,
+ uint32_t log_options,
+ const char **categories,
+ Stream *feedback_strm)
{
CallbackMap &callback_map = GetCallbackMap ();
CallbackMapIter pos, end = callback_map.end();
@@ -421,7 +411,6 @@ Log::EnableAllLogChannels
{
channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories);
}
-
}
void
@@ -441,7 +430,6 @@ Log::AutoCompleteChannelName (const char *channel_name, StringList &matches)
}
else
matches.AppendString(pos_channel_name);
-
}
}
@@ -471,7 +459,7 @@ Log::Initialize()
void
Log::Terminate ()
{
- DisableAllLogChannels (NULL);
+ DisableAllLogChannels(nullptr);
}
void
@@ -492,7 +480,7 @@ Log::ListAllLogChannels (Stream *strm)
uint32_t idx = 0;
const char *name;
- for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != NULL; ++idx)
+ for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != nullptr; ++idx)
{
LogChannelSP log_channel_sp(LogChannel::FindPlugin (name));
if (log_channel_sp)
@@ -529,7 +517,6 @@ Log::GetDebug() const
return false;
}
-
LogChannelSP
LogChannel::FindPlugin (const char *plugin_name)
{
@@ -566,8 +553,4 @@ LogChannel::LogChannel () :
{
}
-LogChannel::~LogChannel ()
-{
-}
-
-
+LogChannel::~LogChannel() = default;
diff --git a/source/Core/Logging.cpp b/source/Core/Logging.cpp
index d08d833ee469..9eb4f6676a4d 100644
--- a/source/Core/Logging.cpp
+++ b/source/Core/Logging.cpp
@@ -11,30 +11,31 @@
// C Includes
// C++ Includes
+#include <cstring>
#include <atomic>
+
// Other libraries and framework includes
// Project includes
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamFile.h"
-#include <string.h>
using namespace lldb;
using namespace lldb_private;
-
// We want to avoid global constructors where code needs to be run so here we
// control access to our static g_log_sp by hiding it in a singleton function
// that will construct the static g_lob_sp the first time this function is
// called.
static std::atomic<bool> g_log_enabled {false};
-static Log * g_log = NULL;
+static Log * g_log = nullptr;
+
static Log *
GetLog ()
{
if (!g_log_enabled)
- return NULL;
+ return nullptr;
return g_log;
}
@@ -62,7 +63,7 @@ lldb_private::GetLogIfAllCategoriesSet (uint32_t mask)
{
uint32_t log_mask = log->GetMask().Get();
if ((log_mask & mask) != mask)
- return NULL;
+ return nullptr;
}
return log;
}
@@ -84,7 +85,7 @@ void
lldb_private::LogIfAnyCategoriesSet (uint32_t mask, const char *format, ...)
{
Log *log(GetLogIfAnyCategoriesSet (mask));
- if (log)
+ if (log != nullptr)
{
va_list args;
va_start (args, format);
@@ -97,9 +98,9 @@ Log *
lldb_private::GetLogIfAnyCategoriesSet (uint32_t mask)
{
Log *log(GetLog ());
- if (log && mask && (mask & log->GetMask().Get()))
+ if (log != nullptr && mask && (mask & log->GetMask().Get()))
return log;
- return NULL;
+ return nullptr;
}
void
@@ -107,13 +108,13 @@ lldb_private::DisableLog (const char **categories, Stream *feedback_strm)
{
Log *log(GetLog ());
- if (log)
+ if (log != nullptr)
{
uint32_t flag_bits = 0;
- if (categories[0] != NULL)
+ if (categories[0] != nullptr)
{
flag_bits = log->GetMask().Get();
- for (size_t i = 0; categories[i] != NULL; ++i)
+ for (size_t i = 0; categories[i] != nullptr; ++i)
{
const char *arg = categories[i];
@@ -149,6 +150,7 @@ lldb_private::DisableLog (const char **categories, Stream *feedback_strm)
else if (0 == ::strcasecmp(arg, "jit")) flag_bits &= ~LIBLLDB_LOG_JIT_LOADER;
else if (0 == ::strcasecmp(arg, "language")) flag_bits &= ~LIBLLDB_LOG_LANGUAGE;
else if (0 == ::strncasecmp(arg, "formatters", 10)) flag_bits &= ~LIBLLDB_LOG_DATAFORMATTERS;
+ else if (0 == ::strncasecmp(arg, "demangle", 8)) flag_bits &= ~LIBLLDB_LOG_DEMANGLE;
else
{
feedback_strm->Printf ("error: unrecognized log category '%s'\n", arg);
@@ -164,8 +166,6 @@ lldb_private::DisableLog (const char **categories, Stream *feedback_strm)
g_log_enabled = false;
}
}
-
- return;
}
Log *
@@ -174,7 +174,7 @@ lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const ch
// Try see if there already is a log - that way we can reuse its settings.
// We could reuse the log in toto, but we don't know that the stream is the same.
uint32_t flag_bits;
- if (g_log)
+ if (g_log != nullptr)
flag_bits = g_log->GetMask().Get();
else
flag_bits = 0;
@@ -182,15 +182,15 @@ lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const ch
// Now make a new log with this stream if one was provided
if (log_stream_sp)
{
- if (g_log)
+ if (g_log != nullptr)
g_log->SetStream(log_stream_sp);
else
g_log = new Log(log_stream_sp);
}
- if (g_log)
+ if (g_log != nullptr)
{
- for (size_t i=0; categories[i] != NULL; ++i)
+ for (size_t i = 0; categories[i] != nullptr; ++i)
{
const char *arg = categories[i];
@@ -226,6 +226,7 @@ lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const ch
else if (0 == ::strcasecmp(arg, "jit")) flag_bits |= LIBLLDB_LOG_JIT_LOADER;
else if (0 == ::strcasecmp(arg, "language")) flag_bits |= LIBLLDB_LOG_LANGUAGE;
else if (0 == ::strncasecmp(arg, "formatters", 10)) flag_bits |= LIBLLDB_LOG_DATAFORMATTERS;
+ else if (0 == ::strncasecmp(arg, "demangle", 8)) flag_bits |= LIBLLDB_LOG_DEMANGLE;
else
{
feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
@@ -241,7 +242,6 @@ lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const ch
return g_log;
}
-
void
lldb_private::ListLogCategories (Stream *strm)
{
@@ -253,6 +253,7 @@ lldb_private::ListLogCategories (Stream *strm)
" communication - log communication activities\n"
" connection - log connection details\n"
" default - enable the default set of logging categories for liblldb\n"
+ " demangle - log mangled names to catch demangler crashes\n"
" dyld - log shared library related activities\n"
" events - log broadcaster, listener and event queue activities\n"
" expr - log expressions\n"
diff --git a/source/Core/Makefile b/source/Core/Makefile
deleted file mode 100644
index b7773e3f571d..000000000000
--- a/source/Core/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Core/Makefile --------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LIBRARYNAME := lldbCore
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp
index bdc710c8f8e1..543b34e337a2 100644
--- a/source/Core/Mangled.cpp
+++ b/source/Core/Mangled.cpp
@@ -34,6 +34,8 @@
#include "llvm/ADT/DenseMap.h"
#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Logging.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
@@ -271,6 +273,8 @@ Mangled::GetDemangledName (lldb::LanguageType language) const
"Mangled::GetDemangledName (m_mangled = %s)",
m_mangled.GetCString());
+ Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DEMANGLE);
+
// Don't bother running anything that isn't mangled
const char *mangled_name = m_mangled.GetCString();
ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)};
@@ -285,6 +289,8 @@ Mangled::GetDemangledName (lldb::LanguageType language) const
case eManglingSchemeMSVC:
{
#if defined(_MSC_VER)
+ if (log)
+ log->Printf("demangle msvc: %s", mangled_name);
const size_t demangled_length = 2048;
demangled_name = static_cast<char *>(::malloc(demangled_length));
::ZeroMemory(demangled_name, demangled_length);
@@ -295,6 +301,14 @@ Mangled::GetDemangledName (lldb::LanguageType language) const
UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers
UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords
);
+ if (log)
+ {
+ if (demangled_name && demangled_name[0])
+ log->Printf("demangled msvc: %s -> \"%s\"", mangled_name, demangled_name);
+ else
+ log->Printf("demangled msvc: %s -> error: 0x%" PRIx64, mangled_name, result);
+ }
+
if (result == 0)
{
free(demangled_name);
@@ -306,6 +320,8 @@ Mangled::GetDemangledName (lldb::LanguageType language) const
case eManglingSchemeItanium:
{
#ifdef LLDB_USE_BUILTIN_DEMANGLER
+ if (log)
+ log->Printf("demangle itanium: %s", mangled_name);
// Try to use the fast-path demangler first for the
// performance win, falling back to the full demangler only
// when necessary
@@ -315,6 +331,13 @@ Mangled::GetDemangledName (lldb::LanguageType language) const
#else
demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL);
#endif
+ if (log)
+ {
+ if (demangled_name)
+ log->Printf("demangled itanium: %s -> \"%s\"", mangled_name, demangled_name);
+ else
+ log->Printf("demangled itanium: %s -> error: failed to demangle", mangled_name);
+ }
break;
}
case eManglingSchemeNone:
diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp
index a29456f5b5a5..5fe39abda183 100644
--- a/source/Core/Module.cpp
+++ b/source/Core/Module.cpp
@@ -7,9 +7,17 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Core/Module.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/Support/raw_os_ostream.h"
+#include "llvm/Support/Signals.h"
+
+// Project includes
#include "lldb/Core/AddressResolverFileLine.h"
#include "lldb/Core/Error.h"
-#include "lldb/Core/Module.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
@@ -40,9 +48,6 @@
#include "Plugins/ObjectFile/JIT/ObjectFileJIT.h"
-#include "llvm/Support/raw_os_ostream.h"
-#include "llvm/Support/Signals.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -60,14 +65,14 @@ GetModuleCollection()
// is a big problem we can introduce a Finalize method that will tear everything down in
// a predictable order.
- static ModuleCollection *g_module_collection = NULL;
- if (g_module_collection == NULL)
+ static ModuleCollection *g_module_collection = nullptr;
+ if (g_module_collection == nullptr)
g_module_collection = new ModuleCollection();
return *g_module_collection;
}
-Mutex *
+std::recursive_mutex &
Module::GetAllocationModuleCollectionMutex()
{
// NOTE: The mutex below must be leaked since the global module list in
@@ -75,30 +80,30 @@ Module::GetAllocationModuleCollectionMutex()
// if it will tear itself down before the "g_module_collection_mutex" below
// will. So we leak a Mutex object below to safeguard against that
- static Mutex *g_module_collection_mutex = NULL;
- if (g_module_collection_mutex == NULL)
- g_module_collection_mutex = new Mutex (Mutex::eMutexTypeRecursive); // NOTE: known leak
- return g_module_collection_mutex;
+ static std::recursive_mutex *g_module_collection_mutex = nullptr;
+ if (g_module_collection_mutex == nullptr)
+ g_module_collection_mutex = new std::recursive_mutex; // NOTE: known leak
+ return *g_module_collection_mutex;
}
size_t
Module::GetNumberAllocatedModules ()
{
- Mutex::Locker locker (GetAllocationModuleCollectionMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetAllocationModuleCollectionMutex());
return GetModuleCollection().size();
}
Module *
Module::GetAllocatedModuleAtIndex (size_t idx)
{
- Mutex::Locker locker (GetAllocationModuleCollectionMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetAllocationModuleCollectionMutex());
ModuleCollection &modules = GetModuleCollection();
if (idx < modules.size())
return modules[idx];
- return NULL;
+ return nullptr;
}
-#if 0
+#if 0
// These functions help us to determine if modules are still loaded, yet don't require that
// you have a command interpreter and can easily be called from an external debugger.
namespace lldb {
@@ -117,7 +122,7 @@ namespace lldb {
ModuleCollection &modules = GetModuleCollection();
const size_t count = modules.size();
printf ("%s: %" PRIu64 " modules:\n", __PRETTY_FUNCTION__, (uint64_t)count);
- for (size_t i=0; i<count; ++i)
+ for (size_t i = 0; i < count; ++i)
{
StreamString strm;
@@ -135,44 +140,42 @@ namespace lldb {
#endif
-Module::Module (const ModuleSpec &module_spec) :
- m_mutex (Mutex::eMutexTypeRecursive),
- m_mod_time (),
- m_arch (),
- m_uuid (),
- m_file (),
- m_platform_file(),
- m_remote_install_file(),
- m_symfile_spec (),
- m_object_name (),
- m_object_offset (),
- m_object_mod_time (),
- m_objfile_sp (),
- m_symfile_ap (),
- m_type_system_map(),
- m_source_mappings (),
- m_sections_ap(),
- m_did_load_objfile (false),
- m_did_load_symbol_vendor (false),
- m_did_parse_uuid (false),
- m_file_has_changed (false),
- m_first_file_changed_log (false)
+Module::Module(const ModuleSpec &module_spec)
+ : m_mutex(),
+ m_mod_time(),
+ m_arch(),
+ m_uuid(),
+ m_file(),
+ m_platform_file(),
+ m_remote_install_file(),
+ m_symfile_spec(),
+ m_object_name(),
+ m_object_offset(),
+ m_object_mod_time(),
+ m_objfile_sp(),
+ m_symfile_ap(),
+ m_type_system_map(),
+ m_source_mappings(),
+ m_sections_ap(),
+ m_did_load_objfile(false),
+ m_did_load_symbol_vendor(false),
+ m_did_parse_uuid(false),
+ m_file_has_changed(false),
+ m_first_file_changed_log(false)
{
// Scope for locker below...
{
- Mutex::Locker locker (GetAllocationModuleCollectionMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetAllocationModuleCollectionMutex());
GetModuleCollection().push_back(this);
}
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT|LIBLLDB_LOG_MODULES));
- if (log)
- log->Printf ("%p Module::Module((%s) '%s%s%s%s')",
- static_cast<void*>(this),
- module_spec.GetArchitecture().GetArchitectureName(),
- module_spec.GetFileSpec().GetPath().c_str(),
- module_spec.GetObjectName().IsEmpty() ? "" : "(",
- module_spec.GetObjectName().IsEmpty() ? "" : module_spec.GetObjectName().AsCString(""),
- module_spec.GetObjectName().IsEmpty() ? "" : ")");
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES));
+ if (log != nullptr)
+ log->Printf("%p Module::Module((%s) '%s%s%s%s')", static_cast<void *>(this),
+ module_spec.GetArchitecture().GetArchitectureName(), module_spec.GetFileSpec().GetPath().c_str(),
+ module_spec.GetObjectName().IsEmpty() ? "" : "(",
+ module_spec.GetObjectName().IsEmpty() ? "" : module_spec.GetObjectName().AsCString(""),
+ module_spec.GetObjectName().IsEmpty() ? "" : ")");
// First extract all module specifications from the file using the local
// file path. If there are no specifications, then don't fill anything in
@@ -189,18 +192,18 @@ Module::Module (const ModuleSpec &module_spec) :
ModuleSpec matching_module_spec;
if (modules_specs.FindMatchingModuleSpec(module_spec, matching_module_spec) == 0)
return;
-
+
if (module_spec.GetFileSpec())
m_mod_time = module_spec.GetFileSpec().GetModificationTime();
else if (matching_module_spec.GetFileSpec())
m_mod_time = matching_module_spec.GetFileSpec().GetModificationTime();
-
+
// Copy the architecture from the actual spec if we got one back, else use the one that was specified
if (matching_module_spec.GetArchitecture().IsValid())
m_arch = matching_module_spec.GetArchitecture();
else if (module_spec.GetArchitecture().IsValid())
m_arch = module_spec.GetArchitecture();
-
+
// Copy the file spec over and use the specified one (if there was one) so we
// don't use a path that might have gotten resolved a path in 'matching_module_spec'
if (module_spec.GetFileSpec())
@@ -213,57 +216,53 @@ Module::Module (const ModuleSpec &module_spec) :
m_platform_file = module_spec.GetPlatformFileSpec();
else if (matching_module_spec.GetPlatformFileSpec())
m_platform_file = matching_module_spec.GetPlatformFileSpec();
-
+
// Copy the symbol file spec over
if (module_spec.GetSymbolFileSpec())
m_symfile_spec = module_spec.GetSymbolFileSpec();
else if (matching_module_spec.GetSymbolFileSpec())
m_symfile_spec = matching_module_spec.GetSymbolFileSpec();
-
+
// Copy the object name over
if (matching_module_spec.GetObjectName())
m_object_name = matching_module_spec.GetObjectName();
else
m_object_name = module_spec.GetObjectName();
-
+
// Always trust the object offset (file offset) and object modification
// time (for mod time in a BSD static archive) of from the matching
// module specification
m_object_offset = matching_module_spec.GetObjectOffset();
m_object_mod_time = matching_module_spec.GetObjectModificationTime();
-
}
-Module::Module(const FileSpec& file_spec,
- const ArchSpec& arch,
- const ConstString *object_name,
- lldb::offset_t object_offset,
- const TimeValue *object_mod_time_ptr) :
- m_mutex (Mutex::eMutexTypeRecursive),
- m_mod_time (file_spec.GetModificationTime()),
- m_arch (arch),
- m_uuid (),
- m_file (file_spec),
- m_platform_file(),
- m_remote_install_file (),
- m_symfile_spec (),
- m_object_name (),
- m_object_offset (object_offset),
- m_object_mod_time (),
- m_objfile_sp (),
- m_symfile_ap (),
- m_type_system_map(),
- m_source_mappings (),
- m_sections_ap(),
- m_did_load_objfile (false),
- m_did_load_symbol_vendor (false),
- m_did_parse_uuid (false),
- m_file_has_changed (false),
- m_first_file_changed_log (false)
+Module::Module(const FileSpec &file_spec, const ArchSpec &arch, const ConstString *object_name,
+ lldb::offset_t object_offset, const TimeValue *object_mod_time_ptr)
+ : m_mutex(),
+ m_mod_time(file_spec.GetModificationTime()),
+ m_arch(arch),
+ m_uuid(),
+ m_file(file_spec),
+ m_platform_file(),
+ m_remote_install_file(),
+ m_symfile_spec(),
+ m_object_name(),
+ m_object_offset(object_offset),
+ m_object_mod_time(),
+ m_objfile_sp(),
+ m_symfile_ap(),
+ m_type_system_map(),
+ m_source_mappings(),
+ m_sections_ap(),
+ m_did_load_objfile(false),
+ m_did_load_symbol_vendor(false),
+ m_did_parse_uuid(false),
+ m_file_has_changed(false),
+ m_first_file_changed_log(false)
{
// Scope for locker below...
{
- Mutex::Locker locker (GetAllocationModuleCollectionMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetAllocationModuleCollectionMutex());
GetModuleCollection().push_back(this);
}
@@ -273,40 +272,37 @@ Module::Module(const FileSpec& file_spec,
if (object_mod_time_ptr)
m_object_mod_time = *object_mod_time_ptr;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT|LIBLLDB_LOG_MODULES));
- if (log)
- log->Printf ("%p Module::Module((%s) '%s%s%s%s')",
- static_cast<void*>(this), m_arch.GetArchitectureName(),
- m_file.GetPath().c_str(),
- m_object_name.IsEmpty() ? "" : "(",
- m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
- m_object_name.IsEmpty() ? "" : ")");
-}
-
-Module::Module () :
- m_mutex (Mutex::eMutexTypeRecursive),
- m_mod_time (),
- m_arch (),
- m_uuid (),
- m_file (),
- m_platform_file(),
- m_remote_install_file (),
- m_symfile_spec (),
- m_object_name (),
- m_object_offset (0),
- m_object_mod_time (),
- m_objfile_sp (),
- m_symfile_ap (),
- m_type_system_map(),
- m_source_mappings (),
- m_sections_ap(),
- m_did_load_objfile (false),
- m_did_load_symbol_vendor (false),
- m_did_parse_uuid (false),
- m_file_has_changed (false),
- m_first_file_changed_log (false)
-{
- Mutex::Locker locker (GetAllocationModuleCollectionMutex());
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES));
+ if (log != nullptr)
+ log->Printf("%p Module::Module((%s) '%s%s%s%s')", static_cast<void *>(this), m_arch.GetArchitectureName(),
+ m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
+ m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");
+}
+
+Module::Module()
+ : m_mutex(),
+ m_mod_time(),
+ m_arch(),
+ m_uuid(),
+ m_file(),
+ m_platform_file(),
+ m_remote_install_file(),
+ m_symfile_spec(),
+ m_object_name(),
+ m_object_offset(0),
+ m_object_mod_time(),
+ m_objfile_sp(),
+ m_symfile_ap(),
+ m_type_system_map(),
+ m_source_mappings(),
+ m_sections_ap(),
+ m_did_load_objfile(false),
+ m_did_load_symbol_vendor(false),
+ m_did_parse_uuid(false),
+ m_file_has_changed(false),
+ m_first_file_changed_log(false)
+{
+ std::lock_guard<std::recursive_mutex> guard(GetAllocationModuleCollectionMutex());
GetModuleCollection().push_back(this);
}
@@ -314,10 +310,10 @@ Module::~Module()
{
// Lock our module down while we tear everything down to make sure
// we don't get any access to the module while it is being destroyed
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Scope for locker below...
{
- Mutex::Locker locker (GetAllocationModuleCollectionMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetAllocationModuleCollectionMutex());
ModuleCollection &modules = GetModuleCollection();
ModuleCollection::iterator end = modules.end();
ModuleCollection::iterator pos = std::find(modules.begin(), end, this);
@@ -325,7 +321,7 @@ Module::~Module()
modules.erase(pos);
}
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT|LIBLLDB_LOG_MODULES));
- if (log)
+ if (log != nullptr)
log->Printf ("%p Module::~Module((%s) '%s%s%s%s')",
static_cast<void*>(this),
m_arch.GetArchitectureName(),
@@ -352,7 +348,7 @@ Module::GetMemoryObjectFile (const lldb::ProcessSP &process_sp, lldb::addr_t hea
}
else
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (process_sp)
{
m_did_load_objfile = true;
@@ -395,18 +391,17 @@ Module::GetMemoryObjectFile (const lldb::ProcessSP &process_sp, lldb::addr_t hea
return m_objfile_sp.get();
}
-
const lldb_private::UUID&
Module::GetUUID()
{
- if (m_did_parse_uuid.load() == false)
+ if (!m_did_parse_uuid.load())
{
- Mutex::Locker locker (m_mutex);
- if (m_did_parse_uuid.load() == false)
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (!m_did_parse_uuid.load())
{
ObjectFile * obj_file = GetObjectFile ();
- if (obj_file != NULL)
+ if (obj_file != nullptr)
{
obj_file->GetUUID(&m_uuid);
m_did_parse_uuid = true;
@@ -425,7 +420,7 @@ Module::GetTypeSystemForLanguage (LanguageType language)
void
Module::ParseAllDebugSymbols()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
size_t num_comp_units = GetNumCompileUnits();
if (num_comp_units == 0)
return;
@@ -439,12 +434,12 @@ Module::ParseAllDebugSymbols()
sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
if (sc.comp_unit)
{
- sc.function = NULL;
+ sc.function = nullptr;
symbols->ParseVariablesForContext(sc);
symbols->ParseCompileUnitFunctions(sc);
- for (size_t func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx)
+ for (size_t func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != nullptr; ++func_idx)
{
symbols->ParseFunctionBlocks(sc);
@@ -452,9 +447,8 @@ Module::ParseAllDebugSymbols()
symbols->ParseVariablesForContext(sc);
}
-
// Parse all types for this compile unit
- sc.function = NULL;
+ sc.function = nullptr;
symbols->ParseTypes(sc);
}
}
@@ -481,7 +475,7 @@ Module::DumpSymbolContext(Stream *s)
size_t
Module::GetNumCompileUnits()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer(__PRETTY_FUNCTION__,
"Module::GetNumCompileUnits (module = %p)",
static_cast<void*>(this));
@@ -494,7 +488,7 @@ Module::GetNumCompileUnits()
CompUnitSP
Module::GetCompileUnitAtIndex (size_t index)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
size_t num_comp_units = GetNumCompileUnits ();
CompUnitSP cu_sp;
@@ -510,7 +504,7 @@ Module::GetCompileUnitAtIndex (size_t index)
bool
Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%" PRIx64 ")", vm_addr);
SectionList *section_list = GetSectionList();
if (section_list)
@@ -522,7 +516,7 @@ uint32_t
Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc,
bool resolve_tail_call_address)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t resolved_flags = 0;
// Clear the result symbol context in case we don't find anything, but don't clear the target
@@ -548,7 +542,8 @@ Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve
if (resolve_scope & eSymbolContextCompUnit ||
resolve_scope & eSymbolContextFunction ||
resolve_scope & eSymbolContextBlock ||
- resolve_scope & eSymbolContextLineEntry )
+ resolve_scope & eSymbolContextLineEntry ||
+ resolve_scope & eSymbolContextVariable )
{
resolved_flags |= sym_vendor->ResolveSymbolContext (so_addr, resolve_scope, sc);
}
@@ -672,7 +667,7 @@ Module::ResolveSymbolContextForFilePath
uint32_t
Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer(__PRETTY_FUNCTION__,
"Module::ResolveSymbolContextForFilePath (%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)",
file_spec.GetPath().c_str(),
@@ -689,7 +684,6 @@ Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t li
return sc_list.GetSize() - initial_count;
}
-
size_t
Module::FindGlobalVariables (const ConstString &name,
const CompilerDeclContext *parent_decl_ctx,
@@ -728,7 +722,7 @@ Module::FindCompileUnits (const FileSpec &path,
SymbolContext sc;
sc.module_sp = shared_from_this();
const bool compare_directory = (bool)path.GetDirectory();
- for (size_t i=0; i<num_compile_units; ++i)
+ for (size_t i = 0; i < num_compile_units; ++i)
{
sc.comp_unit = GetCompileUnitAtIndex(i).get();
if (sc.comp_unit)
@@ -740,6 +734,186 @@ Module::FindCompileUnits (const FileSpec &path,
return sc_list.GetSize() - start_size;
}
+Module::LookupInfo::LookupInfo(const ConstString &name, uint32_t name_type_mask, lldb::LanguageType language) :
+ m_name(name),
+ m_lookup_name(),
+ m_language(language),
+ m_name_type_mask(0),
+ m_match_name_after_lookup(false)
+{
+ const char *name_cstr = name.GetCString();
+ llvm::StringRef basename;
+ llvm::StringRef context;
+
+ if (name_type_mask & eFunctionNameTypeAuto)
+ {
+ if (CPlusPlusLanguage::IsCPPMangledName (name_cstr))
+ m_name_type_mask = eFunctionNameTypeFull;
+ else if ((language == eLanguageTypeUnknown ||
+ Language::LanguageIsObjC(language)) &&
+ ObjCLanguage::IsPossibleObjCMethodName (name_cstr))
+ m_name_type_mask = eFunctionNameTypeFull;
+ else if (Language::LanguageIsC(language))
+ {
+ m_name_type_mask = eFunctionNameTypeFull;
+ }
+ else
+ {
+ if ((language == eLanguageTypeUnknown ||
+ Language::LanguageIsObjC(language)) &&
+ ObjCLanguage::IsPossibleObjCSelector(name_cstr))
+ m_name_type_mask |= eFunctionNameTypeSelector;
+
+ CPlusPlusLanguage::MethodName cpp_method (name);
+ basename = cpp_method.GetBasename();
+ if (basename.empty())
+ {
+ if (CPlusPlusLanguage::ExtractContextAndIdentifier (name_cstr, context, basename))
+ m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
+ else
+ m_name_type_mask |= eFunctionNameTypeFull;
+ }
+ else
+ {
+ m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
+ }
+ }
+ }
+ else
+ {
+ m_name_type_mask = name_type_mask;
+ if (name_type_mask & eFunctionNameTypeMethod || name_type_mask & eFunctionNameTypeBase)
+ {
+ // If they've asked for a CPP method or function name and it can't be that, we don't
+ // even need to search for CPP methods or names.
+ CPlusPlusLanguage::MethodName cpp_method (name);
+ if (cpp_method.IsValid())
+ {
+ basename = cpp_method.GetBasename();
+
+ if (!cpp_method.GetQualifiers().empty())
+ {
+ // There is a "const" or other qualifier following the end of the function parens,
+ // this can't be a eFunctionNameTypeBase
+ m_name_type_mask &= ~(eFunctionNameTypeBase);
+ if (m_name_type_mask == eFunctionNameTypeNone)
+ return;
+ }
+ }
+ else
+ {
+ // If the CPP method parser didn't manage to chop this up, try to fill in the base name if we can.
+ // If a::b::c is passed in, we need to just look up "c", and then we'll filter the result later.
+ CPlusPlusLanguage::ExtractContextAndIdentifier (name_cstr, context, basename);
+ }
+ }
+
+ if (name_type_mask & eFunctionNameTypeSelector)
+ {
+ if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr))
+ {
+ m_name_type_mask &= ~(eFunctionNameTypeSelector);
+ if (m_name_type_mask == eFunctionNameTypeNone)
+ return;
+ }
+ }
+
+ // Still try and get a basename in case someone specifies a name type mask of
+ // eFunctionNameTypeFull and a name like "A::func"
+ if (basename.empty())
+ {
+ if (name_type_mask & eFunctionNameTypeFull)
+ {
+ CPlusPlusLanguage::MethodName cpp_method (name);
+ basename = cpp_method.GetBasename();
+ if (basename.empty())
+ CPlusPlusLanguage::ExtractContextAndIdentifier (name_cstr, context, basename);
+ }
+ }
+ }
+
+ if (!basename.empty())
+ {
+ // The name supplied was a partial C++ path like "a::count". In this case we want to do a
+ // lookup on the basename "count" and then make sure any matching results contain "a::count"
+ // so that it would match "b::a::count" and "a::count". This is why we set "match_name_after_lookup"
+ // to true
+ m_lookup_name.SetString(basename);
+ m_match_name_after_lookup = true;
+ }
+ else
+ {
+ // The name is already correct, just use the exact name as supplied, and we won't need
+ // to check if any matches contain "name"
+ m_lookup_name = name;
+ m_match_name_after_lookup = false;
+ }
+
+}
+
+void
+Module::LookupInfo::Prune(SymbolContextList &sc_list, size_t start_idx) const
+{
+ if (m_match_name_after_lookup && m_name)
+ {
+ SymbolContext sc;
+ size_t i = start_idx;
+ while (i < sc_list.GetSize())
+ {
+ if (!sc_list.GetContextAtIndex(i, sc))
+ break;
+ ConstString full_name(sc.GetFunctionName());
+ if (full_name && ::strstr(full_name.GetCString(), m_name.GetCString()) == nullptr)
+ {
+ sc_list.RemoveContextAtIndex(i);
+ }
+ else
+ {
+ ++i;
+ }
+ }
+ }
+
+ // If we have only full name matches we might have tried to set breakpoint on "func"
+ // and specified eFunctionNameTypeFull, but we might have found "a::func()",
+ // "a::b::func()", "c::func()", "func()" and "func". Only "func()" and "func" should
+ // end up matching.
+ if (m_name_type_mask == eFunctionNameTypeFull)
+ {
+ SymbolContext sc;
+ size_t i = start_idx;
+ while (i < sc_list.GetSize())
+ {
+ if (!sc_list.GetContextAtIndex(i, sc))
+ break;
+ ConstString full_name(sc.GetFunctionName());
+ CPlusPlusLanguage::MethodName cpp_method(full_name);
+ if (cpp_method.IsValid())
+ {
+ if (cpp_method.GetContext().empty())
+ {
+ if (cpp_method.GetBasename().compare(m_name.GetStringRef()) != 0)
+ {
+ sc_list.RemoveContextAtIndex(i);
+ continue;
+ }
+ }
+ else
+ {
+ std::string qualified_name = cpp_method.GetScopeQualifiedName();
+ if (qualified_name.compare(m_name.GetCString()) != 0)
+ {
+ sc_list.RemoveContextAtIndex(i);
+ continue;
+ }
+ }
+ }
+ ++i;
+ }
+ }
+}
+
+
size_t
Module::FindFunctions (const ConstString &name,
const CompilerDeclContext *parent_decl_ctx,
@@ -759,21 +933,13 @@ Module::FindFunctions (const ConstString &name,
if (name_type_mask & eFunctionNameTypeAuto)
{
- ConstString lookup_name;
- uint32_t lookup_name_type_mask = 0;
- bool match_name_after_lookup = false;
- Module::PrepareForFunctionNameLookup (name,
- name_type_mask,
- eLanguageTypeUnknown, // TODO: add support
- lookup_name,
- lookup_name_type_mask,
- match_name_after_lookup);
-
+ LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
+
if (symbols)
{
- symbols->FindFunctions(lookup_name,
+ symbols->FindFunctions(lookup_info.GetLookupName(),
parent_decl_ctx,
- lookup_name_type_mask,
+ lookup_info.GetNameTypeMask(),
include_inlines,
append,
sc_list);
@@ -783,30 +949,14 @@ Module::FindFunctions (const ConstString &name,
{
Symtab *symtab = symbols->GetSymtab();
if (symtab)
- symtab->FindFunctionSymbols(lookup_name, lookup_name_type_mask, sc_list);
+ symtab->FindFunctionSymbols(lookup_info.GetLookupName(), lookup_info.GetNameTypeMask(), sc_list);
}
}
- if (match_name_after_lookup)
- {
- SymbolContext sc;
- size_t i = old_size;
- while (i<sc_list.GetSize())
- {
- if (sc_list.GetContextAtIndex(i, sc))
- {
- const char *func_name = sc.GetFunctionName().GetCString();
- if (func_name && strstr (func_name, name.GetCString()) == NULL)
- {
- // Remove the current context
- sc_list.RemoveContextAtIndex(i);
- // Don't increment i and continue in the loop
- continue;
- }
- }
- ++i;
- }
- }
+ const size_t new_size = sc_list.GetSize();
+
+ if (old_size < new_size)
+ lookup_info.Prune (sc_list, old_size);
}
else
{
@@ -861,7 +1011,7 @@ Module::FindFunctions (const RegularExpression& regex,
if (num_functions_added_to_sc_list == 0)
{
// No functions were added, just symbols, so we can just append them
- for (size_t i=0; i<num_matches; ++i)
+ for (size_t i = 0; i < num_matches; ++i)
{
sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
SymbolType sym_type = sc.symbol->GetType();
@@ -874,7 +1024,7 @@ Module::FindFunctions (const RegularExpression& regex,
{
typedef std::map<lldb::addr_t, uint32_t> FileAddrToIndexMap;
FileAddrToIndexMap file_addr_to_index;
- for (size_t i=start_size; i<end_functions_added_index; ++i)
+ for (size_t i = start_size; i < end_functions_added_index; ++i)
{
const SymbolContext &sc = sc_list[i];
if (sc.block)
@@ -885,7 +1035,7 @@ Module::FindFunctions (const RegularExpression& regex,
FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();
// Functions were added so we need to merge symbols into any
// existing function symbol contexts
- for (size_t i=start_size; i<num_matches; ++i)
+ for (size_t i = start_size; i < num_matches; ++i)
{
sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
SymbolType sym_type = sc.symbol->GetType();
@@ -916,7 +1066,7 @@ Module::FindAddressesForLine (const lldb::TargetSP target_sp,
AddressResolverFileLine resolver(file, line, true);
resolver.ResolveAddress (filter);
- for (size_t n=0;n<resolver.GetNumberOfAddresses();n++)
+ for (size_t n = 0; n < resolver.GetNumberOfAddresses(); n++)
{
Address addr = resolver.GetAddressRangeAtIndex(n).GetBaseAddress();
Function *f = addr.CalculateSymbolContextFunction();
@@ -933,14 +1083,15 @@ Module::FindTypes_Impl (const SymbolContext& sc,
const CompilerDeclContext *parent_decl_ctx,
bool append,
size_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap& types)
{
Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
- if (sc.module_sp.get() == NULL || sc.module_sp.get() == this)
+ if (!sc.module_sp || sc.module_sp.get() == this)
{
SymbolVendor *symbols = GetSymbolVendor ();
if (symbols)
- return symbols->FindTypes(sc, name, parent_decl_ctx, append, max_matches, types);
+ return symbols->FindTypes(sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
}
return 0;
}
@@ -954,7 +1105,8 @@ Module::FindTypesInNamespace (const SymbolContext& sc,
{
const bool append = true;
TypeMap types_map;
- size_t num_types = FindTypes_Impl(sc, type_name, parent_decl_ctx, append, max_matches, types_map);
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+ size_t num_types = FindTypes_Impl(sc, type_name, parent_decl_ctx, append, max_matches, searched_symbol_files, types_map);
if (num_types > 0)
sc.SortTypeList(types_map, type_list);
return num_types;
@@ -966,18 +1118,19 @@ Module::FindFirstType (const SymbolContext& sc,
bool exact_match)
{
TypeList type_list;
- const size_t num_matches = FindTypes (sc, name, exact_match, 1, type_list);
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+ const size_t num_matches = FindTypes (sc, name, exact_match, 1, searched_symbol_files, type_list);
if (num_matches)
return type_list.GetTypeAtIndex(0);
return TypeSP();
}
-
size_t
Module::FindTypes (const SymbolContext& sc,
const ConstString &name,
bool exact_match,
size_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeList& types)
{
size_t num_matches = 0;
@@ -1000,7 +1153,7 @@ Module::FindTypes (const SymbolContext& sc,
exact_match = true;
}
ConstString type_basename_const_str (type_basename.c_str());
- if (FindTypes_Impl(sc, type_basename_const_str, NULL, append, max_matches, typesmap))
+ if (FindTypes_Impl(sc, type_basename_const_str, nullptr, append, max_matches, searched_symbol_files, typesmap))
{
typesmap.RemoveMismatchedTypes (type_scope, type_basename, type_class, exact_match);
num_matches = typesmap.GetSize();
@@ -1013,13 +1166,13 @@ Module::FindTypes (const SymbolContext& sc,
{
// The "type_name_cstr" will have been modified if we have a valid type class
// prefix (like "struct", "class", "union", "typedef" etc).
- FindTypes_Impl(sc, ConstString(type_name_cstr), NULL, append, max_matches, typesmap);
+ FindTypes_Impl(sc, ConstString(type_name_cstr), nullptr, append, max_matches, searched_symbol_files, typesmap);
typesmap.RemoveMismatchedTypes (type_class);
num_matches = typesmap.GetSize();
}
else
{
- num_matches = FindTypes_Impl(sc, name, NULL, append, max_matches, typesmap);
+ num_matches = FindTypes_Impl(sc, name, nullptr, append, max_matches, searched_symbol_files, typesmap);
}
}
if (num_matches > 0)
@@ -1030,13 +1183,13 @@ Module::FindTypes (const SymbolContext& sc,
SymbolVendor*
Module::GetSymbolVendor (bool can_create, lldb_private::Stream *feedback_strm)
{
- if (m_did_load_symbol_vendor.load() == false)
+ if (!m_did_load_symbol_vendor.load())
{
- Mutex::Locker locker (m_mutex);
- if (m_did_load_symbol_vendor.load() == false && can_create)
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (!m_did_load_symbol_vendor.load() && can_create)
{
ObjectFile *obj_file = GetObjectFile ();
- if (obj_file != NULL)
+ if (obj_file != nullptr)
{
Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
m_symfile_ap.reset(SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
@@ -1079,7 +1232,7 @@ Module::GetSpecificationDescription () const
void
Module::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (level >= eDescriptionLevelFull)
{
@@ -1127,14 +1280,13 @@ Module::ReportError (const char *format, ...)
strm.EOL();
}
Host::SystemLog (Host::eSystemLogError, "%s", strm.GetString().c_str());
-
}
}
bool
Module::FileHasChanged () const
{
- if (m_file_has_changed == false)
+ if (!m_file_has_changed)
m_file_has_changed = (m_file.GetModificationTime() != m_mod_time);
return m_file_has_changed;
}
@@ -1142,7 +1294,7 @@ Module::FileHasChanged () const
void
Module::ReportErrorIfModifyDetected (const char *format, ...)
{
- if (m_first_file_changed_log == false)
+ if (!m_first_file_changed_log)
{
if (FileHasChanged ())
{
@@ -1202,7 +1354,7 @@ Module::ReportWarning (const char *format, ...)
void
Module::LogMessage (Log *log, const char *format, ...)
{
- if (log)
+ if (log != nullptr)
{
StreamString log_message;
GetDescription(&log_message, lldb::eDescriptionLevelFull);
@@ -1218,7 +1370,7 @@ Module::LogMessage (Log *log, const char *format, ...)
void
Module::LogMessageVerboseBacktrace (Log *log, const char *format, ...)
{
- if (log)
+ if (log != nullptr)
{
StreamString log_message;
GetDescription(&log_message, lldb::eDescriptionLevelFull);
@@ -1241,7 +1393,7 @@ Module::LogMessageVerboseBacktrace (Log *log, const char *format, ...)
void
Module::Dump(Stream *s)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
//s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
s->Indent();
s->Printf("Module %s%s%s%s\n",
@@ -1263,14 +1415,13 @@ Module::Dump(Stream *s)
s->IndentLess();
}
-
TypeList*
Module::GetTypeList ()
{
SymbolVendor *symbols = GetSymbolVendor ();
if (symbols)
return &symbols->GetTypeList();
- return NULL;
+ return nullptr;
}
const ConstString &
@@ -1282,10 +1433,10 @@ Module::GetObjectName() const
ObjectFile *
Module::GetObjectFile()
{
- if (m_did_load_objfile.load() == false)
+ if (!m_did_load_objfile.load())
{
- Mutex::Locker locker (m_mutex);
- if (m_did_load_objfile.load() == false)
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (!m_did_load_objfile.load())
{
Timer scoped_timer(__PRETTY_FUNCTION__,
"Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString(""));
@@ -1326,10 +1477,10 @@ SectionList *
Module::GetSectionList()
{
// Populate m_unified_sections_ap with sections from objfile.
- if (m_sections_ap.get() == NULL)
+ if (!m_sections_ap)
{
ObjectFile *obj_file = GetObjectFile();
- if (obj_file)
+ if (obj_file != nullptr)
obj_file->CreateSections(*GetUnifiedSectionList());
}
return m_sections_ap.get();
@@ -1342,7 +1493,7 @@ Module::SectionFileAddressesChanged ()
if (obj_file)
obj_file->SectionFileAddressesChanged ();
SymbolVendor* sym_vendor = GetSymbolVendor();
- if (sym_vendor)
+ if (sym_vendor != nullptr)
sym_vendor->SectionFileAddressesChanged ();
}
@@ -1350,7 +1501,7 @@ SectionList *
Module::GetUnifiedSectionList()
{
// Populate m_unified_sections_ap with sections from objfile.
- if (m_sections_ap.get() == NULL)
+ if (!m_sections_ap)
m_sections_ap.reset(new SectionList());
return m_sections_ap.get();
}
@@ -1369,7 +1520,7 @@ Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symb
if (symtab)
return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
}
- return NULL;
+ return nullptr;
}
void
Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
@@ -1416,7 +1567,6 @@ Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_t
// No need to protect this call using m_mutex all other method calls are
// already thread safe.
-
Timer scoped_timer(__PRETTY_FUNCTION__,
"Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
name.AsCString(),
@@ -1530,7 +1680,7 @@ Module::SetSymbolFileFileSpec (const FileSpec &file)
bool
Module::IsExecutable ()
{
- if (GetObjectFile() == NULL)
+ if (GetObjectFile() == nullptr)
return false;
else
return GetObjectFile()->IsExecutable();
@@ -1543,7 +1693,7 @@ Module::IsLoadedInTarget (Target *target)
if (obj_file)
{
SectionList *sections = GetSectionList();
- if (sections != NULL)
+ if (sections != nullptr)
{
size_t num_sections = sections->GetSize();
for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++)
@@ -1589,15 +1739,14 @@ Module::LoadScriptingResourceInTarget (Target *target, Error& error, Stream* fee
FileSpecList file_specs = platform_sp->LocateExecutableScriptingResources (target,
*this,
feedback_stream);
-
-
+
const uint32_t num_specs = file_specs.GetSize();
if (num_specs)
{
ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
if (script_interpreter)
{
- for (uint32_t i=0; i<num_specs; ++i)
+ for (uint32_t i = 0; i < num_specs; ++i)
{
FileSpec scripting_fspec (file_specs.GetFileSpecAtIndex(i));
if (scripting_fspec && scripting_fspec.Exists())
@@ -1651,7 +1800,7 @@ bool
Module::SetLoadAddress (Target &target, lldb::addr_t value, bool value_is_offset, bool &changed)
{
ObjectFile *object_file = GetObjectFile();
- if (object_file)
+ if (object_file != nullptr)
{
changed = object_file->SetLoadAddress(target, value, value_is_offset);
return true;
@@ -1672,10 +1821,7 @@ Module::MatchesModuleSpec (const ModuleSpec &module_ref)
if (uuid.IsValid())
{
// If the UUID matches, then nothing more needs to match...
- if (uuid == GetUUID())
- return true;
- else
- return false;
+ return (uuid == GetUUID());
}
const FileSpec &file_spec = module_ref.GetFileSpec();
@@ -1712,14 +1858,14 @@ Module::MatchesModuleSpec (const ModuleSpec &module_ref)
bool
Module::FindSourceFile (const FileSpec &orig_spec, FileSpec &new_spec) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_source_mappings.FindFile (orig_spec, new_spec);
}
bool
Module::RemapSourceFile (const char *path, std::string &new_path) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_source_mappings.RemapPath(path, new_path);
}
@@ -1730,121 +1876,14 @@ Module::GetVersion (uint32_t *versions, uint32_t num_versions)
if (obj_file)
return obj_file->GetVersion (versions, num_versions);
- if (versions && num_versions)
+ if (versions != nullptr && num_versions != 0)
{
- for (uint32_t i=0; i<num_versions; ++i)
+ for (uint32_t i = 0; i < num_versions; ++i)
versions[i] = LLDB_INVALID_MODULE_VERSION;
}
return 0;
}
-void
-Module::PrepareForFunctionNameLookup (const ConstString &name,
- uint32_t name_type_mask,
- LanguageType language,
- ConstString &lookup_name,
- uint32_t &lookup_name_type_mask,
- bool &match_name_after_lookup)
-{
- const char *name_cstr = name.GetCString();
- lookup_name_type_mask = eFunctionNameTypeNone;
- match_name_after_lookup = false;
-
- llvm::StringRef basename;
- llvm::StringRef context;
-
- if (name_type_mask & eFunctionNameTypeAuto)
- {
- if (CPlusPlusLanguage::IsCPPMangledName (name_cstr))
- lookup_name_type_mask = eFunctionNameTypeFull;
- else if ((language == eLanguageTypeUnknown ||
- Language::LanguageIsObjC(language)) &&
- ObjCLanguage::IsPossibleObjCMethodName (name_cstr))
- lookup_name_type_mask = eFunctionNameTypeFull;
- else if (Language::LanguageIsC(language))
- {
- lookup_name_type_mask = eFunctionNameTypeFull;
- }
- else
- {
- if ((language == eLanguageTypeUnknown ||
- Language::LanguageIsObjC(language)) &&
- ObjCLanguage::IsPossibleObjCSelector(name_cstr))
- lookup_name_type_mask |= eFunctionNameTypeSelector;
-
- CPlusPlusLanguage::MethodName cpp_method (name);
- basename = cpp_method.GetBasename();
- if (basename.empty())
- {
- if (CPlusPlusLanguage::ExtractContextAndIdentifier (name_cstr, context, basename))
- lookup_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
- else
- lookup_name_type_mask |= eFunctionNameTypeFull;
- }
- else
- {
- lookup_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
- }
- }
- }
- else
- {
- lookup_name_type_mask = name_type_mask;
- if (lookup_name_type_mask & eFunctionNameTypeMethod || name_type_mask & eFunctionNameTypeBase)
- {
- // If they've asked for a CPP method or function name and it can't be that, we don't
- // even need to search for CPP methods or names.
- CPlusPlusLanguage::MethodName cpp_method (name);
- if (cpp_method.IsValid())
- {
- basename = cpp_method.GetBasename();
-
- if (!cpp_method.GetQualifiers().empty())
- {
- // There is a "const" or other qualifier following the end of the function parens,
- // this can't be a eFunctionNameTypeBase
- lookup_name_type_mask &= ~(eFunctionNameTypeBase);
- if (lookup_name_type_mask == eFunctionNameTypeNone)
- return;
- }
- }
- else
- {
- // If the CPP method parser didn't manage to chop this up, try to fill in the base name if we can.
- // If a::b::c is passed in, we need to just look up "c", and then we'll filter the result later.
- CPlusPlusLanguage::ExtractContextAndIdentifier (name_cstr, context, basename);
- }
- }
-
- if (lookup_name_type_mask & eFunctionNameTypeSelector)
- {
- if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr))
- {
- lookup_name_type_mask &= ~(eFunctionNameTypeSelector);
- if (lookup_name_type_mask == eFunctionNameTypeNone)
- return;
- }
- }
- }
-
- if (!basename.empty())
- {
- // The name supplied was a partial C++ path like "a::count". In this case we want to do a
- // lookup on the basename "count" and then make sure any matching results contain "a::count"
- // so that it would match "b::a::count" and "a::count". This is why we set "match_name_after_lookup"
- // to true
- lookup_name.SetString(basename);
- match_name_after_lookup = true;
- }
- else
- {
- // The name is already correct, just use the exact name as supplied, and we won't need
- // to check if any matches contain "name"
- lookup_name = name;
- match_name_after_lookup = false;
- }
-}
-
ModuleSP
Module::CreateJITModule (const lldb::ObjectFileJITDelegateSP &delegate_sp)
{
diff --git a/source/Core/ModuleList.cpp b/source/Core/ModuleList.cpp
index 75b2ca11103a..bfd53e7d1c2c 100644
--- a/source/Core/ModuleList.cpp
+++ b/source/Core/ModuleList.cpp
@@ -10,10 +10,9 @@
#include "lldb/Core/ModuleList.h"
// C Includes
-#include <stdint.h>
-
// C++ Includes
-#include <mutex> // std::once
+#include <cstdint>
+#include <mutex>
// Other libraries and framework includes
// Project includes
@@ -23,44 +22,27 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/VariableList.h"
using namespace lldb;
using namespace lldb_private;
-//----------------------------------------------------------------------
-// ModuleList constructor
-//----------------------------------------------------------------------
-ModuleList::ModuleList() :
- m_modules(),
- m_modules_mutex (Mutex::eMutexTypeRecursive),
- m_notifier(NULL)
+ModuleList::ModuleList() : m_modules(), m_modules_mutex(), m_notifier(nullptr)
{
}
-//----------------------------------------------------------------------
-// Copy constructor
-//----------------------------------------------------------------------
-ModuleList::ModuleList(const ModuleList& rhs) :
- m_modules(),
- m_modules_mutex (Mutex::eMutexTypeRecursive),
- m_notifier(NULL)
+ModuleList::ModuleList(const ModuleList &rhs) : m_modules(), m_modules_mutex(), m_notifier(nullptr)
{
- Mutex::Locker lhs_locker(m_modules_mutex);
- Mutex::Locker rhs_locker(rhs.m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
m_modules = rhs.m_modules;
}
-ModuleList::ModuleList (ModuleList::Notifier* notifier) :
- m_modules(),
- m_modules_mutex (Mutex::eMutexTypeRecursive),
- m_notifier(notifier)
+ModuleList::ModuleList(ModuleList::Notifier *notifier) : m_modules(), m_modules_mutex(), m_notifier(notifier)
{
}
-//----------------------------------------------------------------------
-// Assignment operator
-//----------------------------------------------------------------------
const ModuleList&
ModuleList::operator= (const ModuleList& rhs)
{
@@ -78,33 +60,28 @@ ModuleList::operator= (const ModuleList& rhs)
// avoids priority inversion.
if (uintptr_t(this) > uintptr_t(&rhs))
{
- Mutex::Locker lhs_locker(m_modules_mutex);
- Mutex::Locker rhs_locker(rhs.m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
m_modules = rhs.m_modules;
}
else
{
- Mutex::Locker rhs_locker(rhs.m_modules_mutex);
- Mutex::Locker lhs_locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
m_modules = rhs.m_modules;
}
}
return *this;
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-ModuleList::~ModuleList()
-{
-}
+ModuleList::~ModuleList() = default;
void
ModuleList::AppendImpl (const ModuleSP &module_sp, bool use_notifier)
{
if (module_sp)
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
m_modules.push_back(module_sp);
if (use_notifier && m_notifier)
m_notifier->ModuleAdded(*this, module_sp);
@@ -122,7 +99,7 @@ ModuleList::ReplaceEquivalent (const ModuleSP &module_sp)
{
if (module_sp)
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
// First remove any equivalent modules. Equivalent modules are modules
// whose path, platform path and architecture match.
@@ -148,7 +125,7 @@ ModuleList::AppendIfNeeded (const ModuleSP &module_sp)
{
if (module_sp)
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -186,7 +163,7 @@ ModuleList::RemoveImpl (const ModuleSP &module_sp, bool use_notifier)
{
if (module_sp)
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -234,7 +211,7 @@ ModuleList::RemoveIfOrphaned (const Module *module_ptr)
{
if (module_ptr)
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -256,16 +233,16 @@ ModuleList::RemoveIfOrphaned (const Module *module_ptr)
size_t
ModuleList::RemoveOrphans (bool mandatory)
{
- Mutex::Locker locker;
-
+ std::unique_lock<std::recursive_mutex> lock(m_modules_mutex, std::defer_lock);
+
if (mandatory)
{
- locker.Lock (m_modules_mutex);
+ lock.lock();
}
else
{
// Not mandatory, remove orphans if we can get the mutex
- if (!locker.TryLock(m_modules_mutex))
+ if (!lock.try_lock())
return 0;
}
collection::iterator pos = m_modules.begin();
@@ -288,7 +265,7 @@ ModuleList::RemoveOrphans (bool mandatory)
size_t
ModuleList::Remove (ModuleList &module_list)
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
size_t num_removed = 0;
collection::iterator pos, end = module_list.m_modules.end();
for (pos = module_list.m_modules.begin(); pos != end; ++pos)
@@ -315,7 +292,7 @@ ModuleList::Destroy()
void
ModuleList::ClearImpl (bool use_notifier)
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
if (use_notifier && m_notifier)
m_notifier->WillClearList(*this);
m_modules.clear();
@@ -324,7 +301,7 @@ ModuleList::ClearImpl (bool use_notifier)
Module*
ModuleList::GetModulePointerAtIndex (size_t idx) const
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
return GetModulePointerAtIndexUnlocked(idx);
}
@@ -333,13 +310,13 @@ ModuleList::GetModulePointerAtIndexUnlocked (size_t idx) const
{
if (idx < m_modules.size())
return m_modules[idx].get();
- return NULL;
+ return nullptr;
}
ModuleSP
ModuleList::GetModuleAtIndex(size_t idx) const
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
return GetModuleAtIndexUnlocked(idx);
}
@@ -367,57 +344,33 @@ ModuleList::FindFunctions (const ConstString &name,
if (name_type_mask & eFunctionNameTypeAuto)
{
- ConstString lookup_name;
- uint32_t lookup_name_type_mask = 0;
- bool match_name_after_lookup = false;
- Module::PrepareForFunctionNameLookup (name, name_type_mask,
- eLanguageTypeUnknown, // TODO: add support
- lookup_name,
- lookup_name_type_mask,
- match_name_after_lookup);
-
- Mutex::Locker locker(m_modules_mutex);
+ Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
+
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
- (*pos)->FindFunctions (lookup_name,
- NULL,
- lookup_name_type_mask,
- include_symbols,
- include_inlines,
- true,
- sc_list);
+ (*pos)->FindFunctions(lookup_info.GetLookupName(),
+ nullptr,
+ lookup_info.GetNameTypeMask(),
+ include_symbols,
+ include_inlines,
+ true,
+ sc_list);
}
- if (match_name_after_lookup)
- {
- SymbolContext sc;
- size_t i = old_size;
- while (i<sc_list.GetSize())
- {
- if (sc_list.GetContextAtIndex(i, sc))
- {
- const char *func_name = sc.GetFunctionName().GetCString();
- if (func_name && strstr (func_name, name.GetCString()) == NULL)
- {
- // Remove the current context
- sc_list.RemoveContextAtIndex(i);
- // Don't increment i and continue in the loop
- continue;
- }
- }
- ++i;
- }
- }
+ const size_t new_size = sc_list.GetSize();
+ if (old_size < new_size)
+ lookup_info.Prune (sc_list, old_size);
}
else
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
- (*pos)->FindFunctions (name, NULL, name_type_mask, include_symbols, include_inlines, true, sc_list);
+ (*pos)->FindFunctions(name, nullptr, name_type_mask, include_symbols, include_inlines, true, sc_list);
}
}
return sc_list.GetSize() - old_size;
@@ -432,49 +385,26 @@ ModuleList::FindFunctionSymbols (const ConstString &name,
if (name_type_mask & eFunctionNameTypeAuto)
{
- ConstString lookup_name;
- uint32_t lookup_name_type_mask = 0;
- bool match_name_after_lookup = false;
- Module::PrepareForFunctionNameLookup (name, name_type_mask,
- eLanguageTypeUnknown, // TODO: add support
- lookup_name,
- lookup_name_type_mask,
- match_name_after_lookup);
-
- Mutex::Locker locker(m_modules_mutex);
+ Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
+
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
- (*pos)->FindFunctionSymbols (lookup_name,
- lookup_name_type_mask,
- sc_list);
- }
-
- if (match_name_after_lookup)
- {
- SymbolContext sc;
- size_t i = old_size;
- while (i<sc_list.GetSize())
- {
- if (sc_list.GetContextAtIndex(i, sc))
- {
- const char *func_name = sc.GetFunctionName().GetCString();
- if (func_name && strstr (func_name, name.GetCString()) == NULL)
- {
- // Remove the current context
- sc_list.RemoveContextAtIndex(i);
- // Don't increment i and continue in the loop
- continue;
- }
- }
- ++i;
- }
+ (*pos)->FindFunctionSymbols (lookup_info.GetLookupName(),
+ lookup_info.GetNameTypeMask(),
+ sc_list);
}
+
+ const size_t new_size = sc_list.GetSize();
+
+ if (old_size < new_size)
+ lookup_info.Prune (sc_list, old_size);
}
else
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -485,7 +415,6 @@ ModuleList::FindFunctionSymbols (const ConstString &name,
return sc_list.GetSize() - old_size;
}
-
size_t
ModuleList::FindFunctions(const RegularExpression &name,
bool include_symbols,
@@ -495,7 +424,7 @@ ModuleList::FindFunctions(const RegularExpression &name,
{
const size_t old_size = sc_list.GetSize();
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -512,8 +441,8 @@ ModuleList::FindCompileUnits (const FileSpec &path,
{
if (!append)
sc_list.Clear();
-
- Mutex::Locker locker(m_modules_mutex);
+
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -530,16 +459,15 @@ ModuleList::FindGlobalVariables (const ConstString &name,
VariableList& variable_list) const
{
size_t initial_size = variable_list.GetSize();
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
- (*pos)->FindGlobalVariables (name, NULL, append, max_matches, variable_list);
+ (*pos)->FindGlobalVariables(name, nullptr, append, max_matches, variable_list);
}
return variable_list.GetSize() - initial_size;
}
-
size_t
ModuleList::FindGlobalVariables (const RegularExpression& regex,
bool append,
@@ -547,7 +475,7 @@ ModuleList::FindGlobalVariables (const RegularExpression& regex,
VariableList& variable_list) const
{
size_t initial_size = variable_list.GetSize();
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -556,14 +484,13 @@ ModuleList::FindGlobalVariables (const RegularExpression& regex,
return variable_list.GetSize() - initial_size;
}
-
size_t
ModuleList::FindSymbolsWithNameAndType (const ConstString &name,
SymbolType symbol_type,
SymbolContextList &sc_list,
bool append) const
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
if (!append)
sc_list.Clear();
size_t initial_size = sc_list.GetSize();
@@ -580,7 +507,7 @@ ModuleList::FindSymbolsMatchingRegExAndType (const RegularExpression &regex,
SymbolContextList &sc_list,
bool append) const
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
if (!append)
sc_list.Clear();
size_t initial_size = sc_list.GetSize();
@@ -596,7 +523,7 @@ ModuleList::FindModules (const ModuleSpec &module_spec, ModuleList& matching_mod
{
size_t existing_matches = matching_module_list.GetSize();
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -614,7 +541,7 @@ ModuleList::FindModule (const Module *module_ptr) const
// Scope for "locker"
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
@@ -627,7 +554,6 @@ ModuleList::FindModule (const Module *module_ptr) const
}
}
return module_sp;
-
}
ModuleSP
@@ -637,7 +563,7 @@ ModuleList::FindModule (const UUID &uuid) const
if (uuid.IsValid())
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
@@ -652,11 +578,10 @@ ModuleList::FindModule (const UUID &uuid) const
return module_sp;
}
-
size_t
-ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool name_is_fully_qualified, size_t max_matches, TypeList& types) const
+ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool name_is_fully_qualified, size_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeList& types) const
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
size_t total_matches = 0;
collection::const_iterator pos, end = m_modules.end();
@@ -668,7 +593,7 @@ ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool na
{
if (sc.module_sp.get() == (*pos).get())
{
- total_matches += (*pos)->FindTypes (sc, name, name_is_fully_qualified, max_matches, types);
+ total_matches += (*pos)->FindTypes (sc, name, name_is_fully_qualified, max_matches, searched_symbol_files, types);
if (total_matches >= max_matches)
break;
@@ -683,9 +608,9 @@ ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool na
{
// Search the module if the module is not equal to the one in the symbol
// context "sc". If "sc" contains a empty module shared pointer, then
- // the comparison will always be true (valid_module_ptr != NULL).
+ // the comparison will always be true (valid_module_ptr != nullptr).
if (sc.module_sp.get() != (*pos).get())
- total_matches += (*pos)->FindTypes (world_sc, name, name_is_fully_qualified, max_matches, types);
+ total_matches += (*pos)->FindTypes (world_sc, name, name_is_fully_qualified, max_matches, searched_symbol_files, types);
if (total_matches >= max_matches)
break;
@@ -698,7 +623,7 @@ ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool na
bool
ModuleList::FindSourceFile (const FileSpec &orig_spec, FileSpec &new_spec) const
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -714,7 +639,7 @@ ModuleList::FindAddressesForLine (const lldb::TargetSP target_sp,
Function *function,
std::vector<Address> &output_local, std::vector<Address> &output_extern)
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -726,7 +651,7 @@ ModuleSP
ModuleList::FindFirstModule (const ModuleSpec &module_spec) const
{
ModuleSP module_sp;
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -743,21 +668,20 @@ ModuleList::GetSize() const
{
size_t size = 0;
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
size = m_modules.size();
}
return size;
}
-
void
ModuleList::Dump(Stream *s) const
{
-// s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
-// s.Indent();
-// s << "ModuleList\n";
+ // s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
+ // s.Indent();
+ // s << "ModuleList\n";
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -768,9 +692,9 @@ ModuleList::Dump(Stream *s) const
void
ModuleList::LogUUIDAndPaths (Log *log, const char *prefix_cstr)
{
- if (log)
- {
- Mutex::Locker locker(m_modules_mutex);
+ if (log != nullptr)
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, begin = m_modules.begin(), end = m_modules.end();
for (pos = begin; pos != end; ++pos)
{
@@ -789,7 +713,7 @@ ModuleList::LogUUIDAndPaths (Log *log, const char *prefix_cstr)
bool
ModuleList::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) const
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -814,7 +738,7 @@ ModuleList::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t res
}
else
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -830,14 +754,11 @@ ModuleList::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t res
}
uint32_t
-ModuleList::ResolveSymbolContextForFilePath
-(
- const char *file_path,
- uint32_t line,
- bool check_inlines,
- uint32_t resolve_scope,
- SymbolContextList& sc_list
-) const
+ModuleList::ResolveSymbolContextForFilePath(const char *file_path,
+ uint32_t line,
+ bool check_inlines,
+ uint32_t resolve_scope,
+ SymbolContextList& sc_list) const
{
FileSpec file_spec(file_path, false);
return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
@@ -846,7 +767,7 @@ ModuleList::ResolveSymbolContextForFilePath
uint32_t
ModuleList::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) const
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
@@ -861,7 +782,7 @@ ModuleList::GetIndexForModule (const Module *module) const
{
if (module)
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos;
collection::const_iterator begin = m_modules.begin();
collection::const_iterator end = m_modules.end();
@@ -877,13 +798,13 @@ ModuleList::GetIndexForModule (const Module *module) const
static ModuleList &
GetSharedModuleList ()
{
- static ModuleList *g_shared_module_list = NULL;
+ static ModuleList *g_shared_module_list = nullptr;
static std::once_flag g_once_flag;
std::call_once(g_once_flag, [](){
// NOTE: Intentionally leak the module list so a program doesn't have to
// cleanup all modules and object files as it exits. This just wastes time
// doing a bunch of cleanup that isn't required.
- if (g_shared_module_list == NULL)
+ if (g_shared_module_list == nullptr)
g_shared_module_list = new ModuleList(); // <--- Intentional leak!!!
});
return *g_shared_module_list;
@@ -895,7 +816,7 @@ ModuleList::ModuleIsInCache (const Module *module_ptr)
if (module_ptr)
{
ModuleList &shared_module_list = GetSharedModuleList ();
- return shared_module_list.FindModule (module_ptr).get() != NULL;
+ return shared_module_list.FindModule(module_ptr).get() != nullptr;
}
return false;
}
@@ -913,18 +834,15 @@ ModuleList::RemoveOrphanSharedModules (bool mandatory)
}
Error
-ModuleList::GetSharedModule
-(
- const ModuleSpec &module_spec,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr,
- bool always_create
-)
+ModuleList::GetSharedModule(const ModuleSpec &module_spec,
+ ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr,
+ bool always_create)
{
ModuleList &shared_module_list = GetSharedModuleList ();
- Mutex::Locker locker(shared_module_list.m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(shared_module_list.m_modules_mutex);
char path[PATH_MAX];
Error error;
@@ -943,7 +861,7 @@ ModuleList::GetSharedModule
// Make sure no one else can try and get or create a module while this
// function is actively working on it by doing an extra lock on the
// global mutex list.
- if (always_create == false)
+ if (!always_create)
{
ModuleList matching_module_list;
const size_t num_matching_modules = shared_module_list.FindModules (module_spec, matching_module_list);
@@ -956,11 +874,11 @@ ModuleList::GetSharedModule
// Make sure the file for the module hasn't been modified
if (module_sp->FileHasChanged())
{
- if (old_module_sp_ptr && !old_module_sp_ptr->get())
+ if (old_module_sp_ptr && !*old_module_sp_ptr)
*old_module_sp_ptr = module_sp;
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_MODULES));
- if (log)
+ if (log != nullptr)
log->Printf("module changed: %p, removing from global module list",
static_cast<void*>(module_sp.get()));
@@ -1104,7 +1022,6 @@ ModuleList::GetSharedModule
return error;
}
-
// Make sure no one else can try and get or create a module while this
// function is actively working on it by doing an extra lock on the
// global mutex list.
@@ -1119,7 +1036,7 @@ ModuleList::GetSharedModule
// If we didn't have a UUID in mind when looking for the object file,
// then we should make sure the modification time hasn't changed!
- if (platform_module_spec.GetUUIDPtr() == NULL)
+ if (platform_module_spec.GetUUIDPtr() == nullptr)
{
TimeValue file_spec_mod_time(located_binary_modulespec.GetFileSpec().GetModificationTime());
if (file_spec_mod_time.IsValid())
@@ -1135,7 +1052,7 @@ ModuleList::GetSharedModule
}
}
- if (module_sp.get() == NULL)
+ if (!module_sp)
{
module_sp.reset (new Module (platform_module_spec));
// Make sure there are a module and an object file since we can specify
@@ -1204,7 +1121,7 @@ ModuleList::LoadScriptingResourcesInTarget (Target *target,
{
if (!target)
return false;
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
for (auto module : m_modules)
{
Error error;
@@ -1225,13 +1142,13 @@ ModuleList::LoadScriptingResourcesInTarget (Target *target,
}
}
}
- return errors.size() == 0;
+ return errors.empty();
}
void
ModuleList::ForEach (std::function <bool (const ModuleSP &module_sp)> const &callback) const
{
- Mutex::Locker locker(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
for (const auto &module : m_modules)
{
// If the callback returns false, then stop iterating and break out
diff --git a/source/Core/Opcode.cpp b/source/Core/Opcode.cpp
index 89eea2624cec..e36727eaa313 100644
--- a/source/Core/Opcode.cpp
+++ b/source/Core/Opcode.cpp
@@ -13,6 +13,7 @@
// C++ Includes
// Other libraries and framework includes
#include "llvm/ADT/Triple.h"
+
// Project includes
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -20,11 +21,9 @@
#include "lldb/Core/Stream.h"
#include "lldb/Host/Endian.h"
-
using namespace lldb;
using namespace lldb_private;
-
int
Opcode::Dump (Stream *s, uint32_t min_byte_width)
{
@@ -50,13 +49,11 @@ Opcode::Dump (Stream *s, uint32_t min_byte_width)
break;
case Opcode::eTypeBytes:
+ for (uint32_t i = 0; i < m_data.inst.length; ++i)
{
- for (uint32_t i=0; i<m_data.inst.length; ++i)
- {
- if (i > 0)
- bytes_written += s->PutChar (' ');
- bytes_written += s->Printf ("%2.2x", m_data.inst.bytes[i]);
- }
+ if (i > 0)
+ bytes_written += s->PutChar (' ');
+ bytes_written += s->Printf ("%2.2x", m_data.inst.bytes[i]);
}
break;
}
@@ -94,7 +91,7 @@ Opcode::GetData (DataExtractor &data) const
{
uint32_t byte_size = GetByteSize ();
uint8_t swap_buf[8];
- const void *buf = NULL;
+ const void *buf = nullptr;
if (byte_size > 0)
{
@@ -148,7 +145,7 @@ Opcode::GetData (DataExtractor &data) const
}
}
}
- if (buf)
+ if (buf != nullptr)
{
DataBufferSP buffer_sp;
@@ -160,6 +157,3 @@ Opcode::GetData (DataExtractor &data) const
data.Clear();
return 0;
}
-
-
-
diff --git a/source/Core/PluginManager.cpp b/source/Core/PluginManager.cpp
index a90b57678b7a..500b08b73e9e 100644
--- a/source/Core/PluginManager.cpp
+++ b/source/Core/PluginManager.cpp
@@ -9,22 +9,25 @@
#include "lldb/Core/PluginManager.h"
-#include <limits.h>
-
+// C Includes
+// C++ Includes
+#include <climits>
+#include <mutex>
#include <string>
#include <vector>
+// Other libraries and framework includes
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DynamicLibrary.h"
+
+// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Interpreter/OptionValueProperties.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/DynamicLibrary.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -35,9 +38,8 @@ enum PluginAction
ePluginGetInstanceAtIndex
};
-
-typedef bool (*PluginInitCallback) (void);
-typedef void (*PluginTermCallback) (void);
+typedef bool (*PluginInitCallback)();
+typedef void (*PluginTermCallback)();
struct PluginInfo
{
@@ -53,10 +55,10 @@ struct PluginInfo
typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
-static Mutex &
-GetPluginMapMutex ()
+static std::recursive_mutex &
+GetPluginMapMutex()
{
- static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_plugin_map_mutex;
return g_plugin_map_mutex;
}
@@ -70,7 +72,7 @@ GetPluginMap ()
static bool
PluginIsLoaded (const FileSpec &plugin_file_spec)
{
- Mutex::Locker locker (GetPluginMapMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
PluginTerminateMap &plugin_map = GetPluginMap ();
return plugin_map.find (plugin_file_spec) != plugin_map.end();
}
@@ -78,7 +80,7 @@ PluginIsLoaded (const FileSpec &plugin_file_spec)
static void
SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
{
- Mutex::Locker locker (GetPluginMapMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
PluginTerminateMap &plugin_map = GetPluginMap ();
assert (plugin_map.find (plugin_file_spec) == plugin_map.end());
plugin_map[plugin_file_spec] = plugin_info;
@@ -92,12 +94,9 @@ CastToFPtr (void *VPtr)
}
static FileSpec::EnumerateDirectoryResult
-LoadPluginCallback
-(
- void *baton,
- FileSpec::FileType file_type,
- const FileSpec &file_spec
-)
+LoadPluginCallback(void *baton,
+ FileSpec::FileType file_type,
+ const FileSpec &file_spec)
{
// PluginManager *plugin_manager = (PluginManager *)baton;
Error error;
@@ -134,7 +133,7 @@ LoadPluginCallback
if (success)
{
- // It is ok for the "LLDBPluginTerminate" symbol to be NULL
+ // It is ok for the "LLDBPluginTerminate" symbol to be nullptr
plugin_info.plugin_term_callback =
CastToFPtr<PluginTermCallback>(plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
}
@@ -170,7 +169,6 @@ LoadPluginCallback
return FileSpec::eEnumerateDirectoryResultNext;
}
-
void
PluginManager::Initialize ()
{
@@ -184,12 +182,12 @@ PluginManager::Initialize ()
{
if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
{
- FileSpec::EnumerateDirectory (dir_path,
- find_directories,
- find_files,
- find_other,
- LoadPluginCallback,
- NULL);
+ FileSpec::EnumerateDirectory(dir_path,
+ find_directories,
+ find_files,
+ find_other,
+ LoadPluginCallback,
+ nullptr);
}
}
@@ -197,12 +195,12 @@ PluginManager::Initialize ()
{
if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
{
- FileSpec::EnumerateDirectory (dir_path,
- find_directories,
- find_files,
- find_other,
- LoadPluginCallback,
- NULL);
+ FileSpec::EnumerateDirectory(dir_path,
+ find_directories,
+ find_files,
+ find_other,
+ LoadPluginCallback,
+ nullptr);
}
}
#endif
@@ -211,14 +209,14 @@ PluginManager::Initialize ()
void
PluginManager::Terminate ()
{
- Mutex::Locker locker (GetPluginMapMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
PluginTerminateMap &plugin_map = GetPluginMap ();
PluginTerminateMap::const_iterator pos, end = plugin_map.end();
for (pos = plugin_map.begin(); pos != end; ++pos)
{
// Call the plug-in "void LLDBPluginTerminate (void)" function if there
- // is one (if the symbol was not NULL).
+ // is one (if the symbol was not nullptr).
if (pos->second.library.isValid())
{
if (pos->second.plugin_term_callback)
@@ -228,16 +226,14 @@ PluginManager::Terminate ()
plugin_map.clear();
}
-
#pragma mark ABI
-
struct ABIInstance
{
ABIInstance() :
name(),
description(),
- create_callback(NULL)
+ create_callback(nullptr)
{
}
@@ -248,10 +244,10 @@ struct ABIInstance
typedef std::vector<ABIInstance> ABIInstances;
-static Mutex &
-GetABIInstancesMutex ()
+static std::recursive_mutex &
+GetABIInstancesMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -263,12 +259,9 @@ GetABIInstances ()
}
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- ABICreateInstance create_callback
-)
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ ABICreateInstance create_callback)
{
if (create_callback)
{
@@ -278,7 +271,7 @@ PluginManager::RegisterPlugin
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
- Mutex::Locker locker (GetABIInstancesMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
GetABIInstances ().push_back (instance);
return true;
}
@@ -290,7 +283,7 @@ PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetABIInstancesMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
ABIInstances &instances = GetABIInstances ();
ABIInstances::iterator pos, end = instances.end();
@@ -309,11 +302,11 @@ PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
ABICreateInstance
PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetABIInstancesMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
ABIInstances &instances = GetABIInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
ABICreateInstance
@@ -321,7 +314,7 @@ PluginManager::GetABICreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
- Mutex::Locker locker (GetABIInstancesMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
ABIInstances &instances = GetABIInstances ();
ABIInstances::iterator pos, end = instances.end();
@@ -331,19 +324,17 @@ PluginManager::GetABICreateCallbackForPluginName (const ConstString &name)
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
-
#pragma mark Disassembler
-
struct DisassemblerInstance
{
DisassemblerInstance() :
name(),
description(),
- create_callback(NULL)
+ create_callback(nullptr)
{
}
@@ -354,10 +345,10 @@ struct DisassemblerInstance
typedef std::vector<DisassemblerInstance> DisassemblerInstances;
-static Mutex &
-GetDisassemblerMutex ()
+static std::recursive_mutex &
+GetDisassemblerMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -369,12 +360,9 @@ GetDisassemblerInstances ()
}
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- DisassemblerCreateInstance create_callback
-)
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ DisassemblerCreateInstance create_callback)
{
if (create_callback)
{
@@ -384,7 +372,7 @@ PluginManager::RegisterPlugin
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
- Mutex::Locker locker (GetDisassemblerMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
GetDisassemblerInstances ().push_back (instance);
return true;
}
@@ -396,7 +384,7 @@ PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetDisassemblerMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
DisassemblerInstances &instances = GetDisassemblerInstances ();
DisassemblerInstances::iterator pos, end = instances.end();
@@ -415,11 +403,11 @@ PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
DisassemblerCreateInstance
PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetDisassemblerMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
DisassemblerInstances &instances = GetDisassemblerInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
DisassemblerCreateInstance
@@ -427,7 +415,7 @@ PluginManager::GetDisassemblerCreateCallbackForPluginName (const ConstString &na
{
if (name)
{
- Mutex::Locker locker (GetDisassemblerMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
DisassemblerInstances &instances = GetDisassemblerInstances ();
DisassemblerInstances::iterator pos, end = instances.end();
@@ -437,21 +425,18 @@ PluginManager::GetDisassemblerCreateCallbackForPluginName (const ConstString &na
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
-
-
#pragma mark DynamicLoader
-
struct DynamicLoaderInstance
{
DynamicLoaderInstance() :
name(),
description(),
- create_callback(NULL),
- debugger_init_callback (NULL)
+ create_callback(nullptr),
+ debugger_init_callback(nullptr)
{
}
@@ -463,11 +448,10 @@ struct DynamicLoaderInstance
typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
-
-static Mutex &
-GetDynamicLoaderMutex ()
+static std::recursive_mutex &
+GetDynamicLoaderMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -478,15 +462,11 @@ GetDynamicLoaderInstances ()
return g_instances;
}
-
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- DynamicLoaderCreateInstance create_callback,
- DebuggerInitializeCallback debugger_init_callback
-)
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ DynamicLoaderCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback)
{
if (create_callback)
{
@@ -497,7 +477,7 @@ PluginManager::RegisterPlugin
instance.description = description;
instance.create_callback = create_callback;
instance.debugger_init_callback = debugger_init_callback;
- Mutex::Locker locker (GetDynamicLoaderMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
GetDynamicLoaderInstances ().push_back (instance);
}
return false;
@@ -508,7 +488,7 @@ PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetDynamicLoaderMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
DynamicLoaderInstances::iterator pos, end = instances.end();
@@ -527,11 +507,11 @@ PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
DynamicLoaderCreateInstance
PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetDynamicLoaderMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
DynamicLoaderCreateInstance
@@ -539,7 +519,7 @@ PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const ConstString &n
{
if (name)
{
- Mutex::Locker locker (GetDynamicLoaderMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
DynamicLoaderInstances::iterator pos, end = instances.end();
@@ -549,19 +529,18 @@ PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const ConstString &n
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
#pragma mark JITLoader
-
struct JITLoaderInstance
{
JITLoaderInstance() :
name(),
description(),
- create_callback(NULL),
- debugger_init_callback (NULL)
+ create_callback(nullptr),
+ debugger_init_callback(nullptr)
{
}
@@ -573,11 +552,10 @@ struct JITLoaderInstance
typedef std::vector<JITLoaderInstance> JITLoaderInstances;
-
-static Mutex &
-GetJITLoaderMutex ()
+static std::recursive_mutex &
+GetJITLoaderMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -588,15 +566,11 @@ GetJITLoaderInstances ()
return g_instances;
}
-
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- JITLoaderCreateInstance create_callback,
- DebuggerInitializeCallback debugger_init_callback
-)
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ JITLoaderCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback)
{
if (create_callback)
{
@@ -607,7 +581,7 @@ PluginManager::RegisterPlugin
instance.description = description;
instance.create_callback = create_callback;
instance.debugger_init_callback = debugger_init_callback;
- Mutex::Locker locker (GetJITLoaderMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
GetJITLoaderInstances ().push_back (instance);
}
return false;
@@ -618,7 +592,7 @@ PluginManager::UnregisterPlugin (JITLoaderCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetJITLoaderMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
JITLoaderInstances &instances = GetJITLoaderInstances ();
JITLoaderInstances::iterator pos, end = instances.end();
@@ -637,11 +611,11 @@ PluginManager::UnregisterPlugin (JITLoaderCreateInstance create_callback)
JITLoaderCreateInstance
PluginManager::GetJITLoaderCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetJITLoaderMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
JITLoaderInstances &instances = GetJITLoaderInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
JITLoaderCreateInstance
@@ -649,7 +623,7 @@ PluginManager::GetJITLoaderCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
- Mutex::Locker locker (GetJITLoaderMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
JITLoaderInstances &instances = GetJITLoaderInstances ();
JITLoaderInstances::iterator pos, end = instances.end();
@@ -659,18 +633,17 @@ PluginManager::GetJITLoaderCreateCallbackForPluginName (const ConstString &name)
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
#pragma mark EmulateInstruction
-
struct EmulateInstructionInstance
{
EmulateInstructionInstance() :
- name(),
- description(),
- create_callback(NULL)
+ name(),
+ description(),
+ create_callback(nullptr)
{
}
@@ -681,10 +654,10 @@ struct EmulateInstructionInstance
typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
-static Mutex &
-GetEmulateInstructionMutex ()
+static std::recursive_mutex &
+GetEmulateInstructionMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -695,14 +668,10 @@ GetEmulateInstructionInstances ()
return g_instances;
}
-
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- EmulateInstructionCreateInstance create_callback
-)
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ EmulateInstructionCreateInstance create_callback)
{
if (create_callback)
{
@@ -712,7 +681,7 @@ PluginManager::RegisterPlugin
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
- Mutex::Locker locker (GetEmulateInstructionMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
GetEmulateInstructionInstances ().push_back (instance);
}
return false;
@@ -723,7 +692,7 @@ PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callbac
{
if (create_callback)
{
- Mutex::Locker locker (GetEmulateInstructionMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
EmulateInstructionInstances::iterator pos, end = instances.end();
@@ -742,11 +711,11 @@ PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callbac
EmulateInstructionCreateInstance
PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetEmulateInstructionMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
EmulateInstructionCreateInstance
@@ -754,7 +723,7 @@ PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstStri
{
if (name)
{
- Mutex::Locker locker (GetEmulateInstructionMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
EmulateInstructionInstances::iterator pos, end = instances.end();
@@ -764,10 +733,10 @@ PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstStri
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
-#pragma mark OperatingSystem
+#pragma mark OperatingSystem
struct OperatingSystemInstance
{
@@ -787,10 +756,10 @@ struct OperatingSystemInstance
typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
-static Mutex &
-GetOperatingSystemMutex ()
+static std::recursive_mutex &
+GetOperatingSystemMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -815,7 +784,7 @@ PluginManager::RegisterPlugin(const ConstString &name, const char *description,
instance.description = description;
instance.create_callback = create_callback;
instance.debugger_init_callback = debugger_init_callback;
- Mutex::Locker locker (GetOperatingSystemMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
GetOperatingSystemInstances ().push_back (instance);
}
return false;
@@ -826,7 +795,7 @@ PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetOperatingSystemMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
OperatingSystemInstances &instances = GetOperatingSystemInstances ();
OperatingSystemInstances::iterator pos, end = instances.end();
@@ -845,11 +814,11 @@ PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
OperatingSystemCreateInstance
PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetOperatingSystemMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
OperatingSystemInstances &instances = GetOperatingSystemInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
OperatingSystemCreateInstance
@@ -857,7 +826,7 @@ PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString
{
if (name)
{
- Mutex::Locker locker (GetOperatingSystemMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
OperatingSystemInstances &instances = GetOperatingSystemInstances ();
OperatingSystemInstances::iterator pos, end = instances.end();
@@ -867,19 +836,17 @@ PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
-
#pragma mark Language
-
struct LanguageInstance
{
LanguageInstance() :
name(),
description(),
- create_callback(NULL)
+ create_callback(nullptr)
{
}
@@ -890,10 +857,10 @@ struct LanguageInstance
typedef std::vector<LanguageInstance> LanguageInstances;
-static Mutex &
-GetLanguageMutex ()
+static std::recursive_mutex &
+GetLanguageMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -905,12 +872,9 @@ GetLanguageInstances ()
}
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- LanguageCreateInstance create_callback
- )
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ LanguageCreateInstance create_callback)
{
if (create_callback)
{
@@ -920,7 +884,7 @@ PluginManager::RegisterPlugin
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
- Mutex::Locker locker (GetLanguageMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
GetLanguageInstances ().push_back (instance);
}
return false;
@@ -931,7 +895,7 @@ PluginManager::UnregisterPlugin (LanguageCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetLanguageMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
LanguageInstances &instances = GetLanguageInstances ();
LanguageInstances::iterator pos, end = instances.end();
@@ -950,11 +914,11 @@ PluginManager::UnregisterPlugin (LanguageCreateInstance create_callback)
LanguageCreateInstance
PluginManager::GetLanguageCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetLanguageMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
LanguageInstances &instances = GetLanguageInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
LanguageCreateInstance
@@ -962,7 +926,7 @@ PluginManager::GetLanguageCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
- Mutex::Locker locker (GetLanguageMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
LanguageInstances &instances = GetLanguageInstances ();
LanguageInstances::iterator pos, end = instances.end();
@@ -972,19 +936,17 @@ PluginManager::GetLanguageCreateCallbackForPluginName (const ConstString &name)
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
-
#pragma mark LanguageRuntime
-
struct LanguageRuntimeInstance
{
LanguageRuntimeInstance() :
name(),
description(),
- create_callback(NULL)
+ create_callback(nullptr)
{
}
@@ -996,10 +958,10 @@ struct LanguageRuntimeInstance
typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
-static Mutex &
-GetLanguageRuntimeMutex ()
+static std::recursive_mutex &
+GetLanguageRuntimeMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -1011,13 +973,10 @@ GetLanguageRuntimeInstances ()
}
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- LanguageRuntimeCreateInstance create_callback,
- LanguageRuntimeGetCommandObject command_callback
-)
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ LanguageRuntimeCreateInstance create_callback,
+ LanguageRuntimeGetCommandObject command_callback)
{
if (create_callback)
{
@@ -1028,7 +987,7 @@ PluginManager::RegisterPlugin
instance.description = description;
instance.create_callback = create_callback;
instance.command_callback = command_callback;
- Mutex::Locker locker (GetLanguageRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
GetLanguageRuntimeInstances ().push_back (instance);
}
return false;
@@ -1039,7 +998,7 @@ PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetLanguageRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
LanguageRuntimeInstances::iterator pos, end = instances.end();
@@ -1058,21 +1017,21 @@ PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
LanguageRuntimeCreateInstance
PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetLanguageRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
LanguageRuntimeGetCommandObject
PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetLanguageRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
if (idx < instances.size())
return instances[idx].command_callback;
- return NULL;
+ return nullptr;
}
LanguageRuntimeCreateInstance
@@ -1080,7 +1039,7 @@ PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString
{
if (name)
{
- Mutex::Locker locker (GetLanguageRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
LanguageRuntimeInstances::iterator pos, end = instances.end();
@@ -1090,18 +1049,17 @@ PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
#pragma mark SystemRuntime
-
struct SystemRuntimeInstance
{
SystemRuntimeInstance() :
name(),
description(),
- create_callback(NULL)
+ create_callback(nullptr)
{
}
@@ -1112,10 +1070,10 @@ struct SystemRuntimeInstance
typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
-static Mutex &
-GetSystemRuntimeMutex ()
+static std::recursive_mutex &
+GetSystemRuntimeMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -1127,12 +1085,9 @@ GetSystemRuntimeInstances ()
}
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- SystemRuntimeCreateInstance create_callback
-)
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ SystemRuntimeCreateInstance create_callback)
{
if (create_callback)
{
@@ -1142,7 +1097,7 @@ PluginManager::RegisterPlugin
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
- Mutex::Locker locker (GetSystemRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
GetSystemRuntimeInstances ().push_back (instance);
}
return false;
@@ -1153,7 +1108,7 @@ PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetSystemRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
SystemRuntimeInstances::iterator pos, end = instances.end();
@@ -1172,11 +1127,11 @@ PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
SystemRuntimeCreateInstance
PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetSystemRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
SystemRuntimeCreateInstance
@@ -1184,7 +1139,7 @@ PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &n
{
if (name)
{
- Mutex::Locker locker (GetSystemRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
SystemRuntimeInstances::iterator pos, end = instances.end();
@@ -1194,10 +1149,9 @@ PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &n
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
-
#pragma mark ObjectFile
struct ObjectFileInstance
@@ -1205,10 +1159,10 @@ struct ObjectFileInstance
ObjectFileInstance() :
name(),
description(),
- create_callback(NULL),
- create_memory_callback (NULL),
- get_module_specifications (NULL),
- save_core (NULL)
+ create_callback(nullptr),
+ create_memory_callback(nullptr),
+ get_module_specifications(nullptr),
+ save_core(nullptr)
{
}
@@ -1222,10 +1176,10 @@ struct ObjectFileInstance
typedef std::vector<ObjectFileInstance> ObjectFileInstances;
-static Mutex &
-GetObjectFileMutex ()
+static std::recursive_mutex &
+GetObjectFileMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -1236,7 +1190,6 @@ GetObjectFileInstances ()
return g_instances;
}
-
bool
PluginManager::RegisterPlugin (const ConstString &name,
const char *description,
@@ -1256,7 +1209,7 @@ PluginManager::RegisterPlugin (const ConstString &name,
instance.create_memory_callback = create_memory_callback;
instance.save_core = save_core;
instance.get_module_specifications = get_module_specifications;
- Mutex::Locker locker (GetObjectFileMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
GetObjectFileInstances ().push_back (instance);
}
return false;
@@ -1267,7 +1220,7 @@ PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetObjectFileMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
ObjectFileInstances &instances = GetObjectFileInstances ();
ObjectFileInstances::iterator pos, end = instances.end();
@@ -1286,32 +1239,31 @@ PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
ObjectFileCreateInstance
PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetObjectFileMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
ObjectFileInstances &instances = GetObjectFileInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
-
ObjectFileCreateMemoryInstance
PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetObjectFileMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
ObjectFileInstances &instances = GetObjectFileInstances ();
if (idx < instances.size())
return instances[idx].create_memory_callback;
- return NULL;
+ return nullptr;
}
ObjectFileGetModuleSpecifications
PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetObjectFileMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
ObjectFileInstances &instances = GetObjectFileInstances ();
if (idx < instances.size())
return instances[idx].get_module_specifications;
- return NULL;
+ return nullptr;
}
ObjectFileCreateInstance
@@ -1319,7 +1271,7 @@ PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name
{
if (name)
{
- Mutex::Locker locker (GetObjectFileMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
ObjectFileInstances &instances = GetObjectFileInstances ();
ObjectFileInstances::iterator pos, end = instances.end();
@@ -1329,16 +1281,15 @@ PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
-
ObjectFileCreateMemoryInstance
PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
{
if (name)
{
- Mutex::Locker locker (GetObjectFileMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
ObjectFileInstances &instances = GetObjectFileInstances ();
ObjectFileInstances::iterator pos, end = instances.end();
@@ -1348,14 +1299,14 @@ PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString
return pos->create_memory_callback;
}
}
- return NULL;
+ return nullptr;
}
Error
PluginManager::SaveCore (const lldb::ProcessSP &process_sp, const FileSpec &outfile)
{
Error error;
- Mutex::Locker locker (GetObjectFileMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
ObjectFileInstances &instances = GetObjectFileInstances ();
ObjectFileInstances::iterator pos, end = instances.end();
@@ -1375,8 +1326,8 @@ struct ObjectContainerInstance
ObjectContainerInstance() :
name(),
description(),
- create_callback (NULL),
- get_module_specifications (NULL)
+ create_callback(nullptr),
+ get_module_specifications(nullptr)
{
}
@@ -1384,15 +1335,14 @@ struct ObjectContainerInstance
std::string description;
ObjectContainerCreateInstance create_callback;
ObjectFileGetModuleSpecifications get_module_specifications;
-
};
typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
-static Mutex &
-GetObjectContainerMutex ()
+static std::recursive_mutex &
+GetObjectContainerMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -1418,7 +1368,7 @@ PluginManager::RegisterPlugin (const ConstString &name,
instance.description = description;
instance.create_callback = create_callback;
instance.get_module_specifications = get_module_specifications;
- Mutex::Locker locker (GetObjectContainerMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
GetObjectContainerInstances ().push_back (instance);
}
return false;
@@ -1429,7 +1379,7 @@ PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetObjectContainerMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
ObjectContainerInstances &instances = GetObjectContainerInstances ();
ObjectContainerInstances::iterator pos, end = instances.end();
@@ -1448,11 +1398,11 @@ PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
ObjectContainerCreateInstance
PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetObjectContainerMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
ObjectContainerInstances &instances = GetObjectContainerInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
ObjectContainerCreateInstance
@@ -1460,7 +1410,7 @@ PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString
{
if (name)
{
- Mutex::Locker locker (GetObjectContainerMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
ObjectContainerInstances &instances = GetObjectContainerInstances ();
ObjectContainerInstances::iterator pos, end = instances.end();
@@ -1470,17 +1420,17 @@ PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
ObjectFileGetModuleSpecifications
PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetObjectContainerMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
ObjectContainerInstances &instances = GetObjectContainerInstances ();
if (idx < instances.size())
return instances[idx].get_module_specifications;
- return NULL;
+ return nullptr;
}
#pragma mark LogChannel
@@ -1490,7 +1440,7 @@ struct LogInstance
LogInstance() :
name(),
description(),
- create_callback(NULL)
+ create_callback(nullptr)
{
}
@@ -1501,10 +1451,10 @@ struct LogInstance
typedef std::vector<LogInstance> LogInstances;
-static Mutex &
-GetLogMutex ()
+static std::recursive_mutex &
+GetLogMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -1515,15 +1465,10 @@ GetLogInstances ()
return g_instances;
}
-
-
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- LogChannelCreateInstance create_callback
-)
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ LogChannelCreateInstance create_callback)
{
if (create_callback)
{
@@ -1533,7 +1478,7 @@ PluginManager::RegisterPlugin
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
- Mutex::Locker locker (GetLogMutex ());
+ std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
GetLogInstances ().push_back (instance);
}
return false;
@@ -1544,7 +1489,7 @@ PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetLogMutex ());
+ std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
LogInstances &instances = GetLogInstances ();
LogInstances::iterator pos, end = instances.end();
@@ -1563,22 +1508,21 @@ PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
const char *
PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetLogMutex ());
+ std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
LogInstances &instances = GetLogInstances ();
if (idx < instances.size())
return instances[idx].name.GetCString();
- return NULL;
+ return nullptr;
}
-
LogChannelCreateInstance
PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetLogMutex ());
+ std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
LogInstances &instances = GetLogInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
LogChannelCreateInstance
@@ -1586,7 +1530,7 @@ PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name
{
if (name)
{
- Mutex::Locker locker (GetLogMutex ());
+ std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
LogInstances &instances = GetLogInstances ();
LogInstances::iterator pos, end = instances.end();
@@ -1596,7 +1540,7 @@ PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
#pragma mark Platform
@@ -1606,8 +1550,8 @@ struct PlatformInstance
PlatformInstance() :
name(),
description(),
- create_callback(NULL),
- debugger_init_callback (NULL)
+ create_callback(nullptr),
+ debugger_init_callback(nullptr)
{
}
@@ -1619,10 +1563,10 @@ struct PlatformInstance
typedef std::vector<PlatformInstance> PlatformInstances;
-static Mutex &
-GetPlatformInstancesMutex ()
+static std::recursive_mutex &
+GetPlatformInstancesMutex()
{
- static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_platform_instances_mutex;
return g_platform_instances_mutex;
}
@@ -1633,7 +1577,6 @@ GetPlatformInstances ()
return g_platform_instances;
}
-
bool
PluginManager::RegisterPlugin (const ConstString &name,
const char *description,
@@ -1642,8 +1585,8 @@ PluginManager::RegisterPlugin (const ConstString &name,
{
if (create_callback)
{
- Mutex::Locker locker (GetPlatformInstancesMutex ());
-
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
+
PlatformInstance instance;
assert ((bool)name);
instance.name = name;
@@ -1657,25 +1600,24 @@ PluginManager::RegisterPlugin (const ConstString &name,
return false;
}
-
const char *
PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetPlatformInstancesMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
PlatformInstances &instances = GetPlatformInstances ();
if (idx < instances.size())
return instances[idx].name.GetCString();
- return NULL;
+ return nullptr;
}
const char *
PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetPlatformInstancesMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
PlatformInstances &instances = GetPlatformInstances ();
if (idx < instances.size())
return instances[idx].description.c_str();
- return NULL;
+ return nullptr;
}
bool
@@ -1683,7 +1625,7 @@ PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetPlatformInstancesMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
PlatformInstances &instances = GetPlatformInstances ();
PlatformInstances::iterator pos, end = instances.end();
@@ -1702,11 +1644,11 @@ PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
PlatformCreateInstance
PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetPlatformInstancesMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
PlatformInstances &instances = GetPlatformInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
PlatformCreateInstance
@@ -1714,7 +1656,7 @@ PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
- Mutex::Locker locker (GetPlatformInstancesMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
PlatformInstances &instances = GetPlatformInstances ();
PlatformInstances::iterator pos, end = instances.end();
@@ -1724,7 +1666,7 @@ PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
size_t
@@ -1732,7 +1674,7 @@ PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
{
if (name)
{
- Mutex::Locker locker (GetPlatformInstancesMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
PlatformInstances &instances = GetPlatformInstances ();
llvm::StringRef name_sref(name);
@@ -1746,6 +1688,7 @@ PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
}
return matches.GetSize();
}
+
#pragma mark Process
struct ProcessInstance
@@ -1753,8 +1696,8 @@ struct ProcessInstance
ProcessInstance() :
name(),
description(),
- create_callback(NULL),
- debugger_init_callback(NULL)
+ create_callback(nullptr),
+ debugger_init_callback(nullptr)
{
}
@@ -1766,10 +1709,10 @@ struct ProcessInstance
typedef std::vector<ProcessInstance> ProcessInstances;
-static Mutex &
-GetProcessMutex ()
+static std::recursive_mutex &
+GetProcessMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -1780,7 +1723,6 @@ GetProcessInstances ()
return g_instances;
}
-
bool
PluginManager::RegisterPlugin (const ConstString &name,
const char *description,
@@ -1796,7 +1738,7 @@ PluginManager::RegisterPlugin (const ConstString &name,
instance.description = description;
instance.create_callback = create_callback;
instance.debugger_init_callback = debugger_init_callback;
- Mutex::Locker locker (GetProcessMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
GetProcessInstances ().push_back (instance);
}
return false;
@@ -1805,21 +1747,21 @@ PluginManager::RegisterPlugin (const ConstString &name,
const char *
PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetProcessMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
ProcessInstances &instances = GetProcessInstances ();
if (idx < instances.size())
return instances[idx].name.GetCString();
- return NULL;
+ return nullptr;
}
const char *
PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetProcessMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
ProcessInstances &instances = GetProcessInstances ();
if (idx < instances.size())
return instances[idx].description.c_str();
- return NULL;
+ return nullptr;
}
bool
@@ -1827,7 +1769,7 @@ PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetProcessMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
ProcessInstances &instances = GetProcessInstances ();
ProcessInstances::iterator pos, end = instances.end();
@@ -1846,20 +1788,19 @@ PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
ProcessCreateInstance
PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetProcessMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
ProcessInstances &instances = GetProcessInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
-
ProcessCreateInstance
PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
- Mutex::Locker locker (GetProcessMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
ProcessInstances &instances = GetProcessInstances ();
ProcessInstances::iterator pos, end = instances.end();
@@ -1869,7 +1810,7 @@ PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
#pragma mark ScriptInterpreter
@@ -1880,7 +1821,7 @@ struct ScriptInterpreterInstance
: name()
, language(lldb::eScriptLanguageNone)
, description()
- , create_callback(NULL)
+ , create_callback(nullptr)
{
}
@@ -1892,10 +1833,10 @@ struct ScriptInterpreterInstance
typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
-static Mutex &
+static std::recursive_mutex &
GetScriptInterpreterMutex()
{
- static Mutex g_instances_mutex(Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -1919,7 +1860,7 @@ PluginManager::RegisterPlugin(const ConstString &name, const char *description,
instance.description = description;
instance.create_callback = create_callback;
instance.language = script_language;
- Mutex::Locker locker(GetScriptInterpreterMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
GetScriptInterpreterInstances().push_back(instance);
return false;
}
@@ -1929,7 +1870,7 @@ PluginManager::UnregisterPlugin(ScriptInterpreterCreateInstance create_callback)
{
if (!create_callback)
return false;
- Mutex::Locker locker(GetScriptInterpreterMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
ScriptInterpreterInstances::iterator pos, end = instances.end();
@@ -1947,7 +1888,7 @@ PluginManager::UnregisterPlugin(ScriptInterpreterCreateInstance create_callback)
ScriptInterpreterCreateInstance
PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx)
{
- Mutex::Locker locker(GetScriptInterpreterMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
if (idx < instances.size())
return instances[idx].create_callback;
@@ -1957,7 +1898,7 @@ PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx)
lldb::ScriptInterpreterSP
PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter)
{
- Mutex::Locker locker(GetScriptInterpreterMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
ScriptInterpreterInstances::iterator pos, end = instances.end();
@@ -1996,10 +1937,10 @@ struct SymbolFileInstance
typedef std::vector<SymbolFileInstance> SymbolFileInstances;
-static Mutex &
-GetSymbolFileMutex ()
+static std::recursive_mutex &
+GetSymbolFileMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -2010,15 +1951,11 @@ GetSymbolFileInstances ()
return g_instances;
}
-
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- SymbolFileCreateInstance create_callback,
- DebuggerInitializeCallback debugger_init_callback
-)
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ SymbolFileCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback)
{
if (create_callback)
{
@@ -2029,7 +1966,7 @@ PluginManager::RegisterPlugin
instance.description = description;
instance.create_callback = create_callback;
instance.debugger_init_callback = debugger_init_callback;
- Mutex::Locker locker (GetSymbolFileMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
GetSymbolFileInstances ().push_back (instance);
}
return false;
@@ -2040,7 +1977,7 @@ PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetSymbolFileMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
SymbolFileInstances &instances = GetSymbolFileInstances ();
SymbolFileInstances::iterator pos, end = instances.end();
@@ -2059,11 +1996,11 @@ PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
SymbolFileCreateInstance
PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetSymbolFileMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
SymbolFileInstances &instances = GetSymbolFileInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
SymbolFileCreateInstance
@@ -2071,7 +2008,7 @@ PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name
{
if (name)
{
- Mutex::Locker locker (GetSymbolFileMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
SymbolFileInstances &instances = GetSymbolFileInstances ();
SymbolFileInstances::iterator pos, end = instances.end();
@@ -2081,11 +2018,9 @@ PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
-
-
#pragma mark SymbolVendor
struct SymbolVendorInstance
@@ -2093,7 +2028,7 @@ struct SymbolVendorInstance
SymbolVendorInstance() :
name(),
description(),
- create_callback(NULL)
+ create_callback(nullptr)
{
}
@@ -2104,10 +2039,10 @@ struct SymbolVendorInstance
typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
-static Mutex &
-GetSymbolVendorMutex ()
+static std::recursive_mutex &
+GetSymbolVendorMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -2119,12 +2054,9 @@ GetSymbolVendorInstances ()
}
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- SymbolVendorCreateInstance create_callback
-)
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ SymbolVendorCreateInstance create_callback)
{
if (create_callback)
{
@@ -2134,7 +2066,7 @@ PluginManager::RegisterPlugin
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
- Mutex::Locker locker (GetSymbolVendorMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
GetSymbolVendorInstances ().push_back (instance);
}
return false;
@@ -2145,7 +2077,7 @@ PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetSymbolVendorMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
SymbolVendorInstances &instances = GetSymbolVendorInstances ();
SymbolVendorInstances::iterator pos, end = instances.end();
@@ -2164,20 +2096,19 @@ PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
SymbolVendorCreateInstance
PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetSymbolVendorMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
SymbolVendorInstances &instances = GetSymbolVendorInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
-
SymbolVendorCreateInstance
PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
- Mutex::Locker locker (GetSymbolVendorMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
SymbolVendorInstances &instances = GetSymbolVendorInstances ();
SymbolVendorInstances::iterator pos, end = instances.end();
@@ -2187,10 +2118,9 @@ PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &na
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
-
#pragma mark UnwindAssembly
struct UnwindAssemblyInstance
@@ -2198,7 +2128,7 @@ struct UnwindAssemblyInstance
UnwindAssemblyInstance() :
name(),
description(),
- create_callback(NULL)
+ create_callback(nullptr)
{
}
@@ -2209,10 +2139,10 @@ struct UnwindAssemblyInstance
typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
-static Mutex &
-GetUnwindAssemblyMutex ()
+static std::recursive_mutex &
+GetUnwindAssemblyMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -2224,12 +2154,9 @@ GetUnwindAssemblyInstances ()
}
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- UnwindAssemblyCreateInstance create_callback
-)
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ UnwindAssemblyCreateInstance create_callback)
{
if (create_callback)
{
@@ -2239,7 +2166,7 @@ PluginManager::RegisterPlugin
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
- Mutex::Locker locker (GetUnwindAssemblyMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
GetUnwindAssemblyInstances ().push_back (instance);
}
return false;
@@ -2250,7 +2177,7 @@ PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetUnwindAssemblyMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
UnwindAssemblyInstances::iterator pos, end = instances.end();
@@ -2269,20 +2196,19 @@ PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
UnwindAssemblyCreateInstance
PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetUnwindAssemblyMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
-
UnwindAssemblyCreateInstance
PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
- Mutex::Locker locker (GetUnwindAssemblyMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
UnwindAssemblyInstances::iterator pos, end = instances.end();
@@ -2292,7 +2218,7 @@ PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
#pragma mark MemoryHistory
@@ -2300,9 +2226,9 @@ PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &
struct MemoryHistoryInstance
{
MemoryHistoryInstance() :
- name(),
- description(),
- create_callback(NULL)
+ name(),
+ description(),
+ create_callback(nullptr)
{
}
@@ -2313,10 +2239,10 @@ struct MemoryHistoryInstance
typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
-static Mutex &
-GetMemoryHistoryMutex ()
+static std::recursive_mutex &
+GetMemoryHistoryMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -2328,12 +2254,9 @@ GetMemoryHistoryInstances ()
}
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- MemoryHistoryCreateInstance create_callback
- )
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ MemoryHistoryCreateInstance create_callback)
{
if (create_callback)
{
@@ -2343,7 +2266,7 @@ PluginManager::RegisterPlugin
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
- Mutex::Locker locker (GetMemoryHistoryMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
GetMemoryHistoryInstances ().push_back (instance);
}
return false;
@@ -2354,7 +2277,7 @@ PluginManager::UnregisterPlugin (MemoryHistoryCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetMemoryHistoryMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
MemoryHistoryInstances::iterator pos, end = instances.end();
@@ -2373,20 +2296,19 @@ PluginManager::UnregisterPlugin (MemoryHistoryCreateInstance create_callback)
MemoryHistoryCreateInstance
PluginManager::GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetMemoryHistoryMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
-
MemoryHistoryCreateInstance
PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
- Mutex::Locker locker (GetMemoryHistoryMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
MemoryHistoryInstances::iterator pos, end = instances.end();
@@ -2396,7 +2318,7 @@ PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const ConstString &n
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
#pragma mark InstrumentationRuntime
@@ -2404,9 +2326,9 @@ PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const ConstString &n
struct InstrumentationRuntimeInstance
{
InstrumentationRuntimeInstance() :
- name(),
- description(),
- create_callback(NULL)
+ name(),
+ description(),
+ create_callback(nullptr)
{
}
@@ -2418,10 +2340,10 @@ struct InstrumentationRuntimeInstance
typedef std::vector<InstrumentationRuntimeInstance> InstrumentationRuntimeInstances;
-static Mutex &
-GetInstrumentationRuntimeMutex ()
+static std::recursive_mutex &
+GetInstrumentationRuntimeMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -2433,13 +2355,10 @@ GetInstrumentationRuntimeInstances ()
}
bool
-PluginManager::RegisterPlugin
-(
- const ConstString &name,
- const char *description,
- InstrumentationRuntimeCreateInstance create_callback,
- InstrumentationRuntimeGetType get_type_callback
- )
+PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ InstrumentationRuntimeCreateInstance create_callback,
+ InstrumentationRuntimeGetType get_type_callback)
{
if (create_callback)
{
@@ -2450,7 +2369,7 @@ PluginManager::RegisterPlugin
instance.description = description;
instance.create_callback = create_callback;
instance.get_type_callback = get_type_callback;
- Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
GetInstrumentationRuntimeInstances ().push_back (instance);
}
return false;
@@ -2461,7 +2380,7 @@ PluginManager::UnregisterPlugin (InstrumentationRuntimeCreateInstance create_cal
{
if (create_callback)
{
- Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
InstrumentationRuntimeInstances::iterator pos, end = instances.end();
@@ -2480,30 +2399,29 @@ PluginManager::UnregisterPlugin (InstrumentationRuntimeCreateInstance create_cal
InstrumentationRuntimeGetType
PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
if (idx < instances.size())
return instances[idx].get_type_callback;
- return NULL;
+ return nullptr;
}
InstrumentationRuntimeCreateInstance
PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
-
InstrumentationRuntimeCreateInstance
PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
- Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
InstrumentationRuntimeInstances::iterator pos, end = instances.end();
@@ -2513,18 +2431,17 @@ PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const Const
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
#pragma mark TypeSystem
-
struct TypeSystemInstance
{
TypeSystemInstance() :
- name(),
- description(),
- create_callback(NULL)
+ name(),
+ description(),
+ create_callback(nullptr)
{
}
@@ -2536,10 +2453,10 @@ struct TypeSystemInstance
typedef std::vector<TypeSystemInstance> TypeSystemInstances;
-static Mutex &
-GetTypeSystemMutex ()
+static std::recursive_mutex &
+GetTypeSystemMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -2565,7 +2482,7 @@ PluginManager::RegisterPlugin (const ConstString &name,
instance.description = description;
instance.create_callback = create_callback;
instance.enumerate_callback = enumerate_supported_languages_callback;
- Mutex::Locker locker (GetTypeSystemMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
GetTypeSystemInstances ().push_back (instance);
}
return false;
@@ -2576,7 +2493,7 @@ PluginManager::UnregisterPlugin (TypeSystemCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetTypeSystemMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
TypeSystemInstances &instances = GetTypeSystemInstances ();
TypeSystemInstances::iterator pos, end = instances.end();
@@ -2595,11 +2512,11 @@ PluginManager::UnregisterPlugin (TypeSystemCreateInstance create_callback)
TypeSystemCreateInstance
PluginManager::GetTypeSystemCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetTypeSystemMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
TypeSystemInstances &instances = GetTypeSystemInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
TypeSystemCreateInstance
@@ -2607,7 +2524,7 @@ PluginManager::GetTypeSystemCreateCallbackForPluginName (const ConstString &name
{
if (name)
{
- Mutex::Locker locker (GetTypeSystemMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
TypeSystemInstances &instances = GetTypeSystemInstances ();
TypeSystemInstances::iterator pos, end = instances.end();
@@ -2617,17 +2534,17 @@ PluginManager::GetTypeSystemCreateCallbackForPluginName (const ConstString &name
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
TypeSystemEnumerateSupportedLanguages
PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetTypeSystemMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
TypeSystemInstances &instances = GetTypeSystemInstances ();
if (idx < instances.size())
return instances[idx].enumerate_callback;
- return NULL;
+ return nullptr;
}
TypeSystemEnumerateSupportedLanguages
@@ -2635,7 +2552,7 @@ PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName (co
{
if (name)
{
- Mutex::Locker locker (GetTypeSystemMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
TypeSystemInstances &instances = GetTypeSystemInstances ();
TypeSystemInstances::iterator pos, end = instances.end();
@@ -2645,7 +2562,7 @@ PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName (co
return pos->enumerate_callback;
}
}
- return NULL;
+ return nullptr;
}
#pragma mark REPL
@@ -2653,9 +2570,9 @@ PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName (co
struct REPLInstance
{
REPLInstance() :
- name(),
- description(),
- create_callback(NULL)
+ name(),
+ description(),
+ create_callback(nullptr)
{
}
@@ -2667,10 +2584,10 @@ struct REPLInstance
typedef std::vector<REPLInstance> REPLInstances;
-static Mutex &
-GetREPLMutex ()
+static std::recursive_mutex &
+GetREPLMutex()
{
- static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
@@ -2696,7 +2613,7 @@ PluginManager::RegisterPlugin (const ConstString &name,
instance.description = description;
instance.create_callback = create_callback;
instance.enumerate_languages_callback = enumerate_languages_callback;
- Mutex::Locker locker (GetREPLMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
GetREPLInstances ().push_back (instance);
}
return false;
@@ -2707,7 +2624,7 @@ PluginManager::UnregisterPlugin (REPLCreateInstance create_callback)
{
if (create_callback)
{
- Mutex::Locker locker (GetREPLMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
REPLInstances &instances = GetREPLInstances ();
REPLInstances::iterator pos, end = instances.end();
@@ -2726,11 +2643,11 @@ PluginManager::UnregisterPlugin (REPLCreateInstance create_callback)
REPLCreateInstance
PluginManager::GetREPLCreateCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetREPLMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
REPLInstances &instances = GetREPLInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
- return NULL;
+ return nullptr;
}
REPLCreateInstance
@@ -2738,7 +2655,7 @@ PluginManager::GetREPLCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
- Mutex::Locker locker (GetREPLMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
REPLInstances &instances = GetREPLInstances ();
REPLInstances::iterator pos, end = instances.end();
@@ -2748,26 +2665,25 @@ PluginManager::GetREPLCreateCallbackForPluginName (const ConstString &name)
return pos->create_callback;
}
}
- return NULL;
+ return nullptr;
}
REPLEnumerateSupportedLanguages
PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx)
{
- Mutex::Locker locker (GetREPLMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
REPLInstances &instances = GetREPLInstances ();
if (idx < instances.size())
return instances[idx].enumerate_languages_callback;
- return NULL;
+ return nullptr;
}
-
REPLEnumerateSupportedLanguages
PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name)
{
if (name)
{
- Mutex::Locker locker (GetREPLMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
REPLInstances &instances = GetREPLInstances ();
REPLInstances::iterator pos, end = instances.end();
@@ -2777,7 +2693,7 @@ PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName (co
return pos->enumerate_languages_callback;
}
}
- return NULL;
+ return nullptr;
}
#pragma mark PluginManager
@@ -2787,7 +2703,7 @@ PluginManager::DebuggerInitialize (Debugger &debugger)
{
// Initialize the DynamicLoader plugins
{
- Mutex::Locker locker (GetDynamicLoaderMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
DynamicLoaderInstances::iterator pos, end = instances.end();
@@ -2800,7 +2716,7 @@ PluginManager::DebuggerInitialize (Debugger &debugger)
// Initialize the JITLoader plugins
{
- Mutex::Locker locker (GetJITLoaderMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
JITLoaderInstances &instances = GetJITLoaderInstances ();
JITLoaderInstances::iterator pos, end = instances.end();
@@ -2813,7 +2729,7 @@ PluginManager::DebuggerInitialize (Debugger &debugger)
// Initialize the Platform plugins
{
- Mutex::Locker locker (GetPlatformInstancesMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
PlatformInstances &instances = GetPlatformInstances ();
PlatformInstances::iterator pos, end = instances.end();
@@ -2826,7 +2742,7 @@ PluginManager::DebuggerInitialize (Debugger &debugger)
// Initialize the Process plugins
{
- Mutex::Locker locker (GetProcessMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
ProcessInstances &instances = GetProcessInstances();
ProcessInstances::iterator pos, end = instances.end();
@@ -2839,7 +2755,7 @@ PluginManager::DebuggerInitialize (Debugger &debugger)
// Initialize the SymbolFile plugins
{
- Mutex::Locker locker (GetSymbolFileMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
for (auto& sym_file: GetSymbolFileInstances())
{
if (sym_file.debugger_init_callback)
@@ -2849,7 +2765,7 @@ PluginManager::DebuggerInitialize (Debugger &debugger)
// Initialize the OperatingSystem plugins
{
- Mutex::Locker locker(GetOperatingSystemMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
for (auto &os : GetOperatingSystemInstances())
{
if (os.debugger_init_callback)
@@ -2871,7 +2787,7 @@ GetDebuggerPropertyForPlugins (Debugger &debugger,
{
static ConstString g_property_name("plugin");
- OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
+ OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty(nullptr, g_property_name);
if (!plugin_properties_sp && can_create)
{
plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
@@ -2883,7 +2799,7 @@ GetDebuggerPropertyForPlugins (Debugger &debugger,
if (plugin_properties_sp)
{
- lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
+ lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
if (!plugin_type_properties_sp && can_create)
{
plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
@@ -2911,7 +2827,7 @@ GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
if (parent_properties_sp)
{
- OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
+ OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
if (!plugin_properties_sp && can_create)
{
plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
@@ -2923,7 +2839,7 @@ GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
if (plugin_properties_sp)
{
- lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
+ lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
if (!plugin_type_properties_sp && can_create)
{
plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
@@ -2990,7 +2906,7 @@ const char* kProcessPluginName("process");
const char* kSymbolFilePluginName("symbol-file");
const char* kJITLoaderPluginName("jit-loader");
-}
+} // anonymous namespace
lldb::OptionValuePropertiesSP
PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger,
@@ -3013,7 +2929,6 @@ PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
is_global_property);
}
-
lldb::OptionValuePropertiesSP
PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
{
@@ -3038,7 +2953,6 @@ PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
GetDebuggerPropertyForPluginsOldStyle);
}
-
lldb::OptionValuePropertiesSP
PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
{
diff --git a/source/Core/RegisterValue.cpp b/source/Core/RegisterValue.cpp
index d4ba9989c6a9..d9085d7f0bae 100644
--- a/source/Core/RegisterValue.cpp
+++ b/source/Core/RegisterValue.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterValue.cpp ----------------------------------------*- C++ -*-===//
+//===-- RegisterValue.cpp ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,7 +11,12 @@
// C Includes
// C++ Includes
+#include <vector>
+
// Other libraries and framework includes
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
// Project includes
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
@@ -24,7 +29,6 @@
using namespace lldb;
using namespace lldb_private;
-
bool
RegisterValue::Dump (Stream *s,
const RegisterInfo *reg_info,
@@ -98,14 +102,12 @@ RegisterValue::Dump (Stream *s,
return false;
}
-
bool
RegisterValue::GetData (DataExtractor &data) const
{
return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
}
-
uint32_t
RegisterValue::GetAsMemoryData (const RegisterInfo *reg_info,
void *dst,
@@ -113,7 +115,7 @@ RegisterValue::GetAsMemoryData (const RegisterInfo *reg_info,
lldb::ByteOrder dst_byte_order,
Error &error) const
{
- if (reg_info == NULL)
+ if (reg_info == nullptr)
{
error.SetErrorString ("invalid register info argument.");
return 0;
@@ -163,7 +165,7 @@ RegisterValue::SetFromMemoryData (const RegisterInfo *reg_info,
lldb::ByteOrder src_byte_order,
Error &error)
{
- if (reg_info == NULL)
+ if (reg_info == nullptr)
{
error.SetErrorString ("invalid register info argument.");
return 0;
@@ -202,34 +204,13 @@ RegisterValue::SetFromMemoryData (const RegisterInfo *reg_info,
// Use a data extractor to correctly copy and pad the bytes read into the
// register value
DataExtractor src_data (src, src_len, src_byte_order, 4);
-
- // Given the register info, set the value type of this RegisterValue object
- SetType (reg_info);
- // And make sure we were able to figure out what that register value was
- RegisterValue::Type value_type = GetType();
- if (value_type == eTypeInvalid)
- {
- // No value has been read into this object...
- error.SetErrorStringWithFormat("invalid register value type for register %s", reg_info->name);
- return 0;
- }
- else if (value_type == eTypeBytes)
- {
- buffer.byte_order = src_byte_order;
- // Make sure to set the buffer length of the destination buffer to avoid
- // problems due to uninitialized variables.
- buffer.length = src_len;
- }
- const uint32_t bytes_copied = src_data.CopyByteOrderedData (0, // src offset
- src_len, // src length
- GetBytes(), // dst buffer
- GetByteSize(), // dst length
- GetByteOrder()); // dst byte order
- if (bytes_copied == 0)
- error.SetErrorStringWithFormat("failed to copy data for register write of %s", reg_info->name);
+ error = SetValueFromData(reg_info, src_data, 0, true);
+ if (error.Fail())
+ return 0;
- return bytes_copied;
+ // If SetValueFromData succeeded, we must have copied all of src_len
+ return src_len;
}
bool
@@ -239,16 +220,27 @@ RegisterValue::GetScalarValue (Scalar &scalar) const
{
case eTypeInvalid: break;
case eTypeBytes:
- {
- switch (buffer.length)
{
- default: break;
- case 1: scalar = *(const uint8_t *)buffer.bytes; return true;
- case 2: scalar = *(const uint16_t *)buffer.bytes; return true;
- case 4: scalar = *(const uint32_t *)buffer.bytes; return true;
- case 8: scalar = *(const uint64_t *)buffer.bytes; return true;
+ switch (buffer.length)
+ {
+ default: break;
+ case 1: scalar = *(const uint8_t *)buffer.bytes; return true;
+ case 2: scalar = *(const uint16_t *)buffer.bytes; return true;
+ case 4: scalar = *(const uint32_t *)buffer.bytes; return true;
+ case 8: scalar = *(const uint64_t *)buffer.bytes; return true;
+ case 16:
+ case 32:
+ if (buffer.length % sizeof(uint64_t) == 0)
+ {
+ const auto length_in_bits = buffer.length * 8;
+ const auto length_in_uint64 = buffer.length / sizeof(uint64_t);
+ scalar = llvm::APInt(length_in_bits, llvm::ArrayRef<uint64_t>((const uint64_t *)buffer.bytes, length_in_uint64));
+ return true;
+ }
+ break;
+ }
}
- }
+ break;
case eTypeUInt8:
case eTypeUInt16:
case eTypeUInt32:
@@ -270,41 +262,12 @@ RegisterValue::Clear()
RegisterValue::Type
RegisterValue::SetType (const RegisterInfo *reg_info)
{
- m_type = eTypeInvalid;
- const uint32_t byte_size = reg_info->byte_size;
- switch (reg_info->encoding)
- {
- case eEncodingInvalid:
- break;
-
- case eEncodingUint:
- case eEncodingSint:
- if (byte_size == 1)
- m_type = eTypeUInt8;
- else if (byte_size <= 2)
- m_type = eTypeUInt16;
- else if (byte_size <= 4)
- m_type = eTypeUInt32;
- else if (byte_size <= 8)
- m_type = eTypeUInt64;
- else if (byte_size <= 16)
- m_type = eTypeUInt128;
- break;
-
- case eEncodingIEEE754:
- if (byte_size == sizeof(float))
- m_type = eTypeFloat;
- else if (byte_size == sizeof(double))
- m_type = eTypeDouble;
- else if (byte_size == sizeof(long double))
- m_type = eTypeLongDouble;
- break;
+ // To change the type, we simply copy the data in again, using the new format
+ RegisterValue copy;
+ DataExtractor copy_data;
+ if (copy.CopyValue(*this) && copy.GetData(copy_data))
+ SetValueFromData(reg_info, copy_data, 0, true);
- case eEncodingVector:
- m_type = eTypeBytes;
- break;
- }
- m_scalar.SetType(reg_info);
return m_type;
}
@@ -342,16 +305,23 @@ RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &sr
memset (buffer.bytes, 0, sizeof (buffer.bytes));
type128 int128;
- switch (SetType (reg_info))
+
+ m_type = eTypeInvalid;
+ switch (reg_info->encoding)
{
- case eTypeInvalid:
- error.SetErrorString("");
+ case eEncodingInvalid:
break;
- case eTypeUInt8: SetUInt8 (src.GetMaxU32 (&src_offset, src_len)); break;
- case eTypeUInt16: SetUInt16 (src.GetMaxU32 (&src_offset, src_len)); break;
- case eTypeUInt32: SetUInt32 (src.GetMaxU32 (&src_offset, src_len)); break;
- case eTypeUInt64: SetUInt64 (src.GetMaxU64 (&src_offset, src_len)); break;
- case eTypeUInt128:
+ case eEncodingUint:
+ case eEncodingSint:
+ if (reg_info->byte_size == 1)
+ SetUInt8(src.GetMaxU32(&src_offset, src_len));
+ else if (reg_info->byte_size <= 2)
+ SetUInt16(src.GetMaxU32(&src_offset, src_len));
+ else if (reg_info->byte_size <= 4)
+ SetUInt32(src.GetMaxU32(&src_offset, src_len));
+ else if (reg_info->byte_size <= 8)
+ SetUInt64(src.GetMaxU64(&src_offset, src_len));
+ else if (reg_info->byte_size <= 16)
{
uint64_t data1 = src.GetU64 (&src_offset);
uint64_t data2 = src.GetU64 (&src_offset);
@@ -368,11 +338,17 @@ RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &sr
SetUInt128 (llvm::APInt(128, 2, int128.x));
}
break;
- case eTypeFloat: SetFloat (src.GetFloat (&src_offset)); break;
- case eTypeDouble: SetDouble(src.GetDouble (&src_offset)); break;
- case eTypeLongDouble: SetFloat (src.GetLongDouble (&src_offset)); break;
- case eTypeBytes:
+ case eEncodingIEEE754:
+ if (reg_info->byte_size == sizeof(float))
+ SetFloat(src.GetFloat(&src_offset));
+ else if (reg_info->byte_size == sizeof(double))
+ SetDouble(src.GetDouble(&src_offset));
+ else if (reg_info->byte_size == sizeof(long double))
+ SetLongDouble(src.GetLongDouble(&src_offset));
+ break;
+ case eEncodingVector:
{
+ m_type = eTypeBytes;
buffer.length = reg_info->byte_size;
buffer.byte_order = src.GetByteOrder();
assert (buffer.length <= kMaxRegisterByteSize);
@@ -384,17 +360,17 @@ RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &sr
buffer.length, // dst length
buffer.byte_order) == 0)// dst byte order
{
- error.SetErrorString ("data copy failed data.");
+ error.SetErrorStringWithFormat("failed to copy data for register write of %s", reg_info->name);
return error;
}
}
}
-
+
+ if (m_type == eTypeInvalid)
+ error.SetErrorStringWithFormat("invalid register value type for register %s", reg_info->name);
return error;
}
-#include "llvm/ADT/StringRef.h"
-#include <vector>
static inline void StripSpaces(llvm::StringRef &Str)
{
while (!Str.empty() && isspace(Str[0]))
@@ -402,16 +378,19 @@ static inline void StripSpaces(llvm::StringRef &Str)
while (!Str.empty() && isspace(Str.back()))
Str = Str.substr(0, Str.size()-1);
}
+
static inline void LStrip(llvm::StringRef &Str, char c)
{
if (!Str.empty() && Str.front() == c)
Str = Str.substr(1);
}
+
static inline void RStrip(llvm::StringRef &Str, char c)
{
if (!Str.empty() && Str.back() == c)
Str = Str.substr(0, Str.size()-1);
}
+
// Helper function for RegisterValue::SetValueFromCString()
static bool
ParseVectorEncoding(const RegisterInfo *reg_info, const char *vector_str, const uint32_t byte_size, RegisterValue *reg_value)
@@ -445,17 +424,18 @@ ParseVectorEncoding(const RegisterInfo *reg_info, const char *vector_str, const
reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
return true;
}
+
Error
RegisterValue::SetValueFromCString (const RegisterInfo *reg_info, const char *value_str)
{
Error error;
- if (reg_info == NULL)
+ if (reg_info == nullptr)
{
error.SetErrorString ("Invalid register info argument.");
return error;
}
- if (value_str == NULL || value_str[0] == '\0')
+ if (value_str == nullptr || value_str[0] == '\0')
{
error.SetErrorString ("Invalid c-string value string.");
return error;
@@ -562,7 +542,6 @@ RegisterValue::SetValueFromCString (const RegisterInfo *reg_info, const char *va
return error;
}
-
bool
RegisterValue::SignExtend (uint32_t sign_bitpos)
{
@@ -730,9 +709,7 @@ RegisterValue::GetAsUInt128 (const llvm::APInt& fail_value, bool *success_ptr) c
case 4:
case 8:
case 16:
- {
return llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)buffer.bytes)->x);
- }
}
}
break;
@@ -825,26 +802,7 @@ RegisterValue::GetBytes () const
case eTypeLongDouble: return m_scalar.GetBytes();
case eTypeBytes: return buffer.bytes;
}
- return NULL;
-}
-
-void *
-RegisterValue::GetBytes ()
-{
- switch (m_type)
- {
- case eTypeInvalid: break;
- case eTypeUInt8:
- case eTypeUInt16:
- case eTypeUInt32:
- case eTypeUInt64:
- case eTypeUInt128:
- case eTypeFloat:
- case eTypeDouble:
- case eTypeLongDouble: return m_scalar.GetBytes();
- case eTypeBytes: return buffer.bytes;
- }
- return NULL;
+ return nullptr;
}
uint32_t
@@ -866,7 +824,6 @@ RegisterValue::GetByteSize () const
return 0;
}
-
bool
RegisterValue::SetUInt (uint64_t uint, uint32_t byte_size)
{
@@ -921,7 +878,6 @@ RegisterValue::SetBytes (const void *bytes, size_t length, lldb::ByteOrder byte_
}
}
-
bool
RegisterValue::operator == (const RegisterValue &rhs) const
{
@@ -1032,7 +988,6 @@ RegisterValue::ClearBit (uint32_t bit)
return false;
}
-
bool
RegisterValue::SetBit (uint32_t bit)
{
@@ -1077,4 +1032,3 @@ RegisterValue::SetBit (uint32_t bit)
}
return false;
}
-
diff --git a/source/Core/RegularExpression.cpp b/source/Core/RegularExpression.cpp
index 767521500af8..bdef3ced94d4 100644
--- a/source/Core/RegularExpression.cpp
+++ b/source/Core/RegularExpression.cpp
@@ -7,11 +7,17 @@
//
//===----------------------------------------------------------------------===//
-#include <string.h>
#include "lldb/Core/RegularExpression.h"
+
+// C Includes
+// C++ Includes
+#include <cstring>
+
+// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
-#include "lldb/Core/Error.h"
+// Project includes
+#include "lldb/Core/Error.h"
//----------------------------------------------------------------------
// Enable enhanced mode if it is available. This allows for things like
@@ -26,15 +32,12 @@
using namespace lldb_private;
-//----------------------------------------------------------------------
-// Default constructor
-//----------------------------------------------------------------------
RegularExpression::RegularExpression() :
m_re(),
m_comp_err (1),
m_preg()
{
- memset(&m_preg,0,sizeof(m_preg));
+ memset(&m_preg, 0, sizeof(m_preg));
}
//----------------------------------------------------------------------
@@ -63,6 +66,7 @@ RegularExpression::operator= (const RegularExpression &rhs)
Compile (rhs.GetText());
return *this;
}
+
//----------------------------------------------------------------------
// Destructor
//
@@ -117,7 +121,7 @@ bool
RegularExpression::Execute (const char* s, Match *match) const
{
int err = 1;
- if (s != NULL && m_comp_err == 0)
+ if (s != nullptr && m_comp_err == 0)
{
if (match)
{
@@ -129,11 +133,11 @@ RegularExpression::Execute (const char* s, Match *match) const
}
else
{
- err = ::regexec (&m_preg,
- s,
- 0,
- NULL,
- 0);
+ err = ::regexec(&m_preg,
+ s,
+ 0,
+ nullptr,
+ 0);
}
}
@@ -202,7 +206,6 @@ RegularExpression::Match::GetMatchSpanningIndices (const char* s, uint32_t idx1,
return false;
}
-
//----------------------------------------------------------------------
// Returns true if the regular expression compiled and is ready
// for execution.
@@ -220,9 +223,7 @@ RegularExpression::IsValid () const
const char*
RegularExpression::GetText () const
{
- if (m_re.empty())
- return NULL;
- return m_re.c_str();
+ return (m_re.empty() ? nullptr : m_re.c_str());
}
//----------------------------------------------------------------------
diff --git a/source/Core/Scalar.cpp b/source/Core/Scalar.cpp
index 586969b2d50a..d3e9a7565046 100644
--- a/source/Core/Scalar.cpp
+++ b/source/Core/Scalar.cpp
@@ -9,10 +9,16 @@
#include "lldb/Core/Scalar.h"
-#include <math.h>
-#include <inttypes.h>
-#include <stdio.h>
+// C Includes
+// C++ Includes
+#include <cinttypes>
+#include <cmath>
+#include <cstdio>
+// Other libraries and framework includes
+#include "llvm/ADT/SmallString.h"
+
+// Project includes
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Stream.h"
@@ -72,19 +78,12 @@ PromoteToMaxType
return Scalar::e_void;
}
-
-//----------------------------------------------------------------------
-// Scalar constructor
-//----------------------------------------------------------------------
Scalar::Scalar() :
m_type(e_void),
m_float((float)0)
{
}
-//----------------------------------------------------------------------
-// Scalar copy constructor
-//----------------------------------------------------------------------
Scalar::Scalar(const Scalar& rhs) :
m_type(rhs.m_type),
m_integer(rhs.m_integer),
@@ -137,10 +136,10 @@ bool
Scalar::GetData (DataExtractor &data, size_t limit_byte_size) const
{
size_t byte_size = GetByteSize();
- static float f_val;
- static double d_val;
if (byte_size > 0)
{
+ const uint8_t *bytes = reinterpret_cast<const uint8_t *>(GetBytes());
+
if (limit_byte_size < byte_size)
{
if (endian::InlHostByteOrder() == eByteOrderLittle)
@@ -148,110 +147,33 @@ Scalar::GetData (DataExtractor &data, size_t limit_byte_size) const
// On little endian systems if we want fewer bytes from the
// current type we just specify fewer bytes since the LSByte
// is first...
- switch(m_type)
- {
- case e_void:
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- data.SetData((const uint8_t *)m_integer.getRawData(), limit_byte_size, endian::InlHostByteOrder());
- return true;
- case e_float:
- f_val = m_float.convertToFloat();
- data.SetData((uint8_t *)&f_val, limit_byte_size, endian::InlHostByteOrder());
- return true;
- case e_double:
- d_val = m_float.convertToDouble();
- data.SetData((uint8_t *)&d_val, limit_byte_size, endian::InlHostByteOrder());
- return true;
- case e_long_double:
- static llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- data.SetData((const uint8_t *)ldbl_val.getRawData(), limit_byte_size, endian::InlHostByteOrder());
- return true;
- }
+ byte_size = limit_byte_size;
}
else if (endian::InlHostByteOrder() == eByteOrderBig)
{
// On big endian systems if we want fewer bytes from the
// current type have to advance our initial byte pointer and
// trim down the number of bytes since the MSByte is first
- switch(m_type)
- {
- case e_void:
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- data.SetData((const uint8_t *)m_integer.getRawData() + byte_size - limit_byte_size, limit_byte_size, endian::InlHostByteOrder());
- return true;
- case e_float:
- f_val = m_float.convertToFloat();
- data.SetData((uint8_t *)&f_val + byte_size - limit_byte_size, limit_byte_size, endian::InlHostByteOrder());
- return true;
- case e_double:
- d_val = m_float.convertToDouble();
- data.SetData((uint8_t *)&d_val + byte_size - limit_byte_size, limit_byte_size, endian::InlHostByteOrder());
- return true;
- case e_long_double:
- static llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- data.SetData((const uint8_t *)ldbl_val.getRawData() + byte_size - limit_byte_size, limit_byte_size, endian::InlHostByteOrder());
- return true;
- }
- }
- }
- else
- {
- // We want all of the data
- switch(m_type)
- {
- case e_void:
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- data.SetData((const uint8_t *)m_integer.getRawData(), byte_size, endian::InlHostByteOrder());
- return true;
- case e_float:
- f_val = m_float.convertToFloat();
- data.SetData((uint8_t *)&f_val, byte_size, endian::InlHostByteOrder());
- return true;
- case e_double:
- d_val = m_float.convertToDouble();
- data.SetData((uint8_t *)&d_val, byte_size, endian::InlHostByteOrder());
- return true;
- case e_long_double:
- static llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- data.SetData((const uint8_t *)ldbl_val.getRawData(), byte_size, endian::InlHostByteOrder());
- return true;
+ bytes += byte_size - limit_byte_size;
+ byte_size = limit_byte_size;
}
}
+
+ data.SetData(bytes, byte_size, endian::InlHostByteOrder());
return true;
}
data.Clear();
return false;
}
-void *
+const void *
Scalar::GetBytes() const
{
+ const uint64_t *apint_words;
+ const uint8_t *bytes;
static float_t flt_val;
static double_t dbl_val;
+ static uint64_t swapped_words[4];
switch (m_type)
{
case e_void:
@@ -262,20 +184,65 @@ Scalar::GetBytes() const
case e_ulong:
case e_slonglong:
case e_ulonglong:
+ bytes = reinterpret_cast<const uint8_t *>(m_integer.getRawData());
+ // getRawData always returns a pointer to an uint64_t. If we have a smaller type,
+ // we need to update the pointer on big-endian systems.
+ if (endian::InlHostByteOrder() == eByteOrderBig)
+ {
+ size_t byte_size = m_integer.getBitWidth() / 8;
+ if (byte_size < 8)
+ bytes += 8 - byte_size;
+ }
+ return bytes;
case e_sint128:
case e_uint128:
- return const_cast<void *>(reinterpret_cast<const void *>(m_integer.getRawData()));
+ apint_words = m_integer.getRawData();
+ // getRawData always returns a pointer to an array of two uint64_t values,
+ // where the least-significant word always comes first. On big-endian
+ // systems we need to swap the two words.
+ if (endian::InlHostByteOrder() == eByteOrderBig)
+ {
+ swapped_words[0] = apint_words[1];
+ swapped_words[1] = apint_words[0];
+ apint_words = swapped_words;
+ }
+ return reinterpret_cast<const void *>(apint_words);
+ case e_sint256:
+ case e_uint256:
+ apint_words = m_integer.getRawData();
+ // getRawData always returns a pointer to an array of four uint64_t values,
+ // where the least-significant word always comes first. On big-endian
+ // systems we need to swap the four words.
+ if (endian::InlHostByteOrder() == eByteOrderBig)
+ {
+ swapped_words[0] = apint_words[3];
+ swapped_words[1] = apint_words[2];
+ swapped_words[2] = apint_words[1];
+ swapped_words[3] = apint_words[0];
+ apint_words = swapped_words;
+ }
+ return reinterpret_cast<const void *>(apint_words);
case e_float:
flt_val = m_float.convertToFloat();
- return (void *)&flt_val;
+ return reinterpret_cast<const void *>(&flt_val);
case e_double:
dbl_val = m_float.convertToDouble();
- return (void *)&dbl_val;
+ return reinterpret_cast<const void *>(&dbl_val);
case e_long_double:
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return const_cast<void *>(reinterpret_cast<const void *>(ldbl_val.getRawData()));
+ apint_words = ldbl_val.getRawData();
+ // getRawData always returns a pointer to an array of two uint64_t values,
+ // where the least-significant word always comes first. On big-endian
+ // systems we need to swap the two words.
+ if (endian::InlHostByteOrder() == eByteOrderBig)
+ {
+ swapped_words[0] = apint_words[1];
+ swapped_words[1] = apint_words[0];
+ apint_words = swapped_words;
+ }
+ return reinterpret_cast<const void *>(apint_words);
}
- return NULL;
+ return nullptr;
}
size_t
@@ -292,7 +259,10 @@ Scalar::GetByteSize() const
case e_slonglong:
case e_ulonglong:
case e_sint128:
- case e_uint128: return (m_integer.getBitWidth() / 8);
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (m_integer.getBitWidth() / 8);
case e_float: return sizeof(float_t);
case e_double: return sizeof(double_t);
case e_long_double: return sizeof(long_double_t);
@@ -316,6 +286,8 @@ Scalar::IsZero() const
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
return llvm::APInt::isSameValue(zero_int, m_integer);
case e_float:
case e_double:
@@ -328,7 +300,6 @@ Scalar::IsZero() const
void
Scalar::GetValue (Stream *s, bool show_type) const
{
- const uint64_t *src;
if (show_type)
s->Printf("(%s) ", GetTypeAsCString());
@@ -336,25 +307,26 @@ Scalar::GetValue (Stream *s, bool show_type) const
{
case e_void:
break;
- case e_sint: s->Printf("%i", *(const sint_t *) m_integer.getRawData()); break;
- case e_uint: s->Printf("0x%8.8x", *(const uint_t *) m_integer.getRawData()); break;
- case e_slong: s->Printf("%li", *(const slong_t *) m_integer.getRawData()); break;
- case e_ulong: s->Printf("0x%8.8lx", *(const ulong_t *) m_integer.getRawData()); break;
- case e_slonglong: s->Printf("%lli", *(const slonglong_t *) m_integer.getRawData()); break;
- case e_ulonglong: s->Printf("0x%16.16llx", *(const ulonglong_t *) m_integer.getRawData()); break;
+ case e_sint:
+ case e_ulong:
+ case e_slonglong:
case e_sint128:
- src = m_integer.getRawData();
- s->Printf("%lli%lli", *(const slonglong_t *)src, *(const slonglong_t *)(src + 1));
+ case e_sint256:
+ s->Printf("%s",m_integer.toString(10,true).c_str());
break;
+ case e_uint:
+ case e_slong:
+ case e_ulonglong:
case e_uint128:
- src = m_integer.getRawData();
- s->Printf("0x%16.16llx%16.16llx", *(const ulonglong_t *)src, *(const ulonglong_t *)(src + 1));
+ case e_uint256:
+ s->Printf("%s",m_integer.toString(16,false).c_str());
break;
- case e_float: s->Printf("%f", m_float.convertToFloat()); break;
- case e_double: s->Printf("%g", m_float.convertToDouble()); break;
+ case e_float:
+ case e_double:
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- s->Printf("%Lg", *(const long_double_t *)ldbl_val.getRawData());
+ llvm::SmallString<24> string;
+ m_float.toString(string);
+ s->Printf("%s", string.c_str());
break;
}
}
@@ -373,6 +345,8 @@ Scalar::GetTypeAsCString() const
case e_ulonglong: return "unsigned long long";
case e_sint128: return "int128_t";
case e_uint128: return "unsigned int128_t";
+ case e_sint256: return "int256_t";
+ case e_uint256: return "unsigned int256_t";
case e_float: return "float";
case e_double: return "double";
case e_long_double: return "long double";
@@ -380,11 +354,6 @@ Scalar::GetTypeAsCString() const
return "<invalid Scalar type>";
}
-
-
-//----------------------------------------------------------------------
-// Scalar copy constructor
-//----------------------------------------------------------------------
Scalar&
Scalar::operator=(const Scalar& rhs)
{
@@ -405,7 +374,6 @@ Scalar::operator= (const int v)
return *this;
}
-
Scalar&
Scalar::operator= (unsigned int v)
{
@@ -499,16 +467,17 @@ Scalar::operator= (llvm::APInt rhs)
else
m_type = e_uint128;
break;
+ case 256:
+ if(m_integer.isSignedIntN(BITWIDTH_INT256))
+ m_type = e_sint256;
+ else
+ m_type = e_uint256;
+ break;
}
return *this;
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-Scalar::~Scalar()
-{
-}
+Scalar::~Scalar() = default;
bool
Scalar::Promote(Scalar::Type type)
@@ -525,63 +494,59 @@ Scalar::Promote(Scalar::Type type)
case e_void: break;
case e_sint: success = true; break;
case e_uint:
- {
- m_integer = llvm::APInt(sizeof(uint_t) * 8, *(const uint64_t *)m_integer.getRawData(), false);
+ m_integer = m_integer.sextOrTrunc(sizeof(uint_t) * 8);
success = true;
break;
- }
+
case e_slong:
- {
- m_integer = llvm::APInt(sizeof(slong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true);
+ m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
success = true;
break;
- }
+
case e_ulong:
- {
- m_integer = llvm::APInt(sizeof(ulong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false);
+ m_integer = m_integer.sextOrTrunc(sizeof(ulong_t) * 8);
success = true;
break;
- }
+
case e_slonglong:
- {
- m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true);
+ m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
success = true;
break;
- }
+
case e_ulonglong:
- {
- m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false);
+ m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8);
success = true;
break;
- }
+
case e_sint128:
case e_uint128:
- {
- m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData()));
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
success = true;
break;
- }
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- {
m_float = llvm::APFloat(m_integer.bitsToFloat());
success = true;
break;
- }
+
case e_double:
- {
m_float = llvm::APFloat(m_integer.bitsToDouble());
success = true;
break;
- }
+
case e_long_double:
- {
if(m_ieee_quad)
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
else
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
success = true;
break;
- }
}
break;
@@ -592,57 +557,54 @@ Scalar::Promote(Scalar::Type type)
case e_sint: break;
case e_uint: success = true; break;
case e_slong:
- {
- m_integer = llvm::APInt(sizeof(slong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true);
+ m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8);
success = true;
break;
- }
+
case e_ulong:
- {
- m_integer = llvm::APInt(sizeof(ulong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false);
+ m_integer = m_integer.zextOrTrunc(sizeof(ulong_t) * 8);
success = true;
break;
- }
+
case e_slonglong:
- {
- m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true);
+ m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
success = true;
break;
- }
+
case e_ulonglong:
- {
- m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false);
+ m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
success = true;
break;
- }
+
case e_sint128:
case e_uint128:
- {
- m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData()));
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
success = true;
break;
- }
- case e_float:
- {
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_float:
m_float = llvm::APFloat(m_integer.bitsToFloat());
success = true;
break;
- }
+
case e_double:
- {
m_float = llvm::APFloat(m_integer.bitsToDouble());
success = true;
break;
- }
+
case e_long_double:
- {
if(m_ieee_quad)
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
else
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
success = true;
break;
- }
}
break;
@@ -654,51 +616,49 @@ Scalar::Promote(Scalar::Type type)
case e_uint: break;
case e_slong: success = true; break;
case e_ulong:
- {
- m_integer = llvm::APInt(sizeof(ulong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false);
+ m_integer = m_integer.sextOrTrunc(sizeof(ulong_t) * 8);
success = true;
break;
- }
+
case e_slonglong:
- {
- m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true);
+ m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
success = true;
break;
- }
+
case e_ulonglong:
- {
- m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false);
+ m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8);
success = true;
break;
- }
+
case e_sint128:
case e_uint128:
- {
- m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData()));
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
success = true;
break;
- }
+
case e_float:
- {
m_float = llvm::APFloat(m_integer.bitsToFloat());
success = true;
break;
- }
+
case e_double:
- {
m_float = llvm::APFloat(m_integer.bitsToDouble());
success = true;
break;
- }
+
case e_long_double:
- {
if(m_ieee_quad)
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
else
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
success = true;
break;
- }
}
break;
@@ -711,45 +671,44 @@ Scalar::Promote(Scalar::Type type)
case e_slong: break;
case e_ulong: success = true; break;
case e_slonglong:
- {
- m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true);
+ m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
success = true;
break;
- }
+
case e_ulonglong:
- {
- m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false);
+ m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
success = true;
break;
- }
+
case e_sint128:
case e_uint128:
- {
- m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData()));
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
success = true;
break;
- }
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- {
m_float = llvm::APFloat(m_integer.bitsToFloat());
success = true;
break;
- }
+
case e_double:
- {
m_float = llvm::APFloat(m_integer.bitsToDouble());
success = true;
break;
- }
+
case e_long_double:
- {
if(m_ieee_quad)
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
else
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
success = true;
break;
- }
}
break;
@@ -763,39 +722,39 @@ Scalar::Promote(Scalar::Type type)
case e_ulong: break;
case e_slonglong: success = true; break;
case e_ulonglong:
- {
- m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false);
+ m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8);
success = true;
break;
- }
+
case e_sint128:
case e_uint128:
- {
- m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData()));
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
success = true;
break;
- }
+
case e_float:
- {
m_float = llvm::APFloat(m_integer.bitsToFloat());
success = true;
break;
- }
+
case e_double:
- {
m_float = llvm::APFloat(m_integer.bitsToDouble());
success = true;
break;
- }
+
case e_long_double:
- {
if(m_ieee_quad)
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
else
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
success = true;
break;
- }
}
break;
@@ -811,32 +770,33 @@ Scalar::Promote(Scalar::Type type)
case e_ulonglong: success = true; break;
case e_sint128:
case e_uint128:
- {
- m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData()));
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
success = true;
break;
- }
+
case e_float:
- {
m_float = llvm::APFloat(m_integer.bitsToFloat());
success = true;
break;
- }
+
case e_double:
- {
m_float = llvm::APFloat(m_integer.bitsToDouble());
success = true;
break;
- }
+
case e_long_double:
- {
if(m_ieee_quad)
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
else
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
success = true;
break;
- }
}
break;
@@ -852,32 +812,33 @@ Scalar::Promote(Scalar::Type type)
case e_ulonglong: break;
case e_sint128: success = true; break;
case e_uint128:
- {
- m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData()));
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
success = true;
break;
- }
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- {
m_float = llvm::APFloat(m_integer.bitsToFloat());
success = true;
break;
- }
+
case e_double:
- {
m_float = llvm::APFloat(m_integer.bitsToDouble());
success = true;
break;
- }
+
case e_long_double:
- {
if(m_ieee_quad)
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
else
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
success = true;
break;
- }
}
break;
@@ -893,30 +854,104 @@ Scalar::Promote(Scalar::Type type)
case e_ulonglong:
case e_sint128: break;
case e_uint128: success = true; break;
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- {
m_float = llvm::APFloat(m_integer.bitsToFloat());
success = true;
break;
- }
+
case e_double:
- {
m_float = llvm::APFloat(m_integer.bitsToDouble());
success = true;
break;
- }
+
case e_long_double:
- {
if(m_ieee_quad)
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
else
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
success = true;
break;
- }
}
break;
+ case e_sint256:
+ switch (type)
+ {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128: break;
+ case e_sint256: success = true; break;
+ case e_uint256:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_float:
+ m_float = llvm::APFloat(m_integer.bitsToFloat());
+ success = true;
+ break;
+
+ case e_double:
+ m_float = llvm::APFloat(m_integer.bitsToDouble());
+ success = true;
+ break;
+
+ case e_long_double:
+ if(m_ieee_quad)
+ m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
+ else
+ m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
+ success = true;
+ break;
+ }
+ break;
+
+ case e_uint256:
+ switch (type)
+ {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256: break;
+ case e_uint256: success = true; break;
+ case e_float:
+ m_float = llvm::APFloat(m_integer.bitsToFloat());
+ success = true;
+ break;
+
+ case e_double:
+ m_float = llvm::APFloat(m_integer.bitsToDouble());
+ success = true;
+ break;
+
+ case e_long_double:
+ if(m_ieee_quad)
+ m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
+ else
+ m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
+ success = true;
+ break;
+ }
+ break;
+
case e_float:
switch (type)
{
@@ -928,23 +963,22 @@ Scalar::Promote(Scalar::Type type)
case e_slonglong:
case e_ulonglong:
case e_sint128:
- case e_uint128: break;
+ case e_uint128:
+ case e_sint256:
+ case e_uint256: break;
case e_float: success = true; break;
case e_double:
- {
m_float = llvm::APFloat((float_t)m_float.convertToFloat());
success = true;
break;
- }
+
case e_long_double:
- {
if(m_ieee_quad)
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_float.bitcastToAPInt());
else
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_float.bitcastToAPInt());
success = true;
break;
- }
}
break;
@@ -960,17 +994,17 @@ Scalar::Promote(Scalar::Type type)
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
case e_float: break;
case e_double: success = true; break;
case e_long_double:
- {
if(m_ieee_quad)
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_float.bitcastToAPInt());
else
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_float.bitcastToAPInt());
success = true;
break;
- }
}
break;
@@ -986,6 +1020,8 @@ Scalar::Promote(Scalar::Type type)
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
case e_float:
case e_double: break;
case e_long_double: success = true; break;
@@ -1015,11 +1051,12 @@ Scalar::GetValueTypeAsCString (Scalar::Type type)
case e_long_double: return "long double";
case e_sint128: return "int128_t";
case e_uint128: return "uint128_t";
+ case e_sint256: return "int256_t";
+ case e_uint256: return "uint256_t";
}
return "???";
}
-
Scalar::Type
Scalar::GetValueTypeForSignedIntegerWithByteSize (size_t byte_size)
{
@@ -1073,78 +1110,78 @@ Scalar::Cast(Scalar::Type type)
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
switch (type)
{
case e_void: break;
case e_sint:
- {
m_integer = m_integer.sextOrTrunc(sizeof(sint_t) * 8);
success = true;
break;
- }
+
case e_uint:
- {
m_integer = m_integer.zextOrTrunc(sizeof(sint_t) * 8);
success = true;
break;
- }
+
case e_slong:
- {
m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
success = true;
break;
- }
+
case e_ulong:
- {
m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8);
success = true;
break;
- }
+
case e_slonglong:
- {
m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
success = true;
break;
- }
+
case e_ulonglong:
- {
m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
success = true;
break;
- }
+
case e_sint128:
- {
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
success = true;
break;
- }
+
case e_uint128:
- {
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
success = true;
break;
- }
+
+ case e_sint256:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_uint256:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- {
m_float = llvm::APFloat(m_integer.bitsToFloat());
success = true;
break;
- }
+
case e_double:
- {
m_float = llvm::APFloat(m_integer.bitsToDouble());
success = true;
break;
- }
+
case e_long_double:
- {
if(m_ieee_quad)
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
else
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
success = true;
break;
- }
}
break;
@@ -1159,7 +1196,9 @@ Scalar::Cast(Scalar::Type type)
case e_slonglong:
case e_ulonglong:
case e_sint128:
- case e_uint128: m_integer = m_float.bitcastToAPInt(); success = true; break;
+ case e_uint128:
+ case e_sint256:
+ case e_uint256: m_integer = m_float.bitcastToAPInt(); success = true; break;
case e_float: m_float = llvm::APFloat(m_float.convertToFloat()); success = true; break;
case e_double: m_float = llvm::APFloat(m_float.convertToFloat()); success = true; break;
case e_long_double:
@@ -1183,7 +1222,9 @@ Scalar::Cast(Scalar::Type type)
case e_slonglong:
case e_ulonglong:
case e_sint128:
- case e_uint128: m_integer = m_float.bitcastToAPInt(); success = true; break;
+ case e_uint128:
+ case e_sint256:
+ case e_uint256: m_integer = m_float.bitcastToAPInt(); success = true; break;
case e_float: m_float = llvm::APFloat(m_float.convertToDouble()); success = true; break;
case e_double: m_float = llvm::APFloat(m_float.convertToDouble()); success = true; break;
case e_long_double:
@@ -1201,61 +1242,65 @@ Scalar::Cast(Scalar::Type type)
{
case e_void: break;
case e_sint:
- {
m_integer = m_float.bitcastToAPInt();
m_integer = m_integer.sextOrTrunc(sizeof(sint_t) * 8);
success = true;
break;
- }
+
case e_uint:
- {
m_integer = m_float.bitcastToAPInt();
m_integer = m_integer.zextOrTrunc(sizeof(sint_t) * 8);
success = true;
break;
- }
+
case e_slong:
- {
m_integer = m_float.bitcastToAPInt();
m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
success = true;
break;
- }
+
case e_ulong:
- {
m_integer = m_float.bitcastToAPInt();
m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8);
success = true;
break;
- }
+
case e_slonglong:
- {
m_integer = m_float.bitcastToAPInt();
m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
success = true;
break;
- }
+
case e_ulonglong:
- {
m_integer = m_float.bitcastToAPInt();
m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
success = true;
break;
- }
+
case e_sint128:
- {
m_integer = m_float.bitcastToAPInt();
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
success = true;
break;
- }
+
case e_uint128:
- {
m_integer = m_float.bitcastToAPInt();
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
success = true;
break;
- }
+
+ case e_sint256:
+ m_integer = m_float.bitcastToAPInt();
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_uint256:
+ m_integer = m_float.bitcastToAPInt();
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float: m_float = llvm::APFloat(m_float.convertToFloat()); success = true; break;
case e_double: m_float = llvm::APFloat(m_float.convertToFloat()); success = true; break;
case e_long_double: success = true; break;
@@ -1283,7 +1328,9 @@ Scalar::MakeSigned ()
case e_slonglong: success = true; break;
case e_ulonglong: m_type = e_slonglong; success = true; break;
case e_sint128: success = true; break;
- case e_uint128: m_type = e_sint; success = true; break;
+ case e_uint128: m_type = e_sint128; success = true; break;
+ case e_sint256: success = true; break;
+ case e_uint256: m_type = e_sint256; success = true; break;
case e_float: success = true; break;
case e_double: success = true; break;
case e_long_double: success = true; break;
@@ -1292,7 +1339,33 @@ Scalar::MakeSigned ()
return success;
}
-char
+bool
+Scalar::MakeUnsigned ()
+{
+ bool success = false;
+
+ switch (m_type)
+ {
+ case e_void: break;
+ case e_sint: success = true; break;
+ case e_uint: m_type = e_uint; success = true; break;
+ case e_slong: success = true; break;
+ case e_ulong: m_type = e_ulong; success = true; break;
+ case e_slonglong: success = true; break;
+ case e_ulonglong: m_type = e_ulonglong; success = true; break;
+ case e_sint128: success = true; break;
+ case e_uint128: m_type = e_uint128; success = true; break;
+ case e_sint256: success = true; break;
+ case e_uint256: m_type = e_uint256; success = true; break;
+ case e_float: success = true; break;
+ case e_double: success = true; break;
+ case e_long_double: success = true; break;
+ }
+
+ return success;
+}
+
+signed char
Scalar::SChar(char fail_value) const
{
switch (m_type)
@@ -1306,14 +1379,16 @@ Scalar::SChar(char fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
- return *(const schar_t *)(m_integer.sextOrTrunc(sizeof(schar_t) * 8)).getRawData();
+ case e_sint256:
+ case e_uint256:
+ return (schar_t)(m_integer.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue();
case e_float:
return (schar_t)m_float.convertToFloat();
case e_double:
return (schar_t)m_float.convertToDouble();
case e_long_double:
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (schar_t)*ldbl_val.getRawData();
+ return (schar_t)(ldbl_val.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue();
}
return fail_value;
}
@@ -1332,14 +1407,16 @@ Scalar::UChar(unsigned char fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
- return *(const uchar_t *)m_integer.getRawData();
+ case e_sint256:
+ case e_uint256:
+ return (uchar_t)(m_integer.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue();
case e_float:
return (uchar_t)m_float.convertToFloat();
case e_double:
return (uchar_t)m_float.convertToDouble();
case e_long_double:
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (uchar_t)*ldbl_val.getRawData();
+ return (uchar_t)(ldbl_val.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue();
}
return fail_value;
}
@@ -1358,14 +1435,16 @@ Scalar::SShort(short fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
- return *(const sshort_t *)(m_integer.sextOrTrunc(sizeof(sshort_t) * 8)).getRawData();
+ case e_sint256:
+ case e_uint256:
+ return (sshort_t)(m_integer.sextOrTrunc(sizeof(sshort_t) * 8)).getSExtValue();
case e_float:
return (sshort_t)m_float.convertToFloat();
case e_double:
return (sshort_t)m_float.convertToDouble();
case e_long_double:
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return *(const sshort_t *)ldbl_val.getRawData();
+ return (sshort_t)(ldbl_val.sextOrTrunc(sizeof(sshort_t) * 8)).getSExtValue();
}
return fail_value;
}
@@ -1384,14 +1463,16 @@ Scalar::UShort(unsigned short fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
- return *(const ushort_t *)m_integer.getRawData();
+ case e_sint256:
+ case e_uint256:
+ return (ushort_t)(m_integer.zextOrTrunc(sizeof(ushort_t) * 8)).getZExtValue();
case e_float:
return (ushort_t)m_float.convertToFloat();
case e_double:
return (ushort_t)m_float.convertToDouble();
case e_long_double:
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return *(const ushort_t *)ldbl_val.getRawData();;
+ return (ushort_t)(ldbl_val.zextOrTrunc(sizeof(ushort_t) * 8)).getZExtValue();
}
return fail_value;
}
@@ -1410,14 +1491,16 @@ Scalar::SInt(int fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
- return *(const sint_t *)(m_integer.sextOrTrunc(sizeof(sint_t) * 8)).getRawData();
+ case e_sint256:
+ case e_uint256:
+ return (sint_t)(m_integer.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue();
case e_float:
return (sint_t)m_float.convertToFloat();
case e_double:
return (sint_t)m_float.convertToDouble();
case e_long_double:
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return *(const sint_t *)ldbl_val.getRawData();
+ return (sint_t)(ldbl_val.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue();
}
return fail_value;
}
@@ -1436,19 +1519,20 @@ Scalar::UInt(unsigned int fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
- return *(const uint_t *)m_integer.getRawData();
+ case e_sint256:
+ case e_uint256:
+ return (uint_t)(m_integer.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue();
case e_float:
return (uint_t)m_float.convertToFloat();
case e_double:
return (uint_t)m_float.convertToDouble();
case e_long_double:
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return *(const uint_t *)ldbl_val.getRawData();
+ return (uint_t)(ldbl_val.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue();
}
return fail_value;
}
-
long
Scalar::SLong(long fail_value) const
{
@@ -1463,20 +1547,20 @@ Scalar::SLong(long fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
- return *(const slong_t *)(m_integer.sextOrTrunc(sizeof(slong_t) * 8)).getRawData();
+ case e_sint256:
+ case e_uint256:
+ return (slong_t)(m_integer.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue();
case e_float:
return (slong_t)m_float.convertToFloat();
case e_double:
return (slong_t)m_float.convertToDouble();
case e_long_double:
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return *(const slong_t *)ldbl_val.getRawData();
+ return (slong_t)(ldbl_val.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue();
}
return fail_value;
}
-
-
unsigned long
Scalar::ULong(unsigned long fail_value) const
{
@@ -1491,48 +1575,20 @@ Scalar::ULong(unsigned long fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
- return *(const ulong_t *)m_integer.getRawData();
+ case e_sint256:
+ case e_uint256:
+ return (ulong_t)(m_integer.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue();
case e_float:
return (ulong_t)m_float.convertToFloat();
case e_double:
return (ulong_t)m_float.convertToDouble();
case e_long_double:
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return *(const ulong_t *)ldbl_val.getRawData();
+ return (ulong_t)(ldbl_val.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue();
}
return fail_value;
}
-uint64_t
-Scalar::GetRawBits64(uint64_t fail_value) const
-{
- switch (m_type)
- {
- case e_void:
- break;
-
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- return *m_integer.getRawData();
- case e_float:
- return (uint64_t)m_float.convertToFloat();
- case e_double:
- return (uint64_t)m_float.convertToDouble();
- case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return *ldbl_val.getRawData();
- }
- return fail_value;
-}
-
-
-
long long
Scalar::SLongLong(long long fail_value) const
{
@@ -1547,19 +1603,20 @@ Scalar::SLongLong(long long fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
- return *(const slonglong_t *)(m_integer.sextOrTrunc(sizeof(slonglong_t) * 8)).getRawData();
+ case e_sint256:
+ case e_uint256:
+ return (slonglong_t)(m_integer.sextOrTrunc(sizeof(slonglong_t) * 8)).getSExtValue();
case e_float:
return (slonglong_t)m_float.convertToFloat();
case e_double:
return (slonglong_t)m_float.convertToDouble();
case e_long_double:
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return *(const slonglong_t *)ldbl_val.getRawData();
+ return (slonglong_t)(ldbl_val.sextOrTrunc(sizeof(slonglong_t) * 8)).getSExtValue();
}
return fail_value;
}
-
unsigned long long
Scalar::ULongLong(unsigned long long fail_value) const
{
@@ -1574,14 +1631,41 @@ Scalar::ULongLong(unsigned long long fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
- return *(const ulonglong_t *)m_integer.getRawData();
+ case e_sint256:
+ case e_uint256:
+ return (ulonglong_t)(m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue();
case e_float:
return (ulonglong_t)m_float.convertToFloat();
case e_double:
return (ulonglong_t)m_float.convertToDouble();
case e_long_double:
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return *(const ulonglong_t *)ldbl_val.getRawData();
+ return (ulonglong_t)(ldbl_val.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue();
+ }
+ return fail_value;
+}
+
+llvm::APInt
+Scalar::SInt128(llvm::APInt& fail_value) const
+{
+ switch (m_type)
+ {
+ case e_void: break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return m_integer;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ return m_float.bitcastToAPInt();
}
return fail_value;
}
@@ -1600,6 +1684,8 @@ Scalar::UInt128(const llvm::APInt& fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
return m_integer;
case e_float:
case e_double:
@@ -1610,7 +1696,7 @@ Scalar::UInt128(const llvm::APInt& fail_value) const
}
llvm::APInt
-Scalar::SInt128(llvm::APInt& fail_value) const
+Scalar::SInt256(llvm::APInt& fail_value) const
{
switch (m_type)
{
@@ -1623,6 +1709,8 @@ Scalar::SInt128(llvm::APInt& fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
return m_integer;
case e_float:
case e_double:
@@ -1632,6 +1720,31 @@ Scalar::SInt128(llvm::APInt& fail_value) const
return fail_value;
}
+llvm::APInt
+Scalar::UInt256(const llvm::APInt& fail_value) const
+{
+ switch (m_type)
+ {
+ case e_void: break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return m_integer;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ return m_float.bitcastToAPInt();
+ }
+ return fail_value;
+}
+
float
Scalar::Float(float fail_value) const
{
@@ -1646,6 +1759,8 @@ Scalar::Float(float fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
return m_integer.bitsToFloat();
case e_float:
return m_float.convertToFloat();
@@ -1658,7 +1773,6 @@ Scalar::Float(float fail_value) const
return fail_value;
}
-
double
Scalar::Double(double fail_value) const
{
@@ -1673,6 +1787,8 @@ Scalar::Double(double fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
return m_integer.bitsToDouble();
case e_float:
return (double_t)m_float.convertToFloat();
@@ -1685,7 +1801,6 @@ Scalar::Double(double fail_value) const
return fail_value;
}
-
long double
Scalar::LongDouble(long double fail_value) const
{
@@ -1700,6 +1815,8 @@ Scalar::LongDouble(long double fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
return (long_double_t)m_integer.bitsToDouble();
case e_float:
return (long_double_t)m_float.convertToFloat();
@@ -1712,7 +1829,6 @@ Scalar::LongDouble(long double fail_value) const
return fail_value;
}
-
Scalar&
Scalar::operator+= (const Scalar& rhs)
{
@@ -1732,17 +1848,16 @@ Scalar::operator+= (const Scalar& rhs)
case e_ulonglong:
case e_sint128:
case e_uint128:
- {
+ case e_sint256:
+ case e_uint256:
m_integer = a->m_integer + b->m_integer;
break;
- }
+
case e_float:
case e_double:
case e_long_double:
- {
m_float = a->m_float + b->m_float;
break;
- }
}
}
return *this;
@@ -1768,6 +1883,8 @@ Scalar::operator<<= (const Scalar& rhs)
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
switch (rhs.m_type)
{
case e_void:
@@ -1784,10 +1901,10 @@ Scalar::operator<<= (const Scalar& rhs)
case e_ulonglong:
case e_sint128:
case e_uint128:
- {
- m_integer <<= *rhs.m_integer.getRawData();
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer << rhs.m_integer;
break;
- }
}
break;
}
@@ -1814,6 +1931,8 @@ Scalar::ShiftRightLogical(const Scalar& rhs)
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
switch (rhs.m_type)
{
case e_void:
@@ -1830,14 +1949,16 @@ Scalar::ShiftRightLogical(const Scalar& rhs)
case e_ulonglong:
case e_sint128:
case e_uint128:
- m_integer = m_integer.lshr(*(const uint_t *) rhs.m_integer.getRawData()); break;
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.lshr(rhs.m_integer);
+ break;
}
break;
}
return m_type != e_void;
}
-
Scalar&
Scalar::operator>>= (const Scalar& rhs)
{
@@ -1858,6 +1979,8 @@ Scalar::operator>>= (const Scalar& rhs)
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
switch (rhs.m_type)
{
case e_void:
@@ -1872,19 +1995,18 @@ Scalar::operator>>= (const Scalar& rhs)
case e_ulong:
case e_slonglong:
case e_ulonglong:
- case e_sint128:
- case e_uint128:
- {
- m_integer >> *rhs.m_integer.getRawData();
- break;
- }
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.ashr(rhs.m_integer);
+ break;
}
break;
}
return *this;
}
-
Scalar&
Scalar::operator&= (const Scalar& rhs)
{
@@ -1905,6 +2027,8 @@ Scalar::operator&= (const Scalar& rhs)
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
switch (rhs.m_type)
{
case e_void:
@@ -1919,20 +2043,18 @@ Scalar::operator&= (const Scalar& rhs)
case e_ulong:
case e_slonglong:
case e_ulonglong:
- case e_sint128:
- case e_uint128:
- {
- m_integer &= rhs.m_integer;
- break;
- }
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer &= rhs.m_integer;
+ break;
}
break;
}
return *this;
}
-
-
bool
Scalar::AbsoluteValue()
{
@@ -1945,6 +2067,7 @@ Scalar::AbsoluteValue()
case e_slong:
case e_slonglong:
case e_sint128:
+ case e_sint256:
if (m_integer.isNegative())
m_integer = -m_integer;
return true;
@@ -1953,6 +2076,7 @@ Scalar::AbsoluteValue()
case e_ulong:
case e_ulonglong: return true;
case e_uint128:
+ case e_uint256:
case e_float:
case e_double:
case e_long_double:
@@ -1962,7 +2086,6 @@ Scalar::AbsoluteValue()
return false;
}
-
bool
Scalar::UnaryNegate()
{
@@ -1977,6 +2100,8 @@ Scalar::UnaryNegate()
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
m_integer = -m_integer; return true;
case e_float:
case e_double:
@@ -1999,6 +2124,8 @@ Scalar::OnesComplement()
case e_ulonglong:
case e_sint128:
case e_uint128:
+ case e_sint256:
+ case e_uint256:
m_integer = ~m_integer; return true;
case e_void:
@@ -2010,7 +2137,6 @@ Scalar::OnesComplement()
return false;
}
-
const Scalar
lldb_private::operator+ (const Scalar& lhs, const Scalar& rhs)
{
@@ -2031,6 +2157,8 @@ lldb_private::operator+ (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_ulonglong:
case Scalar::e_sint128:
case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
result.m_integer = a->m_integer + b->m_integer; break;
case Scalar::e_float:
case Scalar::e_double:
@@ -2041,7 +2169,6 @@ lldb_private::operator+ (const Scalar& lhs, const Scalar& rhs)
return result;
}
-
const Scalar
lldb_private::operator- (const Scalar& lhs, const Scalar& rhs)
{
@@ -2062,6 +2189,8 @@ lldb_private::operator- (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_ulonglong:
case Scalar::e_sint128:
case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
result.m_integer = a->m_integer - b->m_integer; break;
case Scalar::e_float:
case Scalar::e_double:
@@ -2085,21 +2214,27 @@ lldb_private::operator/ (const Scalar& lhs, const Scalar& rhs)
{
case Scalar::e_void: break;
case Scalar::e_sint:
- case Scalar::e_uint:
case Scalar::e_slong:
- case Scalar::e_ulong:
case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ if (b->m_integer != 0)
+ {
+ result.m_integer = a->m_integer.sdiv(b->m_integer);
+ return result;
+ }
+ break;
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
case Scalar::e_uint128:
- {
+ case Scalar::e_uint256:
if (b->m_integer != 0)
{
- result.m_integer = *a->m_integer.getRawData() / *b->m_integer.getRawData();
+ result.m_integer = a->m_integer.udiv(b->m_integer);
return result;
}
break;
- }
case Scalar::e_float:
case Scalar::e_double:
case Scalar::e_long_double:
@@ -2137,6 +2272,8 @@ lldb_private::operator* (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_ulonglong:
case Scalar::e_sint128:
case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
result.m_integer = a->m_integer * b->m_integer; break;
case Scalar::e_float:
case Scalar::e_double:
@@ -2166,6 +2303,8 @@ lldb_private::operator& (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_ulonglong:
case Scalar::e_sint128:
case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
result.m_integer = a->m_integer & b->m_integer; break;
case Scalar::e_void:
case Scalar::e_float:
@@ -2198,6 +2337,8 @@ lldb_private::operator| (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_ulonglong:
case Scalar::e_sint128:
case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
result.m_integer = a->m_integer | b->m_integer; break;
case Scalar::e_void:
@@ -2224,23 +2365,29 @@ lldb_private::operator% (const Scalar& lhs, const Scalar& rhs)
switch (result.m_type)
{
default: break;
- case Scalar::e_void: break;
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- {
- if (b->m_integer != 0)
- {
- result.m_integer = *a->m_integer.getRawData() % *b->m_integer.getRawData();
- return result;
- }
- break;
- }
+ case Scalar::e_void: break;
+ case Scalar::e_sint:
+ case Scalar::e_slong:
+ case Scalar::e_slonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ if (b->m_integer != 0)
+ {
+ result.m_integer = a->m_integer.srem(b->m_integer);
+ return result;
+ }
+ break;
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ if (b->m_integer != 0)
+ {
+ result.m_integer = a->m_integer.urem(b->m_integer);
+ return result;
+ }
+ break;
}
}
result.m_type = Scalar::e_void;
@@ -2266,6 +2413,8 @@ lldb_private::operator^ (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_ulonglong:
case Scalar::e_sint128:
case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
result.m_integer = a->m_integer ^ b->m_integer; break;
case Scalar::e_void:
@@ -2296,33 +2445,11 @@ lldb_private::operator>> (const Scalar& lhs, const Scalar &rhs)
return result;
}
-// Return the raw unsigned integer without any casting or conversion
-unsigned int
-Scalar::RawUInt () const
-{
- return *(const uint_t *) m_integer.getRawData();
-}
-
-// Return the raw unsigned long without any casting or conversion
-unsigned long
-Scalar::RawULong () const
-{
- return *(const ulong_t *) m_integer.getRawData();
-}
-
-// Return the raw unsigned long long without any casting or conversion
-unsigned long long
-Scalar::RawULongLong () const
-{
- return *(const ulonglong_t *) m_integer.getRawData();
-}
-
-
Error
Scalar::SetValueFromCString (const char *value_str, Encoding encoding, size_t byte_size)
{
Error error;
- if (value_str == NULL || value_str[0] == '\0')
+ if (value_str == nullptr || value_str[0] == '\0')
{
error.SetErrorString ("Invalid c-string value string.");
return error;
@@ -2449,6 +2576,7 @@ Scalar::SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t b
Error error;
type128 int128;
+ type256 int256;
switch (encoding)
{
case lldb::eEncodingInvalid:
@@ -2468,20 +2596,35 @@ Scalar::SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t b
case 4: operator=((uint32_t)data.GetU32(&offset)); break;
case 8: operator=((uint64_t)data.GetU64(&offset)); break;
case 16:
- {
if (data.GetByteOrder() == eByteOrderBig)
{
int128.x[1] = (uint64_t)data.GetU64 (&offset);
- int128.x[0] = (uint64_t)data.GetU64 (&offset + 1);
+ int128.x[0] = (uint64_t)data.GetU64 (&offset);
}
else
{
int128.x[0] = (uint64_t)data.GetU64 (&offset);
- int128.x[1] = (uint64_t)data.GetU64 (&offset + 1);
+ int128.x[1] = (uint64_t)data.GetU64 (&offset);
}
operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x));
break;
- }
+ case 32:
+ if (data.GetByteOrder() == eByteOrderBig)
+ {
+ int256.x[3] = (uint64_t)data.GetU64 (&offset);
+ int256.x[2] = (uint64_t)data.GetU64 (&offset);
+ int256.x[1] = (uint64_t)data.GetU64 (&offset);
+ int256.x[0] = (uint64_t)data.GetU64 (&offset);
+ }
+ else
+ {
+ int256.x[0] = (uint64_t)data.GetU64 (&offset);
+ int256.x[1] = (uint64_t)data.GetU64 (&offset);
+ int256.x[2] = (uint64_t)data.GetU64 (&offset);
+ int256.x[3] = (uint64_t)data.GetU64 (&offset);
+ }
+ operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x));
+ break;
default:
error.SetErrorStringWithFormat("unsupported unsigned integer byte size: %" PRIu64 "", (uint64_t)byte_size);
break;
@@ -2499,20 +2642,35 @@ Scalar::SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t b
case 4: operator=((int32_t)data.GetU32(&offset)); break;
case 8: operator=((int64_t)data.GetU64(&offset)); break;
case 16:
- {
if (data.GetByteOrder() == eByteOrderBig)
{
int128.x[1] = (uint64_t)data.GetU64 (&offset);
- int128.x[0] = (uint64_t)data.GetU64 (&offset + 1);
+ int128.x[0] = (uint64_t)data.GetU64 (&offset);
}
else
{
int128.x[0] = (uint64_t)data.GetU64 (&offset);
- int128.x[1] = (uint64_t)data.GetU64 (&offset + 1);
+ int128.x[1] = (uint64_t)data.GetU64 (&offset);
}
operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x));
break;
- }
+ case 32:
+ if (data.GetByteOrder() == eByteOrderBig)
+ {
+ int256.x[3] = (uint64_t)data.GetU64 (&offset);
+ int256.x[2] = (uint64_t)data.GetU64 (&offset);
+ int256.x[1] = (uint64_t)data.GetU64 (&offset);
+ int256.x[0] = (uint64_t)data.GetU64 (&offset);
+ }
+ else
+ {
+ int256.x[0] = (uint64_t)data.GetU64 (&offset);
+ int256.x[1] = (uint64_t)data.GetU64 (&offset);
+ int256.x[2] = (uint64_t)data.GetU64 (&offset);
+ int256.x[3] = (uint64_t)data.GetU64 (&offset);
+ }
+ operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x));
+ break;
default:
error.SetErrorStringWithFormat("unsupported signed integer byte size: %" PRIu64 "", (uint64_t)byte_size);
break;
@@ -2561,6 +2719,8 @@ Scalar::SignExtend (uint32_t sign_bit_pos)
case Scalar::e_ulonglong:
case Scalar::e_sint128:
case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
if (max_bit_pos == sign_bit_pos)
return true;
else if (sign_bit_pos < (max_bit_pos-1))
@@ -2615,51 +2775,33 @@ Scalar::ExtractBitfield (uint32_t bit_size,
if (bit_size == 0)
return true;
- uint32_t msbit = bit_offset + bit_size - 1;
- uint32_t lsbit = bit_offset;
- uint64_t result;
switch (m_type)
{
case Scalar::e_void:
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
break;
- case e_float:
- result = SignedBits ((uint64_t )m_float.convertToFloat(), msbit, lsbit);
- m_float = llvm::APFloat((float_t)result);
- return true;
- case e_double:
- result = SignedBits ((uint64_t )m_float.convertToDouble(), msbit, lsbit);
- m_float = llvm::APFloat((double_t)result);
- case e_long_double:
- m_integer = m_float.bitcastToAPInt();
- result = SignedBits (*m_integer.getRawData(), msbit, lsbit);
- if(m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&result)->x));
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&result)->x));
- return true;
-
case Scalar::e_sint:
case Scalar::e_slong:
case Scalar::e_slonglong:
case Scalar::e_sint128:
- m_integer = SignedBits (*m_integer.getRawData(), msbit, lsbit);
+ case Scalar::e_sint256:
+ m_integer = m_integer.ashr(bit_offset).sextOrTrunc(bit_size).sextOrSelf(8 * GetByteSize());
return true;
case Scalar::e_uint:
case Scalar::e_ulong:
case Scalar::e_ulonglong:
case Scalar::e_uint128:
- m_integer = UnsignedBits (*m_integer.getRawData(), msbit, lsbit);
+ case Scalar::e_uint256:
+ m_integer = m_integer.lshr(bit_offset).zextOrTrunc(bit_size).zextOrSelf(8 * GetByteSize());
return true;
}
return false;
}
-
-
-
-
bool
lldb_private::operator== (const Scalar& lhs, const Scalar& rhs)
{
@@ -2682,6 +2824,8 @@ lldb_private::operator== (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_ulonglong:
case Scalar::e_sint128:
case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
return a->m_integer == b->m_integer;
case Scalar::e_float:
case Scalar::e_double:
@@ -2715,6 +2859,8 @@ lldb_private::operator!= (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_ulonglong:
case Scalar::e_sint128:
case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
return a->m_integer != b->m_integer;
case Scalar::e_float:
case Scalar::e_double:
@@ -2743,11 +2889,13 @@ lldb_private::operator< (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_slong:
case Scalar::e_slonglong:
case Scalar::e_sint128:
+ case Scalar::e_sint256:
return a->m_integer.slt(b->m_integer);
case Scalar::e_uint:
case Scalar::e_ulong:
case Scalar::e_ulonglong:
case Scalar::e_uint128:
+ case Scalar::e_uint256:
return a->m_integer.ult(b->m_integer);
case Scalar::e_float:
case Scalar::e_double:
@@ -2776,11 +2924,13 @@ lldb_private::operator<= (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_slong:
case Scalar::e_slonglong:
case Scalar::e_sint128:
+ case Scalar::e_sint256:
return a->m_integer.sle(b->m_integer);
case Scalar::e_uint:
case Scalar::e_ulong:
case Scalar::e_ulonglong:
case Scalar::e_uint128:
+ case Scalar::e_uint256:
return a->m_integer.ule(b->m_integer);
case Scalar::e_float:
case Scalar::e_double:
@@ -2792,7 +2942,6 @@ lldb_private::operator<= (const Scalar& lhs, const Scalar& rhs)
return false;
}
-
bool
lldb_private::operator> (const Scalar& lhs, const Scalar& rhs)
{
@@ -2810,11 +2959,13 @@ lldb_private::operator> (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_slong:
case Scalar::e_slonglong:
case Scalar::e_sint128:
+ case Scalar::e_sint256:
return a->m_integer.sgt(b->m_integer);
case Scalar::e_uint:
case Scalar::e_ulong:
case Scalar::e_ulonglong:
case Scalar::e_uint128:
+ case Scalar::e_uint256:
return a->m_integer.ugt(b->m_integer);
case Scalar::e_float:
case Scalar::e_double:
@@ -2843,11 +2994,13 @@ lldb_private::operator>= (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_slong:
case Scalar::e_slonglong:
case Scalar::e_sint128:
+ case Scalar::e_sint256:
return a->m_integer.sge(b->m_integer);
case Scalar::e_uint:
case Scalar::e_ulong:
case Scalar::e_ulonglong:
case Scalar::e_uint128:
+ case Scalar::e_uint256:
return a->m_integer.uge(b->m_integer);
case Scalar::e_float:
case Scalar::e_double:
@@ -2873,7 +3026,9 @@ Scalar::ClearBit (uint32_t bit)
case e_slonglong:
case e_ulonglong:
case e_sint128:
- case e_uint128: m_integer.clearBit(bit); return true;
+ case e_uint128:
+ case e_sint256:
+ case e_uint256: m_integer.clearBit(bit); return true;
case e_float:
case e_double:
case e_long_double: break;
@@ -2895,7 +3050,9 @@ Scalar::SetBit (uint32_t bit)
case e_slonglong:
case e_ulonglong:
case e_sint128:
- case e_uint128: m_integer.setBit(bit); return true;
+ case e_uint128:
+ case e_sint256:
+ case e_uint256: m_integer.setBit(bit); return true;
case e_float:
case e_double:
case e_long_double: break;
@@ -2903,72 +3060,3 @@ Scalar::SetBit (uint32_t bit)
return false;
}
-void
-Scalar::SetType (const RegisterInfo *reg_info)
-{
- const uint32_t byte_size = reg_info->byte_size;
- switch (reg_info->encoding)
- {
- case eEncodingInvalid:
- break;
- case eEncodingUint:
- if (byte_size == 1 || byte_size == 2 || byte_size == 4)
- {
- m_integer = llvm::APInt(sizeof(uint_t) * 8, *(const uint64_t *)m_integer.getRawData(), false);
- m_type = e_uint;
- }
- if (byte_size == 8)
- {
- m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false);
- m_type = e_ulonglong;
- }
- if (byte_size == 16)
- {
- m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())->x);
- m_type = e_uint128;
- }
- break;
- case eEncodingSint:
- if (byte_size == 1 || byte_size == 2 || byte_size == 4)
- {
- m_integer = llvm::APInt(sizeof(sint_t) * 8, *(const uint64_t *)m_integer.getRawData(), true);
- m_type = e_sint;
- }
- if (byte_size == 8)
- {
- m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true);
- m_type = e_slonglong;
- }
- if (byte_size == 16)
- {
- m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())->x);
- m_type = e_sint128;
- }
- break;
- case eEncodingIEEE754:
- if (byte_size == sizeof(float))
- {
- bool losesInfo = false;
- m_float.convert(llvm::APFloat::IEEEsingle, llvm::APFloat::rmTowardZero, &losesInfo);
- m_type = e_float;
- }
- else if (byte_size == sizeof(double))
- {
- bool losesInfo = false;
- m_float.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmTowardZero, &losesInfo);
- m_type = e_double;
- }
- else if (byte_size == sizeof(long double))
- {
- if(m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_float.bitcastToAPInt());
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_float.bitcastToAPInt());
- m_type = e_long_double;
- }
- break;
- case eEncodingVector:
- m_type = e_void;
- break;
- }
-}
diff --git a/source/Core/SearchFilter.cpp b/source/Core/SearchFilter.cpp
index f54bbe8d4adf..202a40ff414d 100644
--- a/source/Core/SearchFilter.cpp
+++ b/source/Core/SearchFilter.cpp
@@ -9,9 +9,9 @@
// C Includes
// C++ Includes
+
// Other libraries and framework includes
// Project includes
-
#include "lldb/lldb-private.h"
#include "lldb/Core/SearchFilter.h"
#include "lldb/Core/Module.h"
@@ -21,56 +21,26 @@
using namespace lldb;
using namespace lldb_private;
-//----------------------------------------------------------------------
-// SearchFilter constructor
-//----------------------------------------------------------------------
-Searcher::Searcher ()
-{
+Searcher::Searcher() = default;
-}
-
-Searcher::~Searcher ()
-{
-
-}
+Searcher::~Searcher() = default;
void
Searcher::GetDescription (Stream *s)
{
}
-//----------------------------------------------------------------------
-// SearchFilter constructor
-//----------------------------------------------------------------------
SearchFilter::SearchFilter(const TargetSP &target_sp) :
m_target_sp (target_sp)
{
}
-//----------------------------------------------------------------------
-// SearchFilter copy constructor
-//----------------------------------------------------------------------
-SearchFilter::SearchFilter(const SearchFilter& rhs) :
- m_target_sp (rhs.m_target_sp)
-{
-}
+SearchFilter::SearchFilter(const SearchFilter& rhs) = default;
-//----------------------------------------------------------------------
-// SearchFilter assignment operator
-//----------------------------------------------------------------------
-const SearchFilter&
-SearchFilter::operator=(const SearchFilter& rhs)
-{
- m_target_sp = rhs.m_target_sp;
- return *this;
-}
+SearchFilter&
+SearchFilter::operator=(const SearchFilter& rhs) = default;
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-SearchFilter::~SearchFilter()
-{
-}
+SearchFilter::~SearchFilter() = default;
bool
SearchFilter::ModulePasses (const FileSpec &spec)
@@ -116,7 +86,6 @@ SearchFilter::GetDescription (Stream *s)
void
SearchFilter::Dump (Stream *s) const
{
-
}
lldb::SearchFilterSP
@@ -143,7 +112,7 @@ SearchFilter::Search (Searcher &searcher)
empty_sc.target_sp = m_target_sp;
if (searcher.GetDepth() == Searcher::eDepthTarget)
- searcher.SearchCallback (*this, empty_sc, NULL, false);
+ searcher.SearchCallback(*this, empty_sc, nullptr, false);
else
DoModuleIteration(empty_sc, searcher);
}
@@ -158,10 +127,10 @@ SearchFilter::SearchInModuleList (Searcher &searcher, ModuleList &modules)
empty_sc.target_sp = m_target_sp;
if (searcher.GetDepth() == Searcher::eDepthTarget)
- searcher.SearchCallback (*this, empty_sc, NULL, false);
+ searcher.SearchCallback(*this, empty_sc, nullptr, false);
else
{
- Mutex::Locker modules_locker(modules.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(modules.GetMutex());
const size_t numModules = modules.GetSize();
for (size_t i = 0; i < numModules; i++)
@@ -176,7 +145,6 @@ SearchFilter::SearchInModuleList (Searcher &searcher, ModuleList &modules)
}
}
-
Searcher::CallbackReturn
SearchFilter::DoModuleIteration (const lldb::ModuleSP& module_sp, Searcher &searcher)
{
@@ -194,7 +162,7 @@ SearchFilter::DoModuleIteration (const SymbolContext &context, Searcher &searche
if (searcher.GetDepth () == Searcher::eDepthModule)
{
SymbolContext matchingContext(context.module_sp.get());
- searcher.SearchCallback (*this, matchingContext, NULL, false);
+ searcher.SearchCallback(*this, matchingContext, nullptr, false);
}
else
{
@@ -204,8 +172,8 @@ SearchFilter::DoModuleIteration (const SymbolContext &context, Searcher &searche
else
{
const ModuleList &target_images = m_target_sp->GetImages();
- Mutex::Locker modules_locker(target_images.GetMutex());
-
+ std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
+
size_t n_modules = target_images.GetSize();
for (size_t i = 0; i < n_modules; i++)
{
@@ -219,7 +187,7 @@ SearchFilter::DoModuleIteration (const SymbolContext &context, Searcher &searche
{
SymbolContext matchingContext(m_target_sp, module_sp);
- Searcher::CallbackReturn shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false);
+ Searcher::CallbackReturn shouldContinue = searcher.SearchCallback(*this, matchingContext, nullptr, false);
if (shouldContinue == Searcher::eCallbackReturnStop
|| shouldContinue == Searcher::eCallbackReturnPop)
return shouldContinue;
@@ -242,7 +210,7 @@ Searcher::CallbackReturn
SearchFilter::DoCUIteration (const ModuleSP &module_sp, const SymbolContext &context, Searcher &searcher)
{
Searcher::CallbackReturn shouldContinue;
- if (context.comp_unit == NULL)
+ if (context.comp_unit == nullptr)
{
const size_t num_comp_units = module_sp->GetNumCompileUnits();
for (size_t i = 0; i < num_comp_units; i++)
@@ -257,7 +225,7 @@ SearchFilter::DoCUIteration (const ModuleSP &module_sp, const SymbolContext &con
{
SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get());
- shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false);
+ shouldContinue = searcher.SearchCallback(*this, matchingContext, nullptr, false);
if (shouldContinue == Searcher::eCallbackReturnPop)
return Searcher::eCallbackReturnContinue;
@@ -276,7 +244,7 @@ SearchFilter::DoCUIteration (const ModuleSP &module_sp, const SymbolContext &con
if (CompUnitPasses(*context.comp_unit))
{
SymbolContext matchingContext (m_target_sp, module_sp, context.comp_unit);
- return searcher.SearchCallback (*this, matchingContext, NULL, false);
+ return searcher.SearchCallback(*this, matchingContext, nullptr, false);
}
}
return Searcher::eCallbackReturnContinue;
@@ -326,30 +294,15 @@ SearchFilterForUnconstrainedSearches::DoCopyForBreakpoint (Breakpoint &breakpoin
// Selects a shared library matching a given file spec
//----------------------------------------------------------------------
-//----------------------------------------------------------------------
-// SearchFilterByModule constructors
-//----------------------------------------------------------------------
-
SearchFilterByModule::SearchFilterByModule (const lldb::TargetSP &target_sp, const FileSpec &module) :
SearchFilter (target_sp),
m_module_spec (module)
{
}
+SearchFilterByModule::SearchFilterByModule(const SearchFilterByModule& rhs) = default;
-//----------------------------------------------------------------------
-// SearchFilterByModule copy constructor
-//----------------------------------------------------------------------
-SearchFilterByModule::SearchFilterByModule(const SearchFilterByModule& rhs) :
- SearchFilter (rhs),
- m_module_spec (rhs.m_module_spec)
-{
-}
-
-//----------------------------------------------------------------------
-// SearchFilterByModule assignment operator
-//----------------------------------------------------------------------
-const SearchFilterByModule&
+SearchFilterByModule&
SearchFilterByModule::operator=(const SearchFilterByModule& rhs)
{
m_target_sp = rhs.m_target_sp;
@@ -357,20 +310,12 @@ SearchFilterByModule::operator=(const SearchFilterByModule& rhs)
return *this;
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-SearchFilterByModule::~SearchFilterByModule()
-{
-}
+SearchFilterByModule::~SearchFilterByModule() = default;
bool
SearchFilterByModule::ModulePasses (const ModuleSP &module_sp)
{
- if (module_sp && FileSpec::Equal(module_sp->GetFileSpec(), m_module_spec, false))
- return true;
- else
- return false;
+ return (module_sp && FileSpec::Equal(module_sp->GetFileSpec(), m_module_spec, false));
}
bool
@@ -388,7 +333,6 @@ SearchFilterByModule::AddressPasses (Address &address)
return true;
}
-
bool
SearchFilterByModule::CompUnitPasses (FileSpec &fileSpec)
{
@@ -411,7 +355,7 @@ SearchFilterByModule::Search (Searcher &searcher)
{
SymbolContext empty_sc;
empty_sc.target_sp = m_target_sp;
- searcher.SearchCallback (*this, empty_sc, NULL, false);
+ searcher.SearchCallback(*this, empty_sc, nullptr, false);
}
// If the module file spec is a full path, then we can just find the one
@@ -419,8 +363,8 @@ SearchFilterByModule::Search (Searcher &searcher)
// find the ones that match the file name.
const ModuleList &target_modules = m_target_sp->GetImages();
- Mutex::Locker modules_locker (target_modules.GetMutex());
-
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+
const size_t num_modules = target_modules.GetSize ();
for (size_t i = 0; i < num_modules; i++)
{
@@ -463,7 +407,6 @@ SearchFilterByModule::GetFilterRequiredItems()
void
SearchFilterByModule::Dump (Stream *s) const
{
-
}
lldb::SearchFilterSP
@@ -478,10 +421,6 @@ SearchFilterByModule::DoCopyForBreakpoint (Breakpoint &breakpoint)
// Selects a shared library matching a given file spec
//----------------------------------------------------------------------
-//----------------------------------------------------------------------
-// SearchFilterByModuleList constructors
-//----------------------------------------------------------------------
-
SearchFilterByModuleList::SearchFilterByModuleList (const lldb::TargetSP &target_sp,
const FileSpecList &module_list) :
SearchFilter (target_sp),
@@ -489,20 +428,9 @@ SearchFilterByModuleList::SearchFilterByModuleList (const lldb::TargetSP &target
{
}
+SearchFilterByModuleList::SearchFilterByModuleList(const SearchFilterByModuleList& rhs) = default;
-//----------------------------------------------------------------------
-// SearchFilterByModuleList copy constructor
-//----------------------------------------------------------------------
-SearchFilterByModuleList::SearchFilterByModuleList(const SearchFilterByModuleList& rhs) :
- SearchFilter (rhs),
- m_module_spec_list (rhs.m_module_spec_list)
-{
-}
-
-//----------------------------------------------------------------------
-// SearchFilterByModuleList assignment operator
-//----------------------------------------------------------------------
-const SearchFilterByModuleList&
+SearchFilterByModuleList&
SearchFilterByModuleList::operator=(const SearchFilterByModuleList& rhs)
{
m_target_sp = rhs.m_target_sp;
@@ -510,12 +438,7 @@ SearchFilterByModuleList::operator=(const SearchFilterByModuleList& rhs)
return *this;
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-SearchFilterByModuleList::~SearchFilterByModuleList()
-{
-}
+SearchFilterByModuleList::~SearchFilterByModuleList() = default;
bool
SearchFilterByModuleList::ModulePasses (const ModuleSP &module_sp)
@@ -523,7 +446,8 @@ SearchFilterByModuleList::ModulePasses (const ModuleSP &module_sp)
if (m_module_spec_list.GetSize() == 0)
return true;
- if (module_sp && m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
+ if (module_sp &&
+ m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
return true;
else
return false;
@@ -548,7 +472,6 @@ SearchFilterByModuleList::AddressPasses (Address &address)
return true;
}
-
bool
SearchFilterByModuleList::CompUnitPasses (FileSpec &fileSpec)
{
@@ -571,7 +494,7 @@ SearchFilterByModuleList::Search (Searcher &searcher)
{
SymbolContext empty_sc;
empty_sc.target_sp = m_target_sp;
- searcher.SearchCallback (*this, empty_sc, NULL, false);
+ searcher.SearchCallback(*this, empty_sc, nullptr, false);
}
// If the module file spec is a full path, then we can just find the one
@@ -579,8 +502,8 @@ SearchFilterByModuleList::Search (Searcher &searcher)
// find the ones that match the file name.
const ModuleList &target_modules = m_target_sp->GetImages();
- Mutex::Locker modules_locker (target_modules.GetMutex());
-
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+
const size_t num_modules = target_modules.GetSize ();
for (size_t i = 0; i < num_modules; i++)
{
@@ -645,7 +568,6 @@ SearchFilterByModuleList::GetFilterRequiredItems()
void
SearchFilterByModuleList::Dump (Stream *s) const
{
-
}
lldb::SearchFilterSP
@@ -655,16 +577,11 @@ SearchFilterByModuleList::DoCopyForBreakpoint (Breakpoint &breakpoint)
return ret_sp;
}
-
//----------------------------------------------------------------------
// SearchFilterByModuleListAndCU:
// Selects a shared library matching a given file spec
//----------------------------------------------------------------------
-//----------------------------------------------------------------------
-// SearchFilterByModuleListAndCU constructors
-//----------------------------------------------------------------------
-
SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU (const lldb::TargetSP &target_sp,
const FileSpecList &module_list,
const FileSpecList &cu_list) :
@@ -673,20 +590,9 @@ SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU (const lldb::Target
{
}
+SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU(const SearchFilterByModuleListAndCU& rhs) = default;
-//----------------------------------------------------------------------
-// SearchFilterByModuleListAndCU copy constructor
-//----------------------------------------------------------------------
-SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU(const SearchFilterByModuleListAndCU& rhs) :
- SearchFilterByModuleList (rhs),
- m_cu_spec_list (rhs.m_cu_spec_list)
-{
-}
-
-//----------------------------------------------------------------------
-// SearchFilterByModuleListAndCU assignment operator
-//----------------------------------------------------------------------
-const SearchFilterByModuleListAndCU&
+SearchFilterByModuleListAndCU&
SearchFilterByModuleListAndCU::operator=(const SearchFilterByModuleListAndCU& rhs)
{
if (&rhs != this)
@@ -698,12 +604,7 @@ SearchFilterByModuleListAndCU::operator=(const SearchFilterByModuleListAndCU& rh
return *this;
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU()
-{
-}
+SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU() = default;
bool
SearchFilterByModuleListAndCU::AddressPasses (Address &address)
@@ -711,7 +612,6 @@ SearchFilterByModuleListAndCU::AddressPasses (Address &address)
return true;
}
-
bool
SearchFilterByModuleListAndCU::CompUnitPasses (FileSpec &fileSpec)
{
@@ -747,7 +647,7 @@ SearchFilterByModuleListAndCU::Search (Searcher &searcher)
{
SymbolContext empty_sc;
empty_sc.target_sp = m_target_sp;
- searcher.SearchCallback (*this, empty_sc, NULL, false);
+ searcher.SearchCallback(*this, empty_sc, nullptr, false);
}
// If the module file spec is a full path, then we can just find the one
@@ -756,14 +656,15 @@ SearchFilterByModuleListAndCU::Search (Searcher &searcher)
ModuleList matching_modules;
const ModuleList &target_images = m_target_sp->GetImages();
- Mutex::Locker modules_locker(target_images.GetMutex());
-
+ std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
+
const size_t num_modules = target_images.GetSize ();
bool no_modules_in_filter = m_module_spec_list.GetSize() == 0;
for (size_t i = 0; i < num_modules; i++)
{
lldb::ModuleSP module_sp = target_images.GetModuleAtIndexUnlocked(i);
- if (no_modules_in_filter || m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
+ if (no_modules_in_filter ||
+ m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
{
SymbolContext matchingContext(m_target_sp, module_sp);
Searcher::CallbackReturn shouldContinue;
@@ -844,7 +745,6 @@ SearchFilterByModuleListAndCU::GetFilterRequiredItems()
void
SearchFilterByModuleListAndCU::Dump (Stream *s) const
{
-
}
lldb::SearchFilterSP
@@ -853,4 +753,3 @@ SearchFilterByModuleListAndCU::DoCopyForBreakpoint (Breakpoint &breakpoint)
SearchFilterSP ret_sp(new SearchFilterByModuleListAndCU(*this));
return ret_sp;
}
-
diff --git a/source/Core/Section.cpp b/source/Core/Section.cpp
index cf1cbac8fd7c..9622cb78970c 100644
--- a/source/Core/Section.cpp
+++ b/source/Core/Section.cpp
@@ -14,75 +14,61 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/ConvertEnum.h"
-#include <limits>
-
using namespace lldb;
using namespace lldb_private;
-Section::Section (const ModuleSP &module_sp,
- ObjectFile *obj_file,
- user_id_t sect_id,
- const ConstString &name,
- SectionType sect_type,
- addr_t file_addr,
- addr_t byte_size,
- lldb::offset_t file_offset,
- lldb::offset_t file_size,
- uint32_t log2align,
- uint32_t flags,
- uint32_t target_byte_size/*=1*/) :
- ModuleChild (module_sp),
- UserID (sect_id),
- Flags (flags),
- m_obj_file (obj_file),
- m_type (sect_type),
- m_parent_wp (),
- m_name (name),
- m_file_addr (file_addr),
- m_byte_size (byte_size),
- m_file_offset (file_offset),
- m_file_size (file_size),
- m_log2align (log2align),
- m_children (),
- m_fake (false),
- m_encrypted (false),
- m_thread_specific (false),
- m_target_byte_size(target_byte_size)
+Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file, user_id_t sect_id, const ConstString &name,
+ SectionType sect_type, addr_t file_addr, addr_t byte_size, lldb::offset_t file_offset,
+ lldb::offset_t file_size, uint32_t log2align, uint32_t flags, uint32_t target_byte_size /*=1*/)
+ : ModuleChild(module_sp),
+ UserID(sect_id),
+ Flags(flags),
+ m_obj_file(obj_file),
+ m_type(sect_type),
+ m_parent_wp(),
+ m_name(name),
+ m_file_addr(file_addr),
+ m_byte_size(byte_size),
+ m_file_offset(file_offset),
+ m_file_size(file_size),
+ m_log2align(log2align),
+ m_children(),
+ m_fake(false),
+ m_encrypted(false),
+ m_thread_specific(false),
+ m_readable(false),
+ m_writable(false),
+ m_executable(false),
+ m_target_byte_size(target_byte_size)
{
// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, name.GetCString());
}
-Section::Section (const lldb::SectionSP &parent_section_sp,
- const ModuleSP &module_sp,
- ObjectFile *obj_file,
- user_id_t sect_id,
- const ConstString &name,
- SectionType sect_type,
- addr_t file_addr,
- addr_t byte_size,
- lldb::offset_t file_offset,
- lldb::offset_t file_size,
- uint32_t log2align,
- uint32_t flags,
- uint32_t target_byte_size/*=1*/) :
- ModuleChild (module_sp),
- UserID (sect_id),
- Flags (flags),
- m_obj_file (obj_file),
- m_type (sect_type),
- m_parent_wp (),
- m_name (name),
- m_file_addr (file_addr),
- m_byte_size (byte_size),
- m_file_offset (file_offset),
- m_file_size (file_size),
- m_log2align (log2align),
- m_children (),
- m_fake (false),
- m_encrypted (false),
- m_thread_specific (false),
- m_target_byte_size(target_byte_size)
+Section::Section(const lldb::SectionSP &parent_section_sp, const ModuleSP &module_sp, ObjectFile *obj_file,
+ user_id_t sect_id, const ConstString &name, SectionType sect_type, addr_t file_addr, addr_t byte_size,
+ lldb::offset_t file_offset, lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
+ uint32_t target_byte_size /*=1*/)
+ : ModuleChild(module_sp),
+ UserID(sect_id),
+ Flags(flags),
+ m_obj_file(obj_file),
+ m_type(sect_type),
+ m_parent_wp(),
+ m_name(name),
+ m_file_addr(file_addr),
+ m_byte_size(byte_size),
+ m_file_offset(file_offset),
+ m_file_size(file_size),
+ m_log2align(log2align),
+ m_children(),
+ m_fake(false),
+ m_encrypted(false),
+ m_thread_specific(false),
+ m_readable(false),
+ m_writable(false),
+ m_executable(false),
+ m_target_byte_size(target_byte_size)
{
// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, parent_section_sp->GetName().GetCString(), name.GetCString());
@@ -254,7 +240,8 @@ Section::Dump (Stream *s, Target *target, uint32_t depth) const
range.Dump (s, 0);
}
- s->Printf("%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", resolved ? ' ' : '*', m_file_offset, m_file_size, Get());
+ s->Printf("%c %c%c%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", resolved ? ' ' : '*', m_readable ? 'r' : '-',
+ m_writable ? 'w' : '-', m_executable ? 'x' : '-', m_file_offset, m_file_size, Get());
DumpName (s);
@@ -319,6 +306,33 @@ Section::Slide (addr_t slide_amount, bool slide_children)
return false;
}
+//------------------------------------------------------------------
+/// Get the permissions as OR'ed bits from lldb::Permissions
+//------------------------------------------------------------------
+uint32_t
+Section::GetPermissions() const
+{
+ uint32_t permissions = 0;
+ if (m_readable)
+ permissions |= ePermissionsReadable;
+ if (m_writable)
+ permissions |= ePermissionsWritable;
+ if (m_executable)
+ permissions |= ePermissionsExecutable;
+ return permissions;
+}
+
+//------------------------------------------------------------------
+/// Set the permissions using bits OR'ed from lldb::Permissions
+//------------------------------------------------------------------
+void
+Section::SetPermissions(uint32_t permissions)
+{
+ m_readable = (permissions & ePermissionsReadable) != 0;
+ m_writable = (permissions & ePermissionsWritable) != 0;
+ m_executable = (permissions & ePermissionsExecutable) != 0;
+}
+
lldb::offset_t
Section::GetSectionData (void *dst, lldb::offset_t dst_len, lldb::offset_t offset)
{
@@ -567,9 +581,12 @@ SectionList::Dump (Stream *s, Target *target, bool show_header, uint32_t depth)
if (show_header && !m_sections.empty())
{
s->Indent();
- s->Printf( "SectID Type %s Address File Off. File Size Flags Section Name\n", target_has_loaded_sections ? "Load" : "File");
+ s->Printf("SectID Type %s Address Perm File Off. File Size Flags "
+ " Section Name\n",
+ target_has_loaded_sections ? "Load" : "File");
s->Indent();
- s->PutCString("---------- ---------------- --------------------------------------- ---------- ---------- ---------- ----------------------------\n");
+ s->PutCString("---------- ---------------- --------------------------------------- ---- ---------- ---------- "
+ "---------- ----------------------------\n");
}
diff --git a/source/Core/StreamCallback.cpp b/source/Core/StreamCallback.cpp
index d144b16755e7..9f0adee2a159 100644
--- a/source/Core/StreamCallback.cpp
+++ b/source/Core/StreamCallback.cpp
@@ -18,13 +18,8 @@
using namespace lldb;
using namespace lldb_private;
-
-StreamCallback::StreamCallback (lldb::LogOutputCallback callback, void *baton) :
- Stream (0, 4, eByteOrderBig),
- m_callback (callback),
- m_baton (baton),
- m_accumulated_data (),
- m_collection_mutex ()
+StreamCallback::StreamCallback(lldb::LogOutputCallback callback, void *baton)
+ : Stream(0, 4, eByteOrderBig), m_callback(callback), m_baton(baton), m_accumulated_data(), m_collection_mutex()
{
}
@@ -35,7 +30,7 @@ StreamCallback::~StreamCallback ()
StreamString &
StreamCallback::FindStreamForThread(lldb::tid_t cur_tid)
{
- Mutex::Locker locker(m_collection_mutex);
+ std::lock_guard<std::mutex> guard(m_collection_mutex);
collection::iterator iter = m_accumulated_data.find (cur_tid);
if (iter == m_accumulated_data.end())
{
diff --git a/source/Core/Timer.cpp b/source/Core/Timer.cpp
index e53ce2ec453d..f4cd33fc3cb5 100644
--- a/source/Core/Timer.cpp
+++ b/source/Core/Timer.cpp
@@ -8,12 +8,12 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/Timer.h"
+#include <algorithm>
#include <map>
+#include <mutex>
#include <vector>
-#include <algorithm>
#include "lldb/Core/Stream.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/Host.h"
#include <stdio.h>
@@ -39,15 +39,23 @@ namespace
std::atomic<bool> Timer::g_quiet(true);
std::atomic<unsigned> Timer::g_display_depth(0);
-std::mutex Timer::g_file_mutex;
-FILE* Timer::g_file = nullptr;
-
-static lldb::thread_key_t g_key;
+static std::mutex &
+GetFileMutex()
+{
+ static std::mutex *g_file_mutex_ptr = nullptr;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ // leaked on purpose to ensure this mutex works after main thread has run
+ // global C++ destructor chain
+ g_file_mutex_ptr = new std::mutex();
+ });
+ return *g_file_mutex_ptr;
+}
-static Mutex &
+static std::mutex &
GetCategoryMutex()
{
- static Mutex g_category_mutex(Mutex::eMutexTypeNormal);
+ static std::mutex g_category_mutex;
return g_category_mutex;
}
@@ -58,10 +66,17 @@ GetCategoryMap()
return g_category_map;
}
+static void
+ThreadSpecificCleanup(void *p)
+{
+ delete static_cast<TimerStack *>(p);
+}
static TimerStack *
GetTimerStackForCurrentThread ()
{
+ static lldb::thread_key_t g_key = Host::ThreadLocalStorageCreate(ThreadSpecificCleanup);
+
void *timer_stack = Host::ThreadLocalStorageGet(g_key);
if (timer_stack == NULL)
{
@@ -72,24 +87,11 @@ GetTimerStackForCurrentThread ()
}
void
-ThreadSpecificCleanup (void *p)
-{
- delete (TimerStack *)p;
-}
-
-void
Timer::SetQuiet (bool value)
{
g_quiet = value;
}
-void
-Timer::Initialize ()
-{
- Timer::g_file = stdout;
- g_key = Host::ThreadLocalStorageCreate(ThreadSpecificCleanup);
-}
-
Timer::Timer (const char *category, const char *format, ...) :
m_category (category),
m_total_start (),
@@ -105,18 +107,18 @@ Timer::Timer (const char *category, const char *format, ...) :
{
if (g_quiet == false)
{
- std::lock_guard<std::mutex> lock(g_file_mutex);
+ std::lock_guard<std::mutex> lock(GetFileMutex());
// Indent
- ::fprintf (g_file, "%*s", stack->m_depth * TIMER_INDENT_AMOUNT, "");
+ ::fprintf(stdout, "%*s", stack->m_depth * TIMER_INDENT_AMOUNT, "");
// Print formatted string
va_list args;
va_start (args, format);
- ::vfprintf (g_file, format, args);
+ ::vfprintf(stdout, format, args);
va_end (args);
// Newline
- ::fprintf (g_file, "\n");
+ ::fprintf(stdout, "\n");
}
TimeValue start_time(TimeValue::Now());
m_total_start = start_time;
@@ -160,16 +162,13 @@ Timer::~Timer()
if (g_quiet == false)
{
- std::lock_guard<std::mutex> lock(g_file_mutex);
- ::fprintf (g_file,
- "%*s%.9f sec (%.9f sec)\n",
- (stack->m_depth - 1) *TIMER_INDENT_AMOUNT, "",
- total_nsec / 1000000000.0,
- timer_nsec / 1000000000.0);
+ std::lock_guard<std::mutex> lock(GetFileMutex());
+ ::fprintf(stdout, "%*s%.9f sec (%.9f sec)\n", (stack->m_depth - 1) * TIMER_INDENT_AMOUNT, "",
+ total_nsec / 1000000000.0, timer_nsec / 1000000000.0);
}
// Keep total results for each category so we can dump results.
- Mutex::Locker locker (GetCategoryMutex());
+ std::lock_guard<std::mutex> guard(GetCategoryMutex());
TimerCategoryMap &category_map = GetCategoryMap();
category_map[m_category] += timer_nsec_uint;
}
@@ -240,7 +239,7 @@ CategoryMapIteratorSortCriterion (const TimerCategoryMap::const_iterator& lhs, c
void
Timer::ResetCategoryTimes ()
{
- Mutex::Locker locker (GetCategoryMutex());
+ std::lock_guard<std::mutex> guard(GetCategoryMutex());
TimerCategoryMap &category_map = GetCategoryMap();
category_map.clear();
}
@@ -248,7 +247,7 @@ Timer::ResetCategoryTimes ()
void
Timer::DumpCategoryTimes (Stream *s)
{
- Mutex::Locker locker (GetCategoryMutex());
+ std::lock_guard<std::mutex> guard(GetCategoryMutex());
TimerCategoryMap &category_map = GetCategoryMap();
std::vector<TimerCategoryMap::const_iterator> sorted_iterators;
TimerCategoryMap::const_iterator pos, end = category_map.end();
diff --git a/source/Core/UserSettingsController.cpp b/source/Core/UserSettingsController.cpp
index 837ff18721e2..6313fa1eb13a 100644
--- a/source/Core/UserSettingsController.cpp
+++ b/source/Core/UserSettingsController.cpp
@@ -108,3 +108,27 @@ Properties::GetSubProperty (const ExecutionContext *exe_ctx,
return lldb::OptionValuePropertiesSP();
}
+const char *
+Properties::GetExperimentalSettingsName()
+{
+ return "experimental";
+}
+
+bool
+Properties::IsSettingExperimental(const char *setting)
+{
+ if (setting == nullptr)
+ return false;
+
+ const char *experimental = GetExperimentalSettingsName();
+ const char *dot_pos = strchr(setting, '.');
+ if (dot_pos == nullptr)
+ return strcmp(experimental, setting) == 0;
+ else
+ {
+ size_t first_elem_len = dot_pos - setting;
+ return strncmp(experimental, setting, first_elem_len) == 0;
+ }
+
+}
+
diff --git a/source/Core/Value.cpp b/source/Core/Value.cpp
index a5c48e823ace..eb250eb77e46 100644
--- a/source/Core/Value.cpp
+++ b/source/Core/Value.cpp
@@ -428,17 +428,16 @@ Value::GetValueAsData (ExecutionContext *exe_ctx,
uint32_t limit_byte_size = UINT32_MAX;
- if (ast_type.IsValid() && ast_type.IsScalarType())
+ if (ast_type.IsValid())
{
- uint64_t type_encoding_count = 0;
- lldb::Encoding type_encoding = ast_type.GetEncoding(type_encoding_count);
-
- if (type_encoding == eEncodingUint || type_encoding == eEncodingSint)
- limit_byte_size = ast_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
+ limit_byte_size = ast_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
}
- if (m_value.GetData (data, limit_byte_size))
- return error; // Success;
+ if (limit_byte_size <= m_value.GetByteSize())
+ {
+ if (m_value.GetData (data, limit_byte_size))
+ return error; // Success;
+ }
error.SetErrorStringWithFormat("extracting data from value failed");
break;
diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp
index 6b1a6c590631..3e0a31833ef6 100644
--- a/source/Core/ValueObject.cpp
+++ b/source/Core/ValueObject.cpp
@@ -834,20 +834,20 @@ ValueObject::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_
ExecutionContext exe_ctx (GetExecutionContextRef());
- child_compiler_type = GetCompilerType().GetChildCompilerTypeAtIndex (&exe_ctx,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name_str,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent,
- this,
- language_flags);
+ child_compiler_type = GetCompilerType().GetChildCompilerTypeAtIndex(&exe_ctx,
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name_str,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ child_is_deref_of_parent,
+ this,
+ language_flags);
if (child_compiler_type)
{
if (synthetic_index)
@@ -1789,6 +1789,10 @@ ValueObject::DumpPrintableRepresentation(Stream& s,
addr_t
ValueObject::GetAddressOf (bool scalar_is_load_address, AddressType *address_type)
{
+ // Can't take address of a bitfield
+ if (IsBitfield())
+ return LLDB_INVALID_ADDRESS;
+
if (!UpdateValueIfNeeded(false))
return LLDB_INVALID_ADDRESS;
@@ -2146,6 +2150,10 @@ ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_cre
synthetic_child_sp = GetSyntheticChild (index_const_str);
if (!synthetic_child_sp)
{
+ uint32_t bit_field_size = to - from + 1;
+ uint32_t bit_field_offset = from;
+ if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
+ bit_field_offset = GetByteSize() * 8 - bit_field_size - bit_field_offset;
// We haven't made a synthetic array member for INDEX yet, so
// lets make one and cache it for any future reference.
ValueObjectChild *synthetic_child = new ValueObjectChild (*this,
@@ -2153,8 +2161,8 @@ ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_cre
index_const_str,
GetByteSize(),
0,
- to-from+1,
- from,
+ bit_field_size,
+ bit_field_offset,
false,
false,
eAddressTypeInvalid,
@@ -2174,14 +2182,20 @@ ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_cre
}
ValueObjectSP
-ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create)
+ValueObject::GetSyntheticChildAtOffset(uint32_t offset,
+ const CompilerType& type,
+ bool can_create,
+ ConstString name_const_str)
{
ValueObjectSP synthetic_child_sp;
- char name_str[64];
- snprintf(name_str, sizeof(name_str), "@%i", offset);
- ConstString name_const_str(name_str);
+ if (name_const_str.IsEmpty())
+ {
+ char name_str[64];
+ snprintf(name_str, sizeof(name_str), "@%i", offset);
+ name_const_str.SetCString(name_str);
+ }
// Check if we have already created a synthetic array member in this
// valid object. If we have we will re-use it.
@@ -2217,13 +2231,19 @@ ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type
}
ValueObjectSP
-ValueObject::GetSyntheticBase (uint32_t offset, const CompilerType& type, bool can_create)
+ValueObject::GetSyntheticBase (uint32_t offset,
+ const CompilerType& type,
+ bool can_create,
+ ConstString name_const_str)
{
ValueObjectSP synthetic_child_sp;
- char name_str[64];
- snprintf(name_str, sizeof(name_str), "%s", type.GetTypeName().AsCString("<unknown>"));
- ConstString name_const_str(name_str);
+ if (name_const_str.IsEmpty())
+ {
+ char name_str[128];
+ snprintf(name_str, sizeof(name_str), "base%s@%i", type.GetTypeName().AsCString("<unknown>"), offset);
+ name_const_str.SetCString(name_str);
+ }
// Check if we have already created a synthetic array member in this
// valid object. If we have we will re-use it.
@@ -2530,7 +2550,7 @@ ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExp
if (!is_deref_of_parent)
{
ValueObject *non_base_class_parent = GetNonBaseClassParent();
- if (non_base_class_parent)
+ if (non_base_class_parent && !non_base_class_parent->GetName().IsEmpty())
{
CompilerType non_base_class_parent_compiler_type = non_base_class_parent->GetCompilerType();
if (non_base_class_parent_compiler_type)
@@ -2797,6 +2817,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
}
expression_cstr++; // skip the -
}
+ LLVM_FALLTHROUGH;
case '.': // or fallthrough from ->
{
if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
diff --git a/source/Core/ValueObjectConstResult.cpp b/source/Core/ValueObjectConstResult.cpp
index a0f1737a861c..441cee540f7c 100644
--- a/source/Core/ValueObjectConstResult.cpp
+++ b/source/Core/ValueObjectConstResult.cpp
@@ -314,9 +314,12 @@ ValueObjectConstResult::Dereference (Error &error)
}
lldb::ValueObjectSP
-ValueObjectConstResult::GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create)
+ValueObjectConstResult::GetSyntheticChildAtOffset(uint32_t offset,
+ const CompilerType& type,
+ bool can_create,
+ ConstString name_const_str)
{
- return m_impl.GetSyntheticChildAtOffset(offset, type, can_create);
+ return m_impl.GetSyntheticChildAtOffset(offset, type, can_create, name_const_str);
}
lldb::ValueObjectSP
diff --git a/source/Core/ValueObjectConstResultCast.cpp b/source/Core/ValueObjectConstResultCast.cpp
index 8f0c0f1522f2..1611503c4bf1 100644
--- a/source/Core/ValueObjectConstResultCast.cpp
+++ b/source/Core/ValueObjectConstResultCast.cpp
@@ -40,9 +40,10 @@ ValueObjectConstResultCast::Dereference (Error &error)
lldb::ValueObjectSP
ValueObjectConstResultCast::GetSyntheticChildAtOffset(uint32_t offset,
const CompilerType& type,
- bool can_create)
+ bool can_create,
+ ConstString name_const_str)
{
- return m_impl.GetSyntheticChildAtOffset(offset, type, can_create);
+ return m_impl.GetSyntheticChildAtOffset(offset, type, can_create, name_const_str);
}
lldb::ValueObjectSP
diff --git a/source/Core/ValueObjectConstResultChild.cpp b/source/Core/ValueObjectConstResultChild.cpp
index c93aedc22603..e3afa36351a8 100644
--- a/source/Core/ValueObjectConstResultChild.cpp
+++ b/source/Core/ValueObjectConstResultChild.cpp
@@ -57,9 +57,15 @@ ValueObjectConstResultChild::Dereference (Error &error)
}
lldb::ValueObjectSP
-ValueObjectConstResultChild::GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create)
+ValueObjectConstResultChild::GetSyntheticChildAtOffset(uint32_t offset,
+ const CompilerType& type,
+ bool can_create,
+ ConstString name_const_str)
{
- return m_impl.GetSyntheticChildAtOffset(offset, type, can_create);
+ return m_impl.GetSyntheticChildAtOffset(offset,
+ type,
+ can_create,
+ name_const_str);
}
lldb::ValueObjectSP
diff --git a/source/Core/ValueObjectConstResultImpl.cpp b/source/Core/ValueObjectConstResultImpl.cpp
index 85ac3f2c5fe5..6db7f184da8f 100644
--- a/source/Core/ValueObjectConstResultImpl.cpp
+++ b/source/Core/ValueObjectConstResultImpl.cpp
@@ -117,12 +117,18 @@ ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array
}
lldb::ValueObjectSP
-ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const CompilerType& type, bool can_create)
+ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset,
+ const CompilerType& type,
+ bool can_create,
+ ConstString name_const_str)
{
if (m_impl_backend == NULL)
return lldb::ValueObjectSP();
- return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
+ return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset,
+ type,
+ can_create,
+ name_const_str);
}
lldb::ValueObjectSP
diff --git a/source/Core/ValueObjectDynamicValue.cpp b/source/Core/ValueObjectDynamicValue.cpp
index 0ac86a68f19f..65deba096d82 100644
--- a/source/Core/ValueObjectDynamicValue.cpp
+++ b/source/Core/ValueObjectDynamicValue.cpp
@@ -419,6 +419,22 @@ ValueObjectDynamicValue::GetPreferredDisplayLanguage ()
}
bool
+ValueObjectDynamicValue::IsSyntheticChildrenGenerated ()
+{
+ if (m_parent)
+ return m_parent->IsSyntheticChildrenGenerated();
+ return false;
+}
+
+void
+ValueObjectDynamicValue::SetSyntheticChildrenGenerated (bool b)
+{
+ if (m_parent)
+ m_parent->SetSyntheticChildrenGenerated(b);
+ this->ValueObject::SetSyntheticChildrenGenerated(b);
+}
+
+bool
ValueObjectDynamicValue::GetDeclaration (Declaration &decl)
{
if (m_parent)
diff --git a/source/Core/ValueObjectSyntheticFilter.cpp b/source/Core/ValueObjectSyntheticFilter.cpp
index 0ccc4385e3cc..f2f233711b9c 100644
--- a/source/Core/ValueObjectSyntheticFilter.cpp
+++ b/source/Core/ValueObjectSyntheticFilter.cpp
@@ -12,6 +12,8 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ValueObjectSyntheticFilter.h"
+
+#include "lldb/Core/Log.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSynthetic.h"
@@ -61,17 +63,12 @@ ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::Synthetic
m_children_byindex(),
m_name_toindex(),
m_synthetic_children_count(UINT32_MAX),
+ m_synthetic_children_cache(),
m_parent_type_name(parent.GetTypeName()),
m_might_have_children(eLazyBoolCalculate),
m_provides_value(eLazyBoolCalculate)
{
-#ifdef FOOBAR
- std::string new_name(parent.GetName().AsCString());
- new_name += "$$__synth__";
- SetName (ConstString(new_name.c_str()));
-#else
SetName(parent.GetName());
-#endif
CopyValueData(m_parent);
CreateSynthFilter();
}
@@ -99,20 +96,41 @@ ValueObjectSynthetic::GetQualifiedTypeName()
ConstString
ValueObjectSynthetic::GetDisplayTypeName()
{
+ if (ConstString synth_name = m_synth_filter_ap->GetSyntheticTypeName())
+ return synth_name;
+
return m_parent->GetDisplayTypeName();
}
size_t
ValueObjectSynthetic::CalculateNumChildren(uint32_t max)
{
+ Log* log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
+
UpdateValueIfNeeded();
if (m_synthetic_children_count < UINT32_MAX)
return m_synthetic_children_count <= max ? m_synthetic_children_count : max;
if (max < UINT32_MAX)
- return m_synth_filter_ap->CalculateNumChildren(max);
+ {
+ size_t num_children = m_synth_filter_ap->CalculateNumChildren(max);
+ if (log)
+ log->Printf("[ValueObjectSynthetic::CalculateNumChildren] for VO of name %s and type %s, the filter returned %zu child values",
+ GetName().AsCString(),
+ GetTypeName().AsCString(),
+ num_children);
+ return num_children;
+ }
else
- return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren(max));
+ {
+ size_t num_children = (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren(max));
+ if (log)
+ log->Printf("[ValueObjectSynthetic::CalculateNumChildren] for VO of name %s and type %s, the filter returned %zu child values",
+ GetName().AsCString(),
+ GetTypeName().AsCString(),
+ num_children);
+ return num_children;
+ }
}
lldb::ValueObjectSP
@@ -156,6 +174,8 @@ ValueObjectSynthetic::CreateSynthFilter ()
bool
ValueObjectSynthetic::UpdateValue ()
{
+ Log* log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
+
SetValueIsValid (false);
m_error.Clear();
@@ -172,6 +192,11 @@ ValueObjectSynthetic::UpdateValue ()
ConstString new_parent_type_name = m_parent->GetTypeName();
if (new_parent_type_name != m_parent_type_name)
{
+ if (log)
+ log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, type changed from %s to %s, recomputing synthetic filter",
+ GetName().AsCString(),
+ m_parent_type_name.AsCString(),
+ new_parent_type_name.AsCString());
m_parent_type_name = new_parent_type_name;
CreateSynthFilter();
}
@@ -179,6 +204,8 @@ ValueObjectSynthetic::UpdateValue ()
// let our backend do its update
if (m_synth_filter_ap->Update() == false)
{
+ if (log)
+ log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic filter said caches are stale - clearing", GetName().AsCString());
// filter said that cached values are stale
m_children_byindex.Clear();
m_name_toindex.Clear();
@@ -186,9 +213,15 @@ ValueObjectSynthetic::UpdateValue ()
// for a synthetic VO that might indeed happen, so we need to tell the upper echelons
// that they need to come back to us asking for children
m_children_count_valid = false;
+ m_synthetic_children_cache.Clear();
m_synthetic_children_count = UINT32_MAX;
m_might_have_children = eLazyBoolCalculate;
}
+ else
+ {
+ if (log)
+ log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic filter said caches are still valid", GetName().AsCString());
+ }
m_provides_value = eLazyBoolCalculate;
@@ -196,11 +229,17 @@ ValueObjectSynthetic::UpdateValue ()
if (synth_val && synth_val->CanProvideValue())
{
+ if (log)
+ log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic filter said it can provide a value", GetName().AsCString());
+
m_provides_value = eLazyBoolYes;
CopyValueData(synth_val.get());
}
else
{
+ if (log)
+ log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic filter said it will not provide a value", GetName().AsCString());
+
m_provides_value = eLazyBoolNo;
CopyValueData(m_parent);
}
@@ -212,6 +251,13 @@ ValueObjectSynthetic::UpdateValue ()
lldb::ValueObjectSP
ValueObjectSynthetic::GetChildAtIndex (size_t idx, bool can_create)
{
+ Log* log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
+
+ if (log)
+ log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, retrieving child at index %zu",
+ GetName().AsCString(),
+ idx);
+
UpdateValueIfNeeded();
ValueObject *valobj;
@@ -219,18 +265,51 @@ ValueObjectSynthetic::GetChildAtIndex (size_t idx, bool can_create)
{
if (can_create && m_synth_filter_ap.get() != nullptr)
{
+ if (log)
+ log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index %zu not cached and will be created",
+ GetName().AsCString(),
+ idx);
+
lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx);
+
+ if (log)
+ log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index %zu created as %p (is synthetic: %s)",
+ GetName().AsCString(),
+ idx,
+ synth_guy.get(),
+ synth_guy.get() ? (synth_guy->IsSyntheticChildrenGenerated() ? "yes" : "no") : "no");
+
if (!synth_guy)
return synth_guy;
+
+ if (synth_guy->IsSyntheticChildrenGenerated())
+ m_synthetic_children_cache.AppendObject(synth_guy);
m_children_byindex.SetValueForKey(idx, synth_guy.get());
synth_guy->SetPreferredDisplayLanguageIfNeeded(GetPreferredDisplayLanguage());
return synth_guy;
}
else
+ {
+ if (log)
+ log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index %zu not cached and cannot be created (can_create = %s, synth_filter = %p)",
+ GetName().AsCString(),
+ idx,
+ can_create ? "yes" : "no",
+ m_synth_filter_ap.get());
+
return lldb::ValueObjectSP();
+ }
}
else
+ {
+ if (log)
+ log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index %zu cached as %p",
+ GetName().AsCString(),
+ idx,
+ valobj);
+
return valobj->GetSP();
+ }
}
lldb::ValueObjectSP
@@ -338,6 +417,22 @@ ValueObjectSynthetic::GetPreferredDisplayLanguage ()
}
bool
+ValueObjectSynthetic::IsSyntheticChildrenGenerated ()
+{
+ if (m_parent)
+ return m_parent->IsSyntheticChildrenGenerated();
+ return false;
+}
+
+void
+ValueObjectSynthetic::SetSyntheticChildrenGenerated (bool b)
+{
+ if (m_parent)
+ m_parent->SetSyntheticChildrenGenerated(b);
+ this->ValueObject::SetSyntheticChildrenGenerated(b);
+}
+
+bool
ValueObjectSynthetic::GetDeclaration (Declaration &decl)
{
if (m_parent)
diff --git a/source/Core/ValueObjectVariable.cpp b/source/Core/ValueObjectVariable.cpp
index 389b7c54243d..a29d858d169f 100644
--- a/source/Core/ValueObjectVariable.cpp
+++ b/source/Core/ValueObjectVariable.cpp
@@ -164,7 +164,15 @@ ValueObjectVariable::UpdateValue ()
loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
}
Value old_value(m_value);
- if (expr.Evaluate (&exe_ctx, NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error))
+ if (expr.Evaluate (&exe_ctx,
+ nullptr,
+ nullptr,
+ nullptr,
+ loclist_base_load_addr,
+ nullptr,
+ nullptr,
+ m_value,
+ &m_error))
{
m_resolved_value = m_value;
m_value.SetContext(Value::eContextTypeVariable, variable);
diff --git a/source/DataFormatters/DumpValueObjectOptions.cpp b/source/DataFormatters/DumpValueObjectOptions.cpp
index f3de1257bb80..e1f5320feee6 100644
--- a/source/DataFormatters/DumpValueObjectOptions.cpp
+++ b/source/DataFormatters/DumpValueObjectOptions.cpp
@@ -242,4 +242,10 @@ DumpValueObjectOptions::SetRevealEmptyAggregates (bool reveal)
m_reveal_empty_aggregates = reveal;
return *this;
}
-
+
+DumpValueObjectOptions&
+DumpValueObjectOptions::SetElementCount (uint32_t element_count)
+{
+ m_element_count = element_count;
+ return *this;
+}
diff --git a/source/DataFormatters/FormatCache.cpp b/source/DataFormatters/FormatCache.cpp
index 748c6d80fbd2..fc5becbf200d 100644
--- a/source/DataFormatters/FormatCache.cpp
+++ b/source/DataFormatters/FormatCache.cpp
@@ -158,11 +158,13 @@ FormatCache::Entry::SetValidator (lldb::TypeValidatorImplSP validator_sp)
m_validator_sp = validator_sp;
}
-FormatCache::FormatCache () :
-m_map(),
-m_mutex (Mutex::eMutexTypeRecursive)
+FormatCache::FormatCache()
+ : m_map(),
+ m_mutex()
#ifdef LLDB_CONFIGURATION_DEBUG
-,m_cache_hits(0),m_cache_misses(0)
+ ,
+ m_cache_hits(0),
+ m_cache_misses(0)
#endif
{
}
@@ -181,9 +183,9 @@ FormatCache::GetEntry (const ConstString& type)
bool
FormatCache::GetFormat (const ConstString& type,lldb::TypeFormatImplSP& format_sp)
{
- Mutex::Locker lock(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
auto entry = GetEntry(type);
- if (entry.IsSummaryCached())
+ if (entry.IsFormatCached())
{
#ifdef LLDB_CONFIGURATION_DEBUG
m_cache_hits++;
@@ -201,7 +203,7 @@ FormatCache::GetFormat (const ConstString& type,lldb::TypeFormatImplSP& format_s
bool
FormatCache::GetSummary (const ConstString& type,lldb::TypeSummaryImplSP& summary_sp)
{
- Mutex::Locker lock(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
auto entry = GetEntry(type);
if (entry.IsSummaryCached())
{
@@ -221,7 +223,7 @@ FormatCache::GetSummary (const ConstString& type,lldb::TypeSummaryImplSP& summar
bool
FormatCache::GetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& synthetic_sp)
{
- Mutex::Locker lock(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
auto entry = GetEntry(type);
if (entry.IsSyntheticCached())
{
@@ -241,7 +243,7 @@ FormatCache::GetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& sy
bool
FormatCache::GetValidator (const ConstString& type,lldb::TypeValidatorImplSP& validator_sp)
{
- Mutex::Locker lock(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
auto entry = GetEntry(type);
if (entry.IsValidatorCached())
{
@@ -261,35 +263,35 @@ FormatCache::GetValidator (const ConstString& type,lldb::TypeValidatorImplSP& va
void
FormatCache::SetFormat (const ConstString& type,lldb::TypeFormatImplSP& format_sp)
{
- Mutex::Locker lock(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
GetEntry(type).SetFormat(format_sp);
}
void
FormatCache::SetSummary (const ConstString& type,lldb::TypeSummaryImplSP& summary_sp)
{
- Mutex::Locker lock(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
GetEntry(type).SetSummary(summary_sp);
}
void
FormatCache::SetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& synthetic_sp)
{
- Mutex::Locker lock(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
GetEntry(type).SetSynthetic(synthetic_sp);
}
void
FormatCache::SetValidator (const ConstString& type,lldb::TypeValidatorImplSP& validator_sp)
{
- Mutex::Locker lock(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
GetEntry(type).SetValidator(validator_sp);
}
void
FormatCache::Clear ()
{
- Mutex::Locker lock(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_map.clear();
}
diff --git a/source/DataFormatters/FormatManager.cpp b/source/DataFormatters/FormatManager.cpp
index 35a0468306fa..f51243f841e3 100644
--- a/source/DataFormatters/FormatManager.cpp
+++ b/source/DataFormatters/FormatManager.cpp
@@ -128,7 +128,7 @@ FormatManager::Changed ()
{
++m_last_revision;
m_format_cache.Clear ();
- Mutex::Locker lang_locker(m_language_categories_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
for (auto& iter : m_language_categories_map)
{
if (iter.second)
@@ -181,7 +181,7 @@ void
FormatManager::EnableAllCategories ()
{
m_categories_map.EnableAllCategories ();
- Mutex::Locker lang_locker(m_language_categories_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
for (auto& iter : m_language_categories_map)
{
if (iter.second)
@@ -193,7 +193,7 @@ void
FormatManager::DisableAllCategories ()
{
m_categories_map.DisableAllCategories ();
- Mutex::Locker lang_locker(m_language_categories_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
for (auto& iter : m_language_categories_map)
{
if (iter.second)
@@ -502,7 +502,7 @@ void
FormatManager::ForEachCategory(TypeCategoryMap::ForEachCallback callback)
{
m_categories_map.ForEach(callback);
- Mutex::Locker locker(m_language_categories_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
for (const auto& entry : m_language_categories_map)
{
if (auto category_sp = entry.second->GetCategory())
@@ -712,7 +712,7 @@ FormatManager::GetCandidateLanguages (lldb::LanguageType lang_type)
LanguageCategory*
FormatManager::GetCategoryForLanguage (lldb::LanguageType lang_type)
{
- Mutex::Locker locker(m_language_categories_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
auto iter = m_language_categories_map.find(lang_type), end = m_language_categories_map.end();
if (iter != end)
return iter->second.get();
@@ -1055,22 +1055,22 @@ FormatManager::GetHardcodedValidator (FormattersMatchData& match_data)
return retval_sp;
}
-FormatManager::FormatManager() :
- m_last_revision(0),
- m_format_cache(),
- m_language_categories_mutex(Mutex::eMutexTypeRecursive),
- m_language_categories_map(),
- m_named_summaries_map(this),
- m_categories_map(this),
- m_default_category_name(ConstString("default")),
- m_system_category_name(ConstString("system")),
- m_vectortypes_category_name(ConstString("VectorTypes"))
+FormatManager::FormatManager()
+ : m_last_revision(0),
+ m_format_cache(),
+ m_language_categories_mutex(),
+ m_language_categories_map(),
+ m_named_summaries_map(this),
+ m_categories_map(this),
+ m_default_category_name(ConstString("default")),
+ m_system_category_name(ConstString("system")),
+ m_vectortypes_category_name(ConstString("VectorTypes"))
{
LoadSystemFormatters();
LoadVectorFormatters();
-
- EnableCategory(m_vectortypes_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
- EnableCategory(m_system_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
+
+ EnableCategory(m_vectortypes_category_name, TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
+ EnableCategory(m_system_category_name, TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
}
void
diff --git a/source/DataFormatters/FormattersHelpers.cpp b/source/DataFormatters/FormattersHelpers.cpp
index 4b0e82e975e4..c4ff75cffdd1 100644
--- a/source/DataFormatters/FormattersHelpers.cpp
+++ b/source/DataFormatters/FormattersHelpers.cpp
@@ -133,178 +133,6 @@ lldb_private::formatters::AddFilter (TypeCategoryImpl::SharedPointer category_s
}
#endif
-StackFrame*
-lldb_private::formatters::GetViableFrame (ExecutionContext exe_ctx)
-{
- StackFrame* frame = exe_ctx.GetFramePtr();
- if (frame)
- return frame;
-
- Process* process = exe_ctx.GetProcessPtr();
- if (!process)
- return nullptr;
-
- ThreadSP thread_sp(process->GetThreadList().GetSelectedThread());
- if (thread_sp)
- return thread_sp->GetSelectedFrame().get();
- return nullptr;
-}
-
-bool
-lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
- const char* target_type,
- const char* selector,
- uint64_t &value)
-{
- if (!target_type || !*target_type)
- return false;
- if (!selector || !*selector)
- return false;
- StreamString expr;
- expr.Printf("(%s)[(id)0x%" PRIx64 " %s]",target_type,valobj.GetPointerValue(),selector);
- ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
- lldb::ValueObjectSP result_sp;
- Target* target = exe_ctx.GetTargetPtr();
- StackFrame* stack_frame = GetViableFrame(exe_ctx);
- if (!target || !stack_frame)
- return false;
-
- EvaluateExpressionOptions options;
- options.SetCoerceToId(false);
- options.SetUnwindOnError(true);
- options.SetKeepInMemory(true);
- options.SetLanguage(lldb::eLanguageTypeObjC_plus_plus);
- options.SetResultIsInternal(true);
- options.SetUseDynamic(lldb::eDynamicCanRunTarget);
-
- target->EvaluateExpression(expr.GetData(),
- stack_frame,
- result_sp,
- options);
- if (!result_sp)
- return false;
- value = result_sp->GetValueAsUnsigned(0);
- return true;
-}
-
-bool
-lldb_private::formatters::ExtractSummaryFromObjCExpression (ValueObject &valobj,
- const char* target_type,
- const char* selector,
- Stream &stream,
- lldb::LanguageType lang_type)
-{
- if (!target_type || !*target_type)
- return false;
- if (!selector || !*selector)
- return false;
- StreamString expr;
- expr.Printf("(%s)[(id)0x%" PRIx64 " %s]",target_type,valobj.GetPointerValue(),selector);
- ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
- lldb::ValueObjectSP result_sp;
- Target* target = exe_ctx.GetTargetPtr();
- StackFrame* stack_frame = GetViableFrame(exe_ctx);
- if (!target || !stack_frame)
- return false;
-
- EvaluateExpressionOptions options;
- options.SetCoerceToId(false);
- options.SetUnwindOnError(true);
- options.SetKeepInMemory(true);
- options.SetLanguage(lldb::eLanguageTypeObjC_plus_plus);
- options.SetResultIsInternal(true);
- options.SetUseDynamic(lldb::eDynamicCanRunTarget);
-
- target->EvaluateExpression(expr.GetData(),
- stack_frame,
- result_sp,
- options);
- if (!result_sp)
- return false;
- stream.Printf("%s",result_sp->GetSummaryAsCString(lang_type));
- return true;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
- const char* return_type,
- const char* selector,
- uint64_t index)
-{
- lldb::ValueObjectSP valobj_sp;
- if (!return_type || !*return_type)
- return valobj_sp;
- if (!selector || !*selector)
- return valobj_sp;
- StreamString expr;
- const char *colon = "";
- llvm::StringRef selector_sr(selector);
- if (selector_sr.back() != ':')
- colon = ":";
- expr.Printf("(%s)[(id)0x%" PRIx64 " %s%s%" PRId64 "]",return_type,valobj.GetPointerValue(),selector,colon,index);
- ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
- lldb::ValueObjectSP result_sp;
- Target* target = exe_ctx.GetTargetPtr();
- StackFrame* stack_frame = GetViableFrame(exe_ctx);
- if (!target || !stack_frame)
- return valobj_sp;
-
- EvaluateExpressionOptions options;
- options.SetCoerceToId(false);
- options.SetUnwindOnError(true);
- options.SetKeepInMemory(true);
- options.SetLanguage(lldb::eLanguageTypeObjC_plus_plus);
- options.SetResultIsInternal(true);
- options.SetUseDynamic(lldb::eDynamicCanRunTarget);
-
- target->EvaluateExpression(expr.GetData(),
- stack_frame,
- valobj_sp,
- options);
- return valobj_sp;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
- const char* return_type,
- const char* selector,
- const char* key)
-{
- lldb::ValueObjectSP valobj_sp;
- if (!return_type || !*return_type)
- return valobj_sp;
- if (!selector || !*selector)
- return valobj_sp;
- if (!key || !*key)
- return valobj_sp;
- StreamString expr;
- const char *colon = "";
- llvm::StringRef selector_sr(selector);
- if (selector_sr.back() != ':')
- colon = ":";
- expr.Printf("(%s)[(id)0x%" PRIx64 " %s%s%s]",return_type,valobj.GetPointerValue(),selector,colon,key);
- ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
- lldb::ValueObjectSP result_sp;
- Target* target = exe_ctx.GetTargetPtr();
- StackFrame* stack_frame = GetViableFrame(exe_ctx);
- if (!target || !stack_frame)
- return valobj_sp;
-
- EvaluateExpressionOptions options;
- options.SetCoerceToId(false);
- options.SetUnwindOnError(true);
- options.SetKeepInMemory(true);
- options.SetLanguage(lldb::eLanguageTypeObjC_plus_plus);
- options.SetResultIsInternal(true);
- options.SetUseDynamic(lldb::eDynamicCanRunTarget);
-
- target->EvaluateExpression(expr.GetData(),
- stack_frame,
- valobj_sp,
- options);
- return valobj_sp;
-}
-
size_t
lldb_private::formatters::ExtractIndexFromString (const char* item_name)
{
diff --git a/source/DataFormatters/Makefile b/source/DataFormatters/Makefile
deleted file mode 100644
index 4eb3249e5a58..000000000000
--- a/source/DataFormatters/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/DataFormatters/Makefile -------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LIBRARYNAME := lldbDataFormatters
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/DataFormatters/StringPrinter.cpp b/source/DataFormatters/StringPrinter.cpp
index b114add50640..8cdbb53eaa85 100644
--- a/source/DataFormatters/StringPrinter.cpp
+++ b/source/DataFormatters/StringPrinter.cpp
@@ -207,7 +207,7 @@ GetPrintableImpl<StringPrinter::StringElementType::UTF8> (uint8_t* buffer, uint8
else
{
uint8_t* data = new uint8_t[11];
- sprintf((char*)data,"\\U%08x",codepoint);
+ sprintf((char *)data, "\\U%08x", (unsigned)codepoint);
retval = { data,10,[] (const uint8_t* c) {delete[] c;} };
break;
}
diff --git a/source/DataFormatters/TypeCategory.cpp b/source/DataFormatters/TypeCategory.cpp
index 636d935b7625..9df3ec6721ff 100644
--- a/source/DataFormatters/TypeCategory.cpp
+++ b/source/DataFormatters/TypeCategory.cpp
@@ -18,21 +18,20 @@
using namespace lldb;
using namespace lldb_private;
-TypeCategoryImpl::TypeCategoryImpl(IFormatChangeListener* clist,
- ConstString name,
- std::initializer_list<lldb::LanguageType> langs) :
-m_format_cont("format","regex-format",clist),
-m_summary_cont("summary","regex-summary",clist),
-m_filter_cont("filter","regex-filter",clist),
+TypeCategoryImpl::TypeCategoryImpl(IFormatChangeListener *clist, ConstString name,
+ std::initializer_list<lldb::LanguageType> langs)
+ : m_format_cont("format", "regex-format", clist),
+ m_summary_cont("summary", "regex-summary", clist),
+ m_filter_cont("filter", "regex-filter", clist),
#ifndef LLDB_DISABLE_PYTHON
-m_synth_cont("synth","regex-synth",clist),
+ m_synth_cont("synth", "regex-synth", clist),
#endif
-m_validator_cont("validator","regex-validator",clist),
-m_enabled(false),
-m_change_listener(clist),
-m_mutex(Mutex::eMutexTypeRecursive),
-m_name(name),
-m_languages()
+ m_validator_cont("validator", "regex-validator", clist),
+ m_enabled(false),
+ m_change_listener(clist),
+ m_mutex(),
+ m_name(name),
+ m_languages()
{
for (const lldb::LanguageType lang : langs)
AddLanguage(lang);
@@ -673,7 +672,7 @@ TypeCategoryImpl::GetTypeNameSpecifierForValidatorAtIndex (size_t index)
void
TypeCategoryImpl::Enable (bool value, uint32_t position)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if ( (m_enabled = value) )
m_enabled_position = position;
if (m_change_listener)
diff --git a/source/DataFormatters/TypeCategoryMap.cpp b/source/DataFormatters/TypeCategoryMap.cpp
index 58e4e2117bb6..984c7f213ded 100644
--- a/source/DataFormatters/TypeCategoryMap.cpp
+++ b/source/DataFormatters/TypeCategoryMap.cpp
@@ -20,22 +20,19 @@
using namespace lldb;
using namespace lldb_private;
-TypeCategoryMap::TypeCategoryMap (IFormatChangeListener* lst) :
-m_map_mutex(Mutex::eMutexTypeRecursive),
-listener(lst),
-m_map(),
-m_active_categories()
+TypeCategoryMap::TypeCategoryMap(IFormatChangeListener *lst)
+ : m_map_mutex(), listener(lst), m_map(), m_active_categories()
{
ConstString default_cs("default");
lldb::TypeCategoryImplSP default_sp = lldb::TypeCategoryImplSP(new TypeCategoryImpl(listener, default_cs));
- Add(default_cs,default_sp);
- Enable(default_cs,First);
+ Add(default_cs, default_sp);
+ Enable(default_cs, First);
}
void
TypeCategoryMap::Add (KeyType name, const ValueSP& entry)
{
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
m_map[name] = entry;
if (listener)
listener->Changed();
@@ -44,7 +41,7 @@ TypeCategoryMap::Add (KeyType name, const ValueSP& entry)
bool
TypeCategoryMap::Delete (KeyType name)
{
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
MapIterator iter = m_map.find(name);
if (iter == m_map.end())
return false;
@@ -58,7 +55,7 @@ TypeCategoryMap::Delete (KeyType name)
bool
TypeCategoryMap::Enable (KeyType category_name, Position pos)
{
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
ValueSP category;
if (!Get(category_name,category))
return false;
@@ -68,7 +65,7 @@ TypeCategoryMap::Enable (KeyType category_name, Position pos)
bool
TypeCategoryMap::Disable (KeyType category_name)
{
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
ValueSP category;
if (!Get(category_name,category))
return false;
@@ -78,7 +75,7 @@ TypeCategoryMap::Disable (KeyType category_name)
bool
TypeCategoryMap::Enable (ValueSP category, Position pos)
{
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
if (category.get())
{
Position pos_w = pos;
@@ -107,7 +104,7 @@ TypeCategoryMap::Enable (ValueSP category, Position pos)
bool
TypeCategoryMap::Disable (ValueSP category)
{
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
if (category.get())
{
m_active_categories.remove_if(delete_matching_categories(category));
@@ -120,7 +117,7 @@ TypeCategoryMap::Disable (ValueSP category)
void
TypeCategoryMap::EnableAllCategories ()
{
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
std::vector<ValueSP> sorted_categories(m_map.size(), ValueSP());
MapType::iterator iter = m_map.begin(), end = m_map.end();
for (; iter != end; ++iter)
@@ -148,7 +145,7 @@ TypeCategoryMap::EnableAllCategories ()
void
TypeCategoryMap::DisableAllCategories ()
{
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
Position p = First;
for (; false == m_active_categories.empty(); p++)
{
@@ -160,7 +157,7 @@ TypeCategoryMap::DisableAllCategories ()
void
TypeCategoryMap::Clear ()
{
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
m_map.clear();
m_active_categories.clear();
if (listener)
@@ -170,7 +167,7 @@ TypeCategoryMap::Clear ()
bool
TypeCategoryMap::Get (KeyType name, ValueSP& entry)
{
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
MapIterator iter = m_map.find(name);
if (iter == m_map.end())
return false;
@@ -181,7 +178,7 @@ TypeCategoryMap::Get (KeyType name, ValueSP& entry)
bool
TypeCategoryMap::Get (uint32_t pos, ValueSP& entry)
{
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
MapIterator iter = m_map.begin();
MapIterator end = m_map.end();
while (pos > 0)
@@ -202,8 +199,8 @@ TypeCategoryMap::AnyMatches (ConstString type_name,
const char** matching_category,
TypeCategoryImpl::FormatCategoryItems* matching_type)
{
- Mutex::Locker locker(m_map_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+
MapIterator pos, end = m_map.end();
for (pos = m_map.begin(); pos != end; pos++)
{
@@ -220,8 +217,8 @@ TypeCategoryMap::AnyMatches (ConstString type_name,
lldb::TypeFormatImplSP
TypeCategoryMap::GetFormat (FormattersMatchData& match_data)
{
- Mutex::Locker locker(m_map_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+
uint32_t reason_why;
ActiveCategoriesIterator begin, end = m_active_categories.end();
@@ -231,7 +228,7 @@ TypeCategoryMap::GetFormat (FormattersMatchData& match_data)
{
for (auto match : match_data.GetMatchesVector())
{
- log->Printf("[CategoryMap::GetSummaryFormat] candidate match = %s %s %s %s reason = %" PRIu32,
+ log->Printf("[CategoryMap::GetFormat] candidate match = %s %s %s %s reason = %" PRIu32,
match.GetTypeName().GetCString(),
match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
match.DidStripReference() ? "strip-reference" : "no-strip-reference",
@@ -258,8 +255,8 @@ TypeCategoryMap::GetFormat (FormattersMatchData& match_data)
lldb::TypeSummaryImplSP
TypeCategoryMap::GetSummaryFormat (FormattersMatchData& match_data)
{
- Mutex::Locker locker(m_map_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+
uint32_t reason_why;
ActiveCategoriesIterator begin, end = m_active_categories.end();
@@ -297,8 +294,8 @@ TypeCategoryMap::GetSummaryFormat (FormattersMatchData& match_data)
lldb::SyntheticChildrenSP
TypeCategoryMap::GetSyntheticChildren (FormattersMatchData& match_data)
{
- Mutex::Locker locker(m_map_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+
uint32_t reason_why;
ActiveCategoriesIterator begin, end = m_active_categories.end();
@@ -309,7 +306,7 @@ TypeCategoryMap::GetSyntheticChildren (FormattersMatchData& match_data)
{
for (auto match : match_data.GetMatchesVector())
{
- log->Printf("[CategoryMap::GetSummaryFormat] candidate match = %s %s %s %s reason = %" PRIu32,
+ log->Printf("[CategoryMap::GetSyntheticChildren] candidate match = %s %s %s %s reason = %" PRIu32,
match.GetTypeName().GetCString(),
match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
match.DidStripReference() ? "strip-reference" : "no-strip-reference",
@@ -337,8 +334,8 @@ TypeCategoryMap::GetSyntheticChildren (FormattersMatchData& match_data)
lldb::TypeValidatorImplSP
TypeCategoryMap::GetValidator (FormattersMatchData& match_data)
{
- Mutex::Locker locker(m_map_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+
uint32_t reason_why;
ActiveCategoriesIterator begin, end = m_active_categories.end();
@@ -377,8 +374,8 @@ TypeCategoryMap::ForEach(ForEachCallback callback)
{
if (callback)
{
- Mutex::Locker locker(m_map_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+
// loop through enabled categories in respective order
{
ActiveCategoriesIterator begin, end = m_active_categories.end();
@@ -408,8 +405,8 @@ TypeCategoryMap::ForEach(ForEachCallback callback)
TypeCategoryImplSP
TypeCategoryMap::GetAtIndex (uint32_t index)
{
- Mutex::Locker locker(m_map_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+
if (index < m_map.size())
{
MapIterator pos, end = m_map.end();
diff --git a/source/DataFormatters/TypeFormat.cpp b/source/DataFormatters/TypeFormat.cpp
index 6ab8d298f94b..a810883b05e0 100644
--- a/source/DataFormatters/TypeFormat.cpp
+++ b/source/DataFormatters/TypeFormat.cpp
@@ -23,6 +23,7 @@
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/Target.h"
@@ -199,7 +200,8 @@ TypeFormatImpl_EnumType::FormatObject (ValueObject *valobj,
const ModuleList& images(target_sp->GetImages());
SymbolContext sc;
TypeList types;
- images.FindTypes(sc, m_enum_type, false, UINT32_MAX, types);
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+ images.FindTypes(sc, m_enum_type, false, UINT32_MAX, searched_symbol_files, types);
if (types.GetSize() == 0)
return false;
for (lldb::TypeSP type_sp : types.Types())
diff --git a/source/DataFormatters/TypeSummary.cpp b/source/DataFormatters/TypeSummary.cpp
index 2806ba20c6a9..dd4cd97f001b 100644
--- a/source/DataFormatters/TypeSummary.cpp
+++ b/source/DataFormatters/TypeSummary.cpp
@@ -256,14 +256,27 @@ std::string
ScriptSummaryFormat::GetDescription ()
{
StreamString sstr;
- sstr.Printf ("%s%s%s%s%s%s%s\n%s", Cascades() ? "" : " (not cascading)",
+ sstr.Printf ("%s%s%s%s%s%s%s\n ", Cascades() ? "" : " (not cascading)",
!DoesPrintChildren(nullptr) ? "" : " (show children)",
!DoesPrintValue(nullptr) ? " (hide value)" : "",
IsOneLiner() ? " (one-line printout)" : "",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "",
- HideNames(nullptr) ? " (hide member names)" : "",
- m_python_script.c_str());
+ HideNames(nullptr) ? " (hide member names)" : "");
+ if (m_python_script.empty())
+ {
+ if (m_function_name.empty())
+ {
+ sstr.PutCString("no backing script");
+ }
+ else
+ {
+ sstr.PutCString(m_function_name.c_str());
+ }
+ }
+ else
+ {
+ sstr.PutCString(m_python_script.c_str());
+ }
return sstr.GetString();
-
}
diff --git a/source/DataFormatters/TypeSynthetic.cpp b/source/DataFormatters/TypeSynthetic.cpp
index e49cd99b02ea..c8de1759c91d 100644
--- a/source/DataFormatters/TypeSynthetic.cpp
+++ b/source/DataFormatters/TypeSynthetic.cpp
@@ -246,6 +246,15 @@ ScriptedSyntheticChildren::FrontEnd::GetSyntheticValue ()
return m_interpreter->GetSyntheticValue(m_wrapper_sp);
}
+ConstString
+ScriptedSyntheticChildren::FrontEnd::GetSyntheticTypeName ()
+{
+ if (!m_wrapper_sp || m_interpreter == NULL)
+ return ConstString();
+
+ return m_interpreter->GetSyntheticTypeName(m_wrapper_sp);
+}
+
std::string
ScriptedSyntheticChildren::GetDescription()
{
diff --git a/source/DataFormatters/ValueObjectPrinter.cpp b/source/DataFormatters/ValueObjectPrinter.cpp
index 04c291283546..167afca7fbb1 100644
--- a/source/DataFormatters/ValueObjectPrinter.cpp
+++ b/source/DataFormatters/ValueObjectPrinter.cpp
@@ -416,11 +416,12 @@ ValueObjectPrinter::GetValueSummaryError (std::string& value,
std::string& summary,
std::string& error)
{
- if (m_options.m_format != eFormatDefault && m_options.m_format != m_valobj->GetFormat())
- {
- m_valobj->GetValueAsCString(m_options.m_format,
- value);
- }
+ lldb::Format format = m_options.m_format;
+ // if I am printing synthetized elements, apply the format to those elements only
+ if (m_options.m_element_count > 0)
+ m_valobj->GetValueAsCString(lldb::eFormatDefault, value);
+ else if (format != eFormatDefault && format != m_valobj->GetFormat())
+ m_valobj->GetValueAsCString(format, value);
else
{
const char* val_cstr = m_valobj->GetValueAsCString();
@@ -514,7 +515,7 @@ ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed,
if (ShouldPrintValueObject())
{
// let's avoid the overly verbose no description error for a nil thing
- if (m_options.m_use_objc && !IsNil() && !IsUninitialized())
+ if (m_options.m_use_objc && !IsNil() && !IsUninitialized() && (m_options.m_element_count == 0))
{
if (!m_options.m_hide_value || !m_options.m_hide_name)
m_stream->Printf(" ");
@@ -587,6 +588,11 @@ ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description,
if (is_uninit)
return false;
+ // if the user has specified an element count, always print children
+ // as it is explicit user demand being honored
+ if (m_options.m_element_count > 0)
+ return true;
+
TypeSummaryImpl* entry = GetSummaryFormatter();
if (m_options.m_use_objc)
@@ -667,18 +673,22 @@ void
ValueObjectPrinter::PrintChild (ValueObjectSP child_sp,
const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
{
+ const uint32_t consumed_depth = (m_options.m_element_count == 0) ? 1 : 0;
+ const bool does_consume_ptr_depth = ((IsPtr() && m_options.m_element_count == 0) || IsRef());
+
DumpValueObjectOptions child_options(m_options);
child_options.SetFormat(m_options.m_format).SetSummary().SetRootValueObjectName();
child_options.SetScopeChecked(true).SetHideName(m_options.m_hide_name).SetHideValue(m_options.m_hide_value)
- .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
+ .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - consumed_depth : 0)
+ .SetElementCount(0);
if (child_sp.get())
{
ValueObjectPrinter child_printer(child_sp.get(),
m_stream,
child_options,
- (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth,
- m_curr_depth + 1,
+ does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth,
+ m_curr_depth + consumed_depth,
m_printed_instance_pointers);
child_printer.PrintValueObject();
}
@@ -689,6 +699,9 @@ ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot)
{
ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
+ if (m_options.m_element_count > 0)
+ return m_options.m_element_count;
+
size_t num_children = synth_m_valobj->GetNumChildren();
print_dotdotdot = false;
if (num_children)
@@ -743,6 +756,21 @@ ValueObjectPrinter::ShouldPrintEmptyBrackets (bool value_printed,
return true;
}
+ValueObjectSP
+ValueObjectPrinter::GenerateChild (ValueObject* synth_valobj, size_t idx)
+{
+ if (m_options.m_element_count > 0)
+ {
+ // if generating pointer-as-array children, use GetSyntheticArrayMember
+ return synth_valobj->GetSyntheticArrayMember(idx, true);
+ }
+ else
+ {
+ // otherwise, do the usual thing
+ return synth_valobj->GetChildAtIndex(idx, true);
+ }
+}
+
void
ValueObjectPrinter::PrintChildren (bool value_printed,
bool summary_printed,
@@ -758,8 +786,7 @@ ValueObjectPrinter::PrintChildren (bool value_printed,
for (size_t idx=0; idx<num_children; ++idx)
{
- ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
- if (child_sp)
+ if (ValueObjectSP child_sp = GenerateChild(synth_m_valobj, idx))
{
if (!any_children_printed)
{
@@ -866,6 +893,7 @@ ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed,
m_options.m_show_types ||
!m_options.m_allow_oneliner_mode ||
m_options.m_flat_output ||
+ (m_options.m_element_count > 0) ||
m_options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj);
bool is_instance_ptr = IsInstancePointer();
uint64_t instance_ptr_value = LLDB_INVALID_ADDRESS;
diff --git a/source/Expression/CMakeLists.txt b/source/Expression/CMakeLists.txt
index 52392f13319a..48e67888e436 100644
--- a/source/Expression/CMakeLists.txt
+++ b/source/Expression/CMakeLists.txt
@@ -1,4 +1,5 @@
add_lldb_library(lldbExpression
+ DiagnosticManager.cpp
DWARFExpression.cpp
Expression.cpp
ExpressionSourceCode.cpp
diff --git a/source/Expression/DWARFExpression.cpp b/source/Expression/DWARFExpression.cpp
index ebcc28460395..b81d60e9b065 100644
--- a/source/Expression/DWARFExpression.cpp
+++ b/source/Expression/DWARFExpression.cpp
@@ -1003,7 +1003,128 @@ DWARFExpression::Update_DW_OP_addr (lldb::addr_t file_addr)
}
bool
-DWARFExpression::LocationListContainsAddress (lldb::addr_t loclist_base_addr, lldb::addr_t addr) const
+DWARFExpression::ContainsThreadLocalStorage() const
+{
+ // We are assuming for now that any thread local variable will not
+ // have a location list. This has been true for all thread local
+ // variables we have seen so far produced by any compiler.
+ if (IsLocationList())
+ return false;
+ lldb::offset_t offset = 0;
+ while (m_data.ValidOffset(offset))
+ {
+ const uint8_t op = m_data.GetU8(&offset);
+
+ if (op == DW_OP_form_tls_address || op == DW_OP_GNU_push_tls_address)
+ return true;
+ const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
+ if (op_arg_size == LLDB_INVALID_OFFSET)
+ return false;
+ else
+ offset += op_arg_size;
+ }
+ return false;
+}
+bool
+DWARFExpression::LinkThreadLocalStorage(
+ lldb::ModuleSP new_module_sp, std::function<lldb::addr_t(lldb::addr_t file_addr)> const &link_address_callback)
+{
+ // We are assuming for now that any thread local variable will not
+ // have a location list. This has been true for all thread local
+ // variables we have seen so far produced by any compiler.
+ if (IsLocationList())
+ return false;
+
+ const uint32_t addr_byte_size = m_data.GetAddressByteSize();
+ // We have to make a copy of the data as we don't know if this
+ // data is from a read only memory mapped buffer, so we duplicate
+ // all of the data first, then modify it, and if all goes well,
+ // we then replace the data for this expression
+
+ // So first we copy the data into a heap buffer
+ std::shared_ptr<DataBufferHeap> heap_data_sp(new DataBufferHeap(m_data.GetDataStart(), m_data.GetByteSize()));
+
+ // Make en encoder so we can write the address into the buffer using
+ // the correct byte order (endianness)
+ DataEncoder encoder(heap_data_sp->GetBytes(), heap_data_sp->GetByteSize(), m_data.GetByteOrder(), addr_byte_size);
+
+ lldb::offset_t offset = 0;
+ lldb::offset_t const_offset = 0;
+ lldb::addr_t const_value = 0;
+ size_t const_byte_size = 0;
+ while (m_data.ValidOffset(offset))
+ {
+ const uint8_t op = m_data.GetU8(&offset);
+
+ bool decoded_data = false;
+ switch (op)
+ {
+ case DW_OP_const4u:
+ // Remember the const offset in case we later have a DW_OP_form_tls_address
+ // or DW_OP_GNU_push_tls_address
+ const_offset = offset;
+ const_value = m_data.GetU32(&offset);
+ decoded_data = true;
+ const_byte_size = 4;
+ break;
+
+ case DW_OP_const8u:
+ // Remember the const offset in case we later have a DW_OP_form_tls_address
+ // or DW_OP_GNU_push_tls_address
+ const_offset = offset;
+ const_value = m_data.GetU64(&offset);
+ decoded_data = true;
+ const_byte_size = 8;
+ break;
+
+ case DW_OP_form_tls_address:
+ case DW_OP_GNU_push_tls_address:
+ // DW_OP_form_tls_address and DW_OP_GNU_push_tls_address must be preceded by
+ // a file address on the stack. We assume that DW_OP_const4u or DW_OP_const8u
+ // is used for these values, and we check that the last opcode we got before
+ // either of these was DW_OP_const4u or DW_OP_const8u. If so, then we can link
+ // the value accodingly. For Darwin, the value in the DW_OP_const4u or
+ // DW_OP_const8u is the file address of a structure that contains a function
+ // pointer, the pthread key and the offset into the data pointed to by the
+ // pthread key. So we must link this address and also set the module of this
+ // expression to the new_module_sp so we can resolve the file address correctly
+ if (const_byte_size > 0)
+ {
+ lldb::addr_t linked_file_addr = link_address_callback(const_value);
+ if (linked_file_addr == LLDB_INVALID_ADDRESS)
+ return false;
+ // Replace the address in the new buffer
+ if (encoder.PutMaxU64(const_offset, const_byte_size, linked_file_addr) == UINT32_MAX)
+ return false;
+ }
+ break;
+
+ default:
+ const_offset = 0;
+ const_value = 0;
+ const_byte_size = 0;
+ break;
+ }
+
+ if (!decoded_data)
+ {
+ const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
+ if (op_arg_size == LLDB_INVALID_OFFSET)
+ return false;
+ else
+ offset += op_arg_size;
+ }
+ }
+
+ // If we linked the TLS address correctly, update the module so that when the expression
+ // is evaluated it can resolve the file address to a load address and read the TLS data
+ m_module_wp = new_module_sp;
+ m_data.SetData(heap_data_sp);
+ return true;
+}
+
+bool
+DWARFExpression::LocationListContainsAddress(lldb::addr_t loclist_base_addr, lldb::addr_t addr) const
{
if (addr == LLDB_INVALID_ADDRESS)
return false;
@@ -1108,12 +1229,21 @@ DWARFExpression::Evaluate
ClangExpressionDeclMap *decl_map,
lldb::addr_t loclist_base_load_addr,
const Value* initial_value_ptr,
+ const Value* object_address_ptr,
Value& result,
Error *error_ptr
) const
{
ExecutionContext exe_ctx (exe_scope);
- return Evaluate(&exe_ctx, expr_locals, decl_map, NULL, loclist_base_load_addr, initial_value_ptr, result, error_ptr);
+ return Evaluate(&exe_ctx,
+ expr_locals,
+ decl_map,
+ nullptr,
+ loclist_base_load_addr,
+ initial_value_ptr,
+ object_address_ptr,
+ result,
+ error_ptr);
}
bool
@@ -1125,6 +1255,7 @@ DWARFExpression::Evaluate
RegisterContext *reg_ctx,
lldb::addr_t loclist_base_load_addr,
const Value* initial_value_ptr,
+ const Value* object_address_ptr,
Value& result,
Error *error_ptr
) const
@@ -1189,6 +1320,7 @@ DWARFExpression::Evaluate
length,
m_reg_kind,
initial_value_ptr,
+ object_address_ptr,
result,
error_ptr);
}
@@ -1212,6 +1344,7 @@ DWARFExpression::Evaluate
m_data.GetByteSize(),
m_reg_kind,
initial_value_ptr,
+ object_address_ptr,
result,
error_ptr);
}
@@ -1232,6 +1365,7 @@ DWARFExpression::Evaluate
const lldb::offset_t opcodes_length,
const lldb::RegisterKind reg_kind,
const Value* initial_value_ptr,
+ const Value* object_address_ptr,
Value& result,
Error *error_ptr
)
@@ -1931,7 +2065,7 @@ DWARFExpression::Evaluate
{
tmp = stack.back();
stack.pop_back();
- stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) + tmp.ResolveValue(exe_ctx);
+ stack.back().GetScalar() += tmp.GetScalar();
}
break;
@@ -1952,8 +2086,8 @@ DWARFExpression::Evaluate
{
const uint64_t uconst_value = opcodes.GetULEB128(&offset);
// Implicit conversion from a UINT to a Scalar...
- stack.back().ResolveValue(exe_ctx) += uconst_value;
- if (!stack.back().ResolveValue(exe_ctx).IsValid())
+ stack.back().GetScalar() += uconst_value;
+ if (!stack.back().GetScalar().IsValid())
{
if (error_ptr)
error_ptr->SetErrorString("DW_OP_plus_uconst failed.");
@@ -2689,9 +2823,15 @@ DWARFExpression::Evaluate
// during user expression evaluation.
//----------------------------------------------------------------------
case DW_OP_push_object_address:
- if (error_ptr)
- error_ptr->SetErrorString ("Unimplemented opcode DW_OP_push_object_address.");
- return false;
+ if (object_address_ptr)
+ stack.push_back(*object_address_ptr);
+ else
+ {
+ if (error_ptr)
+ error_ptr->SetErrorString ("DW_OP_push_object_address used without specifying an object address");
+ return false;
+ }
+ break;
//----------------------------------------------------------------------
// OPCODE: DW_OP_call2
@@ -2826,18 +2966,17 @@ DWARFExpression::Evaluate
}
// Lookup the TLS block address for this thread and module.
- addr_t tls_addr = thread->GetThreadLocalData (module_sp);
+ const addr_t tls_file_addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ const addr_t tls_load_addr = thread->GetThreadLocalData(module_sp, tls_file_addr);
- if (tls_addr == LLDB_INVALID_ADDRESS)
+ if (tls_load_addr == LLDB_INVALID_ADDRESS)
{
if (error_ptr)
error_ptr->SetErrorString ("No TLS data currently exists for this thread.");
return false;
}
- // Convert the TLS offset into the absolute address.
- Scalar tmp = stack.back().ResolveValue(exe_ctx);
- stack.back() = tmp + tls_addr;
+ stack.back().GetScalar() = tls_load_addr;
stack.back().SetValueType (Value::eValueTypeLoadAddress);
}
break;
diff --git a/source/Expression/DiagnosticManager.cpp b/source/Expression/DiagnosticManager.cpp
new file mode 100644
index 000000000000..5156ee38a67b
--- /dev/null
+++ b/source/Expression/DiagnosticManager.cpp
@@ -0,0 +1,91 @@
+//===-- DiagnosticManager.cpp -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Expression/DiagnosticManager.h"
+
+#include "llvm/Support/ErrorHandling.h"
+
+#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamString.h"
+
+using namespace lldb_private;
+
+void
+DiagnosticManager::Dump(Log *log)
+{
+ if (!log)
+ return;
+
+ std::string str = GetString();
+
+ // GetString() puts a separator after each diagnostic.
+ // We want to remove the last '\n' because log->PutCString will add one for us.
+
+ if (str.size() && str.back() == '\n')
+ {
+ str.pop_back();
+ }
+
+ log->PutCString(str.c_str());
+}
+
+static const char *
+StringForSeverity(DiagnosticSeverity severity)
+{
+ switch (severity)
+ {
+ // this should be exhaustive
+ case lldb_private::eDiagnosticSeverityError:
+ return "error: ";
+ case lldb_private::eDiagnosticSeverityWarning:
+ return "warning: ";
+ case lldb_private::eDiagnosticSeverityRemark:
+ return "";
+ }
+ llvm_unreachable("switch needs another case for DiagnosticSeverity enum");
+}
+
+std::string
+DiagnosticManager::GetString(char separator)
+{
+ std::string ret;
+
+ for (const Diagnostic *diagnostic : Diagnostics())
+ {
+ ret.append(StringForSeverity(diagnostic->GetSeverity()));
+ ret.append(diagnostic->GetMessage());
+ ret.push_back(separator);
+ }
+
+ return ret;
+}
+
+size_t
+DiagnosticManager::Printf(DiagnosticSeverity severity, const char *format, ...)
+{
+ StreamString ss;
+
+ va_list args;
+ va_start(args, format);
+ size_t result = ss.PrintfVarArg(format, args);
+ va_end(args);
+
+ AddDiagnostic(ss.GetData(), severity, eDiagnosticOriginLLDB);
+
+ return result;
+}
+
+size_t
+DiagnosticManager::PutCString(DiagnosticSeverity severity, const char *cstr)
+{
+ if (!cstr)
+ return 0;
+ AddDiagnostic(cstr, severity, eDiagnosticOriginLLDB);
+ return strlen(cstr);
+}
diff --git a/source/Expression/ExpressionSourceCode.cpp b/source/Expression/ExpressionSourceCode.cpp
index c4ab7a95d7a9..2d41d1a8b449 100644
--- a/source/Expression/ExpressionSourceCode.cpp
+++ b/source/Expression/ExpressionSourceCode.cpp
@@ -16,7 +16,9 @@
#include "lldb/Symbol/DebugMacros.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/TypeSystem.h"
+#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Language.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
@@ -59,6 +61,9 @@ 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
@@ -106,8 +111,6 @@ public:
{
case CURRENT_FILE_NOT_YET_PUSHED:
return true;
- case CURRENT_FILE_POPPED:
- return false;
case CURRENT_FILE_PUSHED:
// If we are in file included in the current file,
// the entry should be added.
@@ -118,6 +121,8 @@ public:
return false;
else
return true;
+ default:
+ return false;
}
}
@@ -175,12 +180,28 @@ AddMacros(const DebugMacros *dm, CompileUnit *comp_unit, AddMacroState &state, S
}
}
-bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object, bool static_method, ExecutionContext &exe_ctx) const
+static void
+AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp, StreamString &stream)
+{
+ for (size_t i = 0; i < var_list_sp->GetSize(); i++)
+ {
+ lldb::VariableSP var_sp = var_list_sp->GetVariableAtIndex(i);
+
+ ConstString var_name = var_sp->GetName();
+ if (!var_name || var_name == ConstString("this") || var_name == ConstString(".block_descriptor"))
+ continue;
+
+ stream.Printf("using $__lldb_local_vars::%s;\n", var_name.AsCString());
+ }
+}
+
+bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool static_method, ExecutionContext &exe_ctx) const
{
const char *target_specific_defines = "typedef signed char BOOL;\n";
std::string module_macros;
- if (Target *target = exe_ctx.GetTargetPtr())
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target)
{
if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64)
{
@@ -239,6 +260,7 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
}
StreamString debug_macros_stream;
+ StreamString lldb_local_var_decls;
if (StackFrame *frame = exe_ctx.GetFramePtr())
{
const SymbolContext &sc = frame->GetSymbolContext(
@@ -253,8 +275,18 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
AddMacros(dm, sc.comp_unit, state, debug_macros_stream);
}
}
+
+ ConstString object_name;
+ if (Language::LanguageIsCPlusPlus(frame->GetLanguage()))
+ {
+ if (target->GetInjectLocalVariables(&exe_ctx))
+ {
+ lldb::VariableListSP var_list_sp = frame->GetInScopeVariableList(false, true);
+ AddLocalVariableDecls(var_list_sp, lldb_local_var_decls);
+ }
+ }
}
-
+
if (m_wrap)
{
switch (wrapping_language)
@@ -276,6 +308,22 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
target_specific_defines,
m_prefix.c_str());
+ // First construct a tagged form of the user expression so we can find it later:
+ std::string tagged_body;
+ switch (wrapping_language)
+ {
+ default:
+ tagged_body = m_body;
+ break;
+ case lldb::eLanguageTypeC:
+ case lldb::eLanguageTypeC_plus_plus:
+ case lldb::eLanguageTypeObjC:
+ tagged_body.append(c_start_marker);
+ tagged_body.append(m_body);
+ tagged_body.append(c_end_marker);
+ break;
+
+ }
switch (wrapping_language)
{
default:
@@ -284,20 +332,23 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
wrap_stream.Printf("void \n"
"%s(void *$__lldb_arg) \n"
"{ \n"
- " %s; \n"
+ " %s; \n"
+ "%s"
"} \n",
m_name.c_str(),
- m_body.c_str());
+ lldb_local_var_decls.GetData(),
+ tagged_body.c_str());
break;
case lldb::eLanguageTypeC_plus_plus:
wrap_stream.Printf("void \n"
- "$__lldb_class::%s(void *$__lldb_arg) %s\n"
+ "$__lldb_class::%s(void *$__lldb_arg) \n"
"{ \n"
- " %s; \n"
+ " %s; \n"
+ "%s"
"} \n",
m_name.c_str(),
- (const_object ? "const" : ""),
- m_body.c_str());
+ lldb_local_var_decls.GetData(),
+ tagged_body.c_str());
break;
case lldb::eLanguageTypeObjC:
if (static_method)
@@ -308,12 +359,12 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
"@implementation $__lldb_objc_class ($__lldb_category) \n"
"+(void)%s:(void *)$__lldb_arg \n"
"{ \n"
- " %s; \n"
+ "%s"
"} \n"
"@end \n",
m_name.c_str(),
m_name.c_str(),
- m_body.c_str());
+ tagged_body.c_str());
}
else
{
@@ -323,12 +374,12 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
"@implementation $__lldb_objc_class ($__lldb_category) \n"
"-(void)%s:(void *)$__lldb_arg \n"
"{ \n"
- " %s; \n"
+ "%s"
"} \n"
"@end \n",
m_name.c_str(),
m_name.c_str(),
- m_body.c_str());
+ tagged_body.c_str());
}
break;
}
@@ -339,6 +390,38 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
{
text.append(m_body);
}
+
+ return true;
+}
+
+bool
+ExpressionSourceCode::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);
+ if (start_loc == std::string::npos)
+ return false;
+ start_loc += strlen(start_marker);
+ end_loc = transformed_text.find(end_marker);
+ if (end_loc == std::string::npos)
+ return false;
return true;
}
+
diff --git a/source/Expression/ExpressionVariable.cpp b/source/Expression/ExpressionVariable.cpp
index 8bef60fdf1d7..5567ee286aa9 100644
--- a/source/Expression/ExpressionVariable.cpp
+++ b/source/Expression/ExpressionVariable.cpp
@@ -7,7 +7,9 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Core/Log.h"
#include "lldb/Expression/ExpressionVariable.h"
+#include "lldb/Expression/IRExecutionUnit.h"
using namespace lldb_private;
@@ -34,3 +36,55 @@ ExpressionVariable::GetValueBytes()
PersistentExpressionState::~PersistentExpressionState ()
{
}
+
+lldb::addr_t
+PersistentExpressionState::LookupSymbol (const ConstString &name)
+{
+ SymbolMap::iterator si = m_symbol_map.find(name.GetCString());
+
+ if (si != m_symbol_map.end())
+ return si->second;
+ else
+ return LLDB_INVALID_ADDRESS;
+}
+
+
+void
+PersistentExpressionState::RegisterExecutionUnit (lldb::IRExecutionUnitSP &execution_unit_sp)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ m_execution_units.insert(execution_unit_sp);
+
+ if (log)
+ log->Printf ("Registering JITted Functions:\n");
+
+ for (const IRExecutionUnit::JittedFunction &jitted_function : execution_unit_sp->GetJittedFunctions())
+ {
+ if (jitted_function.m_external &&
+ jitted_function.m_name != execution_unit_sp->GetFunctionName() &&
+ jitted_function.m_remote_addr != LLDB_INVALID_ADDRESS)
+ {
+ m_symbol_map[jitted_function.m_name.GetCString()] = jitted_function.m_remote_addr;
+ if (log)
+ log->Printf (" Function: %s at 0x%" PRIx64 ".", jitted_function.m_name.GetCString(), jitted_function.m_remote_addr);
+ }
+ }
+
+ if (log)
+ log->Printf ("Registering JIIted Symbols:\n");
+
+ for (const IRExecutionUnit::JittedGlobalVariable &global_var : execution_unit_sp->GetJittedGlobalVariables())
+ {
+ if (global_var.m_remote_addr != LLDB_INVALID_ADDRESS)
+ {
+ // Demangle the name before inserting it, so that lookups by the ConstStr of the demangled name
+ // will find the mangled one (needed for looking up metadata pointers.)
+ Mangled mangler(global_var.m_name);
+ mangler.GetDemangledName(lldb::eLanguageTypeUnknown);
+ m_symbol_map[global_var.m_name.GetCString()] = global_var.m_remote_addr;
+ if (log)
+ log->Printf (" Symbol: %s at 0x%" PRIx64 ".", global_var.m_name.GetCString(), global_var.m_remote_addr);
+ }
+ }
+}
diff --git a/source/Expression/FunctionCaller.cpp b/source/Expression/FunctionCaller.cpp
index ddc378dcb416..3a4f1fe33add 100644
--- a/source/Expression/FunctionCaller.cpp
+++ b/source/Expression/FunctionCaller.cpp
@@ -13,13 +13,14 @@
// Other libraries and framework includes
// Project includes
+#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/State.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectList.h"
-#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/Function.h"
@@ -76,11 +77,11 @@ FunctionCaller::~FunctionCaller()
lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
if (jit_module_sp)
process_sp->GetTarget().GetImages().Remove(jit_module_sp);
- }
+ }
}
bool
-FunctionCaller::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
+FunctionCaller::WriteFunctionWrapper(ExecutionContext &exe_ctx, DiagnosticManager &diagnostic_manager)
{
Process *process = exe_ctx.GetProcessPtr();
@@ -133,27 +134,28 @@ FunctionCaller::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
}
bool
-FunctionCaller::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
+FunctionCaller::WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref,
+ DiagnosticManager &diagnostic_manager)
{
- return WriteFunctionArguments(exe_ctx, args_addr_ref, m_arg_values, errors);
+ return WriteFunctionArguments(exe_ctx, args_addr_ref, m_arg_values, diagnostic_manager);
}
// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.
bool
-FunctionCaller::WriteFunctionArguments (ExecutionContext &exe_ctx,
- lldb::addr_t &args_addr_ref,
- ValueList &arg_values,
- Stream &errors)
+FunctionCaller::WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, ValueList &arg_values,
+ DiagnosticManager &diagnostic_manager)
{
// All the information to reconstruct the struct is provided by the
// StructExtractor.
if (!m_struct_valid)
{
- errors.Printf("Argument information was not correctly parsed, so the function cannot be called.");
+ diagnostic_manager.PutCString(
+ eDiagnosticSeverityError,
+ "Argument information was not correctly parsed, so the function cannot be called.");
return false;
}
-
+
Error error;
lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
@@ -191,14 +193,16 @@ FunctionCaller::WriteFunctionArguments (ExecutionContext &exe_ctx,
// FIXME: We will need to extend this for Variadic functions.
Error value_error;
-
+
size_t num_args = arg_values.GetSize();
if (num_args != m_arg_values.GetSize())
{
- errors.Printf ("Wrong number of arguments - was: %" PRIu64 " should be: %" PRIu64 "", (uint64_t)num_args, (uint64_t)m_arg_values.GetSize());
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "Wrong number of arguments - was: %" PRIu64 " should be: %" PRIu64 "",
+ (uint64_t)num_args, (uint64_t)m_arg_values.GetSize());
return false;
}
-
+
for (size_t i = 0; i < num_args; i++)
{
// FIXME: We should sanity check sizes.
@@ -225,16 +229,17 @@ FunctionCaller::WriteFunctionArguments (ExecutionContext &exe_ctx,
}
bool
-FunctionCaller::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
+FunctionCaller::InsertFunction(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref,
+ DiagnosticManager &diagnostic_manager)
{
- if (CompileFunction(errors) != 0)
+ if (CompileFunction(exe_ctx.GetThreadSP(), diagnostic_manager) != 0)
return false;
- if (!WriteFunctionWrapper(exe_ctx, errors))
+ if (!WriteFunctionWrapper(exe_ctx, diagnostic_manager))
return false;
- if (!WriteFunctionArguments(exe_ctx, args_addr_ref, errors))
+ if (!WriteFunctionArguments(exe_ctx, args_addr_ref, diagnostic_manager))
return false;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log)
log->Printf ("Call Address: 0x%" PRIx64 " Struct Address: 0x%" PRIx64 ".\n", m_jit_start_addr, args_addr_ref);
@@ -242,13 +247,12 @@ FunctionCaller::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_ad
}
lldb::ThreadPlanSP
-FunctionCaller::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
- lldb::addr_t args_addr,
+FunctionCaller::GetThreadPlanToCallFunction(ExecutionContext &exe_ctx, lldb::addr_t args_addr,
const EvaluateExpressionOptions &options,
- Stream &errors)
+ DiagnosticManager &diagnostic_manager)
{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
-
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
+
if (log)
log->Printf("-- [FunctionCaller::GetThreadPlanToCallFunction] Creating thread plan to call function \"%s\" --", m_name.c_str());
@@ -256,7 +260,7 @@ FunctionCaller::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
Thread *thread = exe_ctx.GetThreadPtr();
if (thread == NULL)
{
- errors.Printf("Can't call a function without a valid thread.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "Can't call a function without a valid thread.");
return NULL;
}
@@ -322,15 +326,12 @@ FunctionCaller::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr
}
lldb::ExpressionResults
-FunctionCaller::ExecuteFunction(
- ExecutionContext &exe_ctx,
- lldb::addr_t *args_addr_ptr,
- const EvaluateExpressionOptions &options,
- Stream &errors,
- Value &results)
+FunctionCaller::ExecuteFunction(ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr,
+ const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager,
+ Value &results)
{
lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
-
+
// FunctionCaller::ExecuteFunction execution is always just to get the result. Do make sure we ignore
// breakpoints, unwind on error, and don't try to debug it.
EvaluateExpressionOptions real_options = options;
@@ -345,12 +346,12 @@ FunctionCaller::ExecuteFunction(
else
args_addr = LLDB_INVALID_ADDRESS;
- if (CompileFunction(errors) != 0)
+ if (CompileFunction(exe_ctx.GetThreadSP(), diagnostic_manager) != 0)
return lldb::eExpressionSetupError;
-
+
if (args_addr == LLDB_INVALID_ADDRESS)
{
- if (!InsertFunction(exe_ctx, args_addr, errors))
+ if (!InsertFunction(exe_ctx, args_addr, diagnostic_manager))
return lldb::eExpressionSetupError;
}
@@ -358,24 +359,18 @@ FunctionCaller::ExecuteFunction(
if (log)
log->Printf("== [FunctionCaller::ExecuteFunction] Executing function \"%s\" ==", m_name.c_str());
-
- lldb::ThreadPlanSP call_plan_sp = GetThreadPlanToCallFunction (exe_ctx,
- args_addr,
- real_options,
- errors);
+
+ lldb::ThreadPlanSP call_plan_sp = GetThreadPlanToCallFunction(exe_ctx, args_addr, real_options, diagnostic_manager);
if (!call_plan_sp)
return lldb::eExpressionSetupError;
-
+
// We need to make sure we record the fact that we are running an expression here
// otherwise this fact will fail to be recorded when fetching an Objective-C object description
if (exe_ctx.GetProcessPtr())
exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
-
- return_value = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
- call_plan_sp,
- real_options,
- errors);
-
+
+ return_value = exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, real_options, diagnostic_manager);
+
if (log)
{
if (return_value != lldb::eExpressionCompleted)
diff --git a/source/Expression/IRDynamicChecks.cpp b/source/Expression/IRDynamicChecks.cpp
index 64fdb08157aa..62bcfe0d14b8 100644
--- a/source/Expression/IRDynamicChecks.cpp
+++ b/source/Expression/IRDynamicChecks.cpp
@@ -50,8 +50,7 @@ DynamicCheckerFunctions::DynamicCheckerFunctions() = default;
DynamicCheckerFunctions::~DynamicCheckerFunctions() = default;
bool
-DynamicCheckerFunctions::Install(Stream &error_stream,
- ExecutionContext &exe_ctx)
+DynamicCheckerFunctions::Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx)
{
Error error;
m_valid_pointer_check.reset(exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_valid_pointer_check_text,
@@ -60,8 +59,8 @@ DynamicCheckerFunctions::Install(Stream &error_stream,
error));
if (error.Fail())
return false;
-
- if (!m_valid_pointer_check->Install(error_stream, exe_ctx))
+
+ if (!m_valid_pointer_check->Install(diagnostic_manager, exe_ctx))
return false;
Process *process = exe_ctx.GetProcessPtr();
@@ -74,7 +73,7 @@ DynamicCheckerFunctions::Install(Stream &error_stream,
{
m_objc_object_check.reset(objc_language_runtime->CreateObjectChecker(VALID_OBJC_OBJECT_CHECK_NAME));
- if (!m_objc_object_check->Install(error_stream, exe_ctx))
+ if (!m_objc_object_check->Install(diagnostic_manager, exe_ctx))
return false;
}
}
@@ -506,6 +505,32 @@ protected:
return true;
}
+
+ static llvm::Function *GetFunction(llvm::Value *value)
+ {
+ if (llvm::Function *function = llvm::dyn_cast<llvm::Function>(value))
+ {
+ return function;
+ }
+
+ if (llvm::ConstantExpr *const_expr = llvm::dyn_cast<llvm::ConstantExpr>(value))
+ {
+ switch (const_expr->getOpcode())
+ {
+ default:
+ return nullptr;
+ case llvm::Instruction::BitCast:
+ return GetFunction(const_expr->getOperand(0));
+ }
+ }
+
+ return nullptr;
+ }
+
+ static llvm::Function *GetCalledFunction(llvm::CallInst *inst)
+ {
+ return GetFunction(inst->getCalledValue());
+ }
bool InspectInstruction(llvm::Instruction &i) override
{
@@ -515,35 +540,12 @@ protected:
if (call_inst)
{
- // This metadata is set by IRForTarget::MaybeHandleCall().
-
- MDNode *metadata = call_inst->getMetadata("lldb.call.realName");
-
- if (!metadata)
+ const llvm::Function *called_function = GetCalledFunction(call_inst);
+
+ if (!called_function)
return true;
-
- if (metadata->getNumOperands() != 1)
- {
- if (log)
- log->Printf("Function call metadata has %d operands for [%p] %s",
- metadata->getNumOperands(),
- static_cast<void*>(call_inst),
- PrintValue(call_inst).c_str());
- return false;
- }
-
- MDString *real_name = dyn_cast<MDString>(metadata->getOperand(0));
-
- if (!real_name)
- {
- if (log)
- log->Printf("Function call metadata is not an MDString for [%p] %s",
- static_cast<void*>(call_inst),
- PrintValue(call_inst).c_str());
- return false;
- }
-
- std::string name_str = real_name->getString();
+
+ std::string name_str = called_function->getName().str();
const char* name_cstr = name_str.c_str();
if (log)
diff --git a/source/Expression/IRExecutionUnit.cpp b/source/Expression/IRExecutionUnit.cpp
index 3f19c508c926..103d76328c3a 100644
--- a/source/Expression/IRExecutionUnit.cpp
+++ b/source/Expression/IRExecutionUnit.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
@@ -20,11 +21,17 @@
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
+#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+#include "lldb/../../source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
using namespace lldb_private;
@@ -32,6 +39,7 @@ IRExecutionUnit::IRExecutionUnit (std::unique_ptr<llvm::LLVMContext> &context_ap
std::unique_ptr<llvm::Module> &module_ap,
ConstString &name,
const lldb::TargetSP &target_sp,
+ const SymbolContext &sym_ctx,
std::vector<std::string> &cpu_features) :
IRMemoryMap(target_sp),
m_context_ap(context_ap.release()),
@@ -39,9 +47,11 @@ IRExecutionUnit::IRExecutionUnit (std::unique_ptr<llvm::LLVMContext> &context_ap
m_module(m_module_ap.get()),
m_cpu_features(cpu_features),
m_name(name),
+ m_sym_ctx(sym_ctx),
m_did_jit(false),
m_function_load_addr(LLDB_INVALID_ADDRESS),
- m_function_end_load_addr(LLDB_INVALID_ADDRESS)
+ m_function_end_load_addr(LLDB_INVALID_ADDRESS),
+ m_reported_allocations(false)
{
}
@@ -115,7 +125,7 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,
for (JittedFunction &function : m_jitted_functions)
{
- if (strstr(function.m_name.c_str(), m_name.AsCString()))
+ if (function.m_name == m_name)
{
func_local_addr = function.m_local_addr;
func_remote_addr = function.m_remote_addr;
@@ -206,10 +216,6 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,
InstructionList &instruction_list = disassembler_sp->GetInstructionList();
instruction_list.Dump(&stream, true, true, &exe_ctx);
-
- // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
- // I'll fix that but for now, just clear the list and it will go away nicely.
- disassembler_sp->GetInstructionList().Clear();
return ret;
}
@@ -237,7 +243,7 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
{
lldb::ProcessSP process_sp(GetProcessWP().lock());
- static Mutex s_runnable_info_mutex(Mutex::Type::eMutexTypeRecursive);
+ static std::recursive_mutex s_runnable_info_mutex;
func_addr = LLDB_INVALID_ADDRESS;
func_end = LLDB_INVALID_ADDRESS;
@@ -257,7 +263,7 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
return;
};
- Mutex::Locker runnable_info_mutex_locker(s_runnable_info_mutex);
+ std::lock_guard<std::recursive_mutex> guard(s_runnable_info_mutex);
m_did_jit = true;
@@ -278,22 +284,21 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
}
llvm::Triple triple(m_module->getTargetTriple());
- llvm::Function *function = m_module->getFunction (m_name.AsCString());
llvm::Reloc::Model relocModel;
llvm::CodeModel::Model codeModel;
if (triple.isOSBinFormatELF())
{
relocModel = llvm::Reloc::Static;
- // This will be small for 32-bit and large for 64-bit.
- codeModel = llvm::CodeModel::JITDefault;
}
else
{
relocModel = llvm::Reloc::PIC_;
- codeModel = llvm::CodeModel::Small;
}
+ // This will be small for 32-bit and large for 64-bit.
+ codeModel = llvm::CodeModel::JITDefault;
+
m_module_ap->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError, &error);
llvm::EngineBuilder builder(std::move(m_module_ap));
@@ -319,6 +324,8 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
m_execution_engine_ap.reset(builder.create(target_machine));
+ m_strip_underscore = (m_execution_engine_ap->getDataLayout().getGlobalPrefix() == '_');
+
if (!m_execution_engine_ap.get())
{
error.SetErrorToGenericError();
@@ -331,44 +338,79 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
m_execution_engine_ap->DisableLazyCompilation();
- // We don't actually need the function pointer here, this just forces it to get resolved.
-
- void *fun_ptr = m_execution_engine_ap->getPointerToFunction(function);
-
- if (!error.Success())
+ for (llvm::Function &function : *m_module)
{
- // We got an error through our callback!
- return;
+ if (function.isDeclaration() || function.hasPrivateLinkage())
+ continue;
+
+ const bool external = function.hasExternalLinkage() || function.hasLinkOnceODRLinkage();
+
+ void *fun_ptr = m_execution_engine_ap->getPointerToFunction(&function);
+
+ if (!error.Success())
+ {
+ // We got an error through our callback!
+ return;
+ }
+
+ if (!fun_ptr)
+ {
+ error.SetErrorToGenericError();
+ error.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", function.getName().str().c_str());
+ return;
+ }
+ m_jitted_functions.push_back (JittedFunction(function.getName().str().c_str(), external, (lldb::addr_t)fun_ptr));
}
- if (!function)
+ CommitAllocations(process_sp);
+ ReportAllocations(*m_execution_engine_ap);
+
+ // We have to do this after calling ReportAllocations because for the MCJIT, getGlobalValueAddress
+ // will cause the JIT to perform all relocations. That can only be done once, and has to happen
+ // after we do the remapping from local -> remote.
+ // That means we don't know the local address of the Variables, but we don't need that for anything,
+ // so that's okay.
+
+ std::function<void (llvm::GlobalValue &)> RegisterOneValue = [this] (llvm::GlobalValue &val) {
+ if (val.hasExternalLinkage() && !val.isDeclaration())
+ {
+ uint64_t var_ptr_addr = m_execution_engine_ap->getGlobalValueAddress(val.getName().str());
+
+ lldb::addr_t remote_addr = GetRemoteAddressForLocal(var_ptr_addr);
+
+ // This is a really unfortunae API that sometimes returns local addresses and sometimes returns remote addresses, based on whether
+ // the variable was relocated during ReportAllocations or not.
+
+ if (remote_addr == LLDB_INVALID_ADDRESS)
+ {
+ remote_addr = var_ptr_addr;
+ }
+
+ if (var_ptr_addr != 0)
+ m_jitted_global_variables.push_back (JittedGlobalVariable (val.getName().str().c_str(), LLDB_INVALID_ADDRESS, remote_addr));
+ }
+ };
+
+ for (llvm::GlobalVariable &global_var : m_module->getGlobalList())
{
- error.SetErrorToGenericError();
- error.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", m_name.AsCString());
- return;
+ RegisterOneValue(global_var);
}
-
- if (!fun_ptr)
+
+ for (llvm::GlobalAlias &global_alias : m_module->getAliasList())
{
- error.SetErrorToGenericError();
- error.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", m_name.AsCString());
- return;
+ RegisterOneValue(global_alias);
}
- m_jitted_functions.push_back (JittedFunction(m_name.AsCString(), (lldb::addr_t)fun_ptr));
-
- CommitAllocations(process_sp);
- ReportAllocations(*m_execution_engine_ap);
WriteData(process_sp);
if (m_failed_lookups.size())
{
StreamString ss;
-
+
ss.PutCString("Couldn't lookup symbols:\n");
-
+
bool emitNewLine = false;
-
+
for (const ConstString &failed_lookup : m_failed_lookups)
{
if (emitNewLine)
@@ -377,14 +419,14 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
ss.PutCString(" ");
ss.PutCString(Mangled(failed_lookup).GetDemangledName(lldb::eLanguageTypeObjC_plus_plus).AsCString());
}
-
+
m_failed_lookups.clear();
-
+
error.SetErrorString(ss.GetData());
-
+
return;
}
-
+
m_function_load_addr = LLDB_INVALID_ADDRESS;
m_function_end_load_addr = LLDB_INVALID_ADDRESS;
@@ -392,7 +434,7 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
{
jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr);
- if (!jitted_function.m_name.compare(m_name.AsCString()))
+ if (!m_name.IsEmpty() && jitted_function.m_name == m_name)
{
AddrRange func_range = GetRemoteRangeForLocal(jitted_function.m_local_addr);
m_function_end_load_addr = func_range.first + func_range.second;
@@ -437,7 +479,7 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
else
{
record.dump(log);
-
+
DataExtractor my_extractor ((const void*)record.m_host_address, record.m_size, lldb::eByteOrderBig, 8);
my_extractor.PutToLog(log, 0, record.m_size, record.m_host_address, 16, DataExtractor::TypeUInt8);
}
@@ -603,6 +645,14 @@ IRExecutionUnit::MemoryManager::allocateCodeSection(uintptr_t Size,
log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
(uint64_t)Size, Alignment, SectionID, (void *)return_value);
}
+
+ if (m_parent.m_reported_allocations)
+ {
+ Error err;
+ lldb::ProcessSP process_sp = m_parent.GetBestExecutionContextScope()->CalculateProcess();
+
+ m_parent.CommitOneAllocation(process_sp, err, m_parent.m_records.back());
+ }
return return_value;
}
@@ -633,105 +683,449 @@ IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size,
log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
(uint64_t)Size, Alignment, SectionID, (void *)return_value);
}
+
+ if (m_parent.m_reported_allocations)
+ {
+ Error err;
+ lldb::ProcessSP process_sp = m_parent.GetBestExecutionContextScope()->CalculateProcess();
+
+ m_parent.CommitOneAllocation(process_sp, err, m_parent.m_records.back());
+ }
return return_value;
}
-uint64_t
-IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name)
+static ConstString
+FindBestAlternateMangledName(const ConstString &demangled,
+ const lldb::LanguageType &lang_type,
+ const SymbolContext &sym_ctx)
{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- SymbolContextList sc_list;
-
- ExecutionContextScope *exe_scope = m_parent.GetBestExecutionContextScope();
-
- lldb::TargetSP target_sp = exe_scope->CalculateTarget();
-
- const char *name = Name.c_str();
-
- ConstString bare_name_cs(name);
- ConstString name_cs;
-
- if (name[0] == '_')
- name_cs = ConstString(name + 1);
-
- if (!target_sp)
+ CPlusPlusLanguage::MethodName cpp_name(demangled);
+ std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();
+
+ if (!scope_qualified_name.size())
+ return ConstString();
+
+ if (!sym_ctx.module_sp)
+ return ConstString();
+
+ SymbolVendor *sym_vendor = sym_ctx.module_sp->GetSymbolVendor();
+ if (!sym_vendor)
+ return ConstString();
+
+ lldb_private::SymbolFile *sym_file = sym_vendor->GetSymbolFile();
+ if (!sym_file)
+ return ConstString();
+
+ std::vector<ConstString> alternates;
+ sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);
+
+ std::vector<ConstString> param_and_qual_matches;
+ std::vector<ConstString> param_matches;
+ for (size_t i = 0; i < alternates.size(); i++)
{
- if (log)
- log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <no target>",
- Name.c_str());
-
- m_parent.ReportSymbolLookupError(name_cs);
-
- return 0xbad0bad0;
+ ConstString alternate_mangled_name = alternates[i];
+ Mangled mangled(alternate_mangled_name, true);
+ ConstString demangled = mangled.GetDemangledName(lang_type);
+
+ CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
+ if (!cpp_name.IsValid())
+ continue;
+
+ if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments())
+ {
+ if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
+ param_and_qual_matches.push_back(alternate_mangled_name);
+ else
+ param_matches.push_back(alternate_mangled_name);
+ }
}
-
- uint32_t num_matches = 0;
- lldb::ProcessSP process_sp = exe_scope->CalculateProcess();
-
- if (!name_cs.IsEmpty())
+
+ if (param_and_qual_matches.size())
+ return param_and_qual_matches[0]; // It is assumed that there will be only one!
+ else if (param_matches.size())
+ return param_matches[0]; // Return one of them as a best match
+ else
+ return ConstString();
+}
+
+struct IRExecutionUnit::SearchSpec
+{
+ ConstString name;
+ uint32_t mask;
+
+ SearchSpec(ConstString n, uint32_t m = lldb::eFunctionNameTypeFull) :
+ name(n),
+ mask(m)
{
- target_sp->GetImages().FindSymbolsWithNameAndType(name_cs, lldb::eSymbolTypeAny, sc_list);
- num_matches = sc_list.GetSize();
}
-
- if (!num_matches)
+};
+
+void
+IRExecutionUnit::CollectCandidateCNames(std::vector<IRExecutionUnit::SearchSpec> &C_specs, const ConstString &name)
+{
+ if (m_strip_underscore && name.AsCString()[0] == '_')
+ C_specs.insert(C_specs.begin(), ConstString(&name.AsCString()[1]));
+ C_specs.push_back(SearchSpec(name));
+}
+
+void
+IRExecutionUnit::CollectCandidateCPlusPlusNames(std::vector<IRExecutionUnit::SearchSpec> &CPP_specs, const std::vector<SearchSpec> &C_specs, const SymbolContext &sc)
+{
+ for (const SearchSpec &C_spec : C_specs)
{
- target_sp->GetImages().FindSymbolsWithNameAndType(bare_name_cs, lldb::eSymbolTypeAny, sc_list);
- num_matches = sc_list.GetSize();
+ const ConstString &name = C_spec.name;
+
+ if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString()))
+ {
+ Mangled mangled(name, true);
+ ConstString demangled = mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus);
+
+ if (demangled)
+ {
+ ConstString best_alternate_mangled_name = FindBestAlternateMangledName(demangled, lldb::eLanguageTypeC_plus_plus, sc);
+
+ if (best_alternate_mangled_name)
+ {
+ CPP_specs.push_back(best_alternate_mangled_name);
+ }
+
+ CPP_specs.push_back(SearchSpec(demangled, lldb::eFunctionNameTypeFull));
+ }
+ }
+
+ // Maybe we're looking for a const symbol but the debug info told us it was const...
+ if (!strncmp(name.GetCString(), "_ZN", 3) &&
+ strncmp(name.GetCString(), "_ZNK", 4))
+ {
+ std::string fixed_scratch("_ZNK");
+ fixed_scratch.append(name.GetCString() + 3);
+ CPP_specs.push_back(ConstString(fixed_scratch.c_str()));
+ }
+
+ // Maybe we're looking for a static symbol but we thought it was global...
+ if (!strncmp(name.GetCString(), "_Z", 2) &&
+ strncmp(name.GetCString(), "_ZL", 3))
+ {
+ std::string fixed_scratch("_ZL");
+ fixed_scratch.append(name.GetCString() + 2);
+ CPP_specs.push_back(ConstString(fixed_scratch.c_str()));
+ }
+
}
-
- lldb::addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
+}
+
+void
+IRExecutionUnit::CollectFallbackNames(std::vector<SearchSpec> &fallback_specs,
+ const std::vector<SearchSpec> &C_specs)
+{
+ // As a last-ditch fallback, try the base name for C++ names. It's terrible,
+ // but the DWARF doesn't always encode "extern C" correctly.
- for (uint32_t i=0; i<num_matches && (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS); i++)
+ for (const SearchSpec &C_spec : C_specs)
{
- SymbolContext sym_ctx;
- sc_list.GetContextAtIndex(i, sym_ctx);
+ const ConstString &name = C_spec.name;
- symbol_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target_sp);
+ if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString()))
+ {
+ Mangled mangled_name(name);
+ ConstString demangled_name = mangled_name.GetDemangledName(lldb::eLanguageTypeC_plus_plus);
+ if (!demangled_name.IsEmpty())
+ {
+ const char *demangled_cstr = demangled_name.AsCString();
+ const char *lparen_loc = strchr(demangled_cstr, '(');
+ if (lparen_loc)
+ {
+ llvm::StringRef base_name(demangled_cstr, lparen_loc-demangled_cstr);
+ fallback_specs.push_back(ConstString(base_name));
+ }
+ }
+ }
+ }
+}
+
+
+lldb::addr_t
+IRExecutionUnit::FindInSymbols(const std::vector<IRExecutionUnit::SearchSpec> &specs, const lldb_private::SymbolContext &sc)
+{
+ Target *target = sc.target_sp.get();
- if (symbol_load_addr == LLDB_INVALID_ADDRESS)
- symbol_load_addr = sym_ctx.symbol->GetAddress().GetLoadAddress(target_sp.get());
+ if (!target)
+ {
+ // we shouldn't be doing any symbol lookup at all without a target
+ return LLDB_INVALID_ADDRESS;
}
+
+ for (const SearchSpec &spec : specs)
+ {
+ SymbolContextList sc_list;
+
+ lldb::addr_t best_internal_load_address = LLDB_INVALID_ADDRESS;
+
+ std::function<bool (lldb::addr_t &, SymbolContextList &, const lldb_private::SymbolContext &)> get_external_load_address =
+ [&best_internal_load_address, target](lldb::addr_t &load_address,
+ SymbolContextList &sc_list,
+ const lldb_private::SymbolContext &sc) -> lldb::addr_t
+ {
+ load_address = LLDB_INVALID_ADDRESS;
+
+ for (size_t si = 0, se = sc_list.GetSize(); si < se; ++si)
+ {
+ SymbolContext candidate_sc;
+
+ sc_list.GetContextAtIndex(si, candidate_sc);
+
+ const bool is_external = (candidate_sc.function) ||
+ (candidate_sc.symbol && candidate_sc.symbol->IsExternal());
+ if (candidate_sc.symbol)
+ {
+ load_address = candidate_sc.symbol->ResolveCallableAddress(*target);
+
+ if (load_address == LLDB_INVALID_ADDRESS)
+ {
+ if (target->GetProcessSP())
+ load_address = candidate_sc.symbol->GetAddress().GetLoadAddress(target);
+ else
+ load_address = candidate_sc.symbol->GetAddress().GetFileAddress();
+ }
+ }
+
+ if (load_address == LLDB_INVALID_ADDRESS && candidate_sc.function)
+ {
+ if (target->GetProcessSP())
+ load_address = candidate_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(target);
+ else
+ load_address = candidate_sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
+ }
+
+ if (load_address != LLDB_INVALID_ADDRESS)
+ {
+ if (is_external)
+ {
+ return true;
+ }
+ else if (best_internal_load_address == LLDB_INVALID_ADDRESS)
+ {
+ best_internal_load_address = load_address;
+ load_address = LLDB_INVALID_ADDRESS;
+ }
+ }
+ }
+
+ return false;
+ };
+
+ if (sc.module_sp)
+ {
+ sc.module_sp->FindFunctions(spec.name,
+ NULL,
+ spec.mask,
+ true, // include_symbols
+ false, // include_inlines
+ true, // append
+ sc_list);
+ }
+
+ lldb::addr_t load_address = LLDB_INVALID_ADDRESS;
+
+ if (get_external_load_address(load_address, sc_list, sc))
+ {
+ return load_address;
+ }
+ else
+ {
+ sc_list.Clear();
+ }
+
+ if (sc_list.GetSize() == 0 && sc.target_sp)
+ {
+ sc.target_sp->GetImages().FindFunctions(spec.name,
+ spec.mask,
+ true, // include_symbols
+ false, // include_inlines
+ true, // append
+ sc_list);
+ }
+
+ if (get_external_load_address(load_address, sc_list, sc))
+ {
+ return load_address;
+ }
+ else
+ {
+ sc_list.Clear();
+ }
+
+ if (sc_list.GetSize() == 0 && sc.target_sp)
+ {
+ sc.target_sp->GetImages().FindSymbolsWithNameAndType(spec.name, lldb::eSymbolTypeAny, sc_list);
+ }
+
+ if (get_external_load_address(load_address, sc_list, sc))
+ {
+ return load_address;
+ }
+ // if there are any searches we try after this, add an sc_list.Clear() in an "else" clause here
+
+ if (best_internal_load_address != LLDB_INVALID_ADDRESS)
+ {
+ return best_internal_load_address;
+ }
+ }
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+lldb::addr_t
+IRExecutionUnit::FindInRuntimes(const std::vector<SearchSpec> &specs, const lldb_private::SymbolContext &sc)
+{
+ lldb::TargetSP target_sp = sc.target_sp;
+
+ if (!target_sp)
+ {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ lldb::ProcessSP process_sp = sc.target_sp->GetProcessSP();
+
+ if (!process_sp)
+ {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
+
+ if (runtime)
+ {
+ for (const SearchSpec &spec : specs)
+ {
+ lldb::addr_t symbol_load_addr = runtime->LookupRuntimeSymbol(spec.name);
+
+ if (symbol_load_addr != LLDB_INVALID_ADDRESS)
+ return symbol_load_addr;
+ }
+ }
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+lldb::addr_t
+IRExecutionUnit::FindInUserDefinedSymbols(const std::vector<SearchSpec> &specs, const lldb_private::SymbolContext &sc)
+{
+ lldb::TargetSP target_sp = sc.target_sp;
- if (symbol_load_addr == LLDB_INVALID_ADDRESS && process_sp && name_cs)
+ for (const SearchSpec &spec : specs)
{
- // Try the Objective-C language runtime.
-
- ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
+ lldb::addr_t symbol_load_addr = target_sp->GetPersistentSymbol(spec.name);
- if (runtime)
- symbol_load_addr = runtime->LookupRuntimeSymbol(name_cs);
+ if (symbol_load_addr != LLDB_INVALID_ADDRESS)
+ return symbol_load_addr;
}
- if (symbol_load_addr == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+}
+
+lldb::addr_t
+IRExecutionUnit::FindSymbol(const lldb_private::ConstString &name)
+{
+ std::vector<SearchSpec> candidate_C_names;
+ std::vector<SearchSpec> candidate_CPlusPlus_names;
+
+ CollectCandidateCNames(candidate_C_names, name);
+
+ lldb::addr_t ret = FindInSymbols(candidate_C_names, m_sym_ctx);
+ if (ret == LLDB_INVALID_ADDRESS)
+ ret = FindInRuntimes(candidate_C_names, m_sym_ctx);
+
+ if (ret == LLDB_INVALID_ADDRESS)
+ ret = FindInUserDefinedSymbols(candidate_C_names, m_sym_ctx);
+
+ if (ret == LLDB_INVALID_ADDRESS)
+ {
+ CollectCandidateCPlusPlusNames(candidate_CPlusPlus_names, candidate_C_names, m_sym_ctx);
+ ret = FindInSymbols(candidate_CPlusPlus_names, m_sym_ctx);
+ }
+
+ if (ret == LLDB_INVALID_ADDRESS)
+ {
+ std::vector<SearchSpec> candidate_fallback_names;
+
+ CollectFallbackNames(candidate_fallback_names, candidate_C_names);
+ ret = FindInSymbols(candidate_fallback_names, m_sym_ctx);
+ }
+
+ return ret;
+}
+
+void
+IRExecutionUnit::GetStaticInitializers(std::vector <lldb::addr_t> &static_initializers)
+{
+ if (llvm::GlobalVariable *global_ctors = m_module->getNamedGlobal("llvm.global_ctors"))
+ {
+ if (llvm::ConstantArray *ctor_array = llvm::dyn_cast<llvm::ConstantArray>(global_ctors->getInitializer()))
+ {
+ for (llvm::Use &ctor_use : ctor_array->operands())
+ {
+ if (llvm::ConstantStruct *ctor_struct = llvm::dyn_cast<llvm::ConstantStruct>(ctor_use))
+ {
+ lldbassert(ctor_struct->getNumOperands() == 3); // this is standardized
+ if (llvm::Function *ctor_function = llvm::dyn_cast<llvm::Function>(ctor_struct->getOperand(1)))
+ {
+ ctor_function->dump();
+
+ ConstString ctor_function_name_cs(ctor_function->getName().str());
+
+ for (JittedFunction &jitted_function : m_jitted_functions)
+ {
+ if (ctor_function_name_cs == jitted_function.m_name)
+ {
+ if (jitted_function.m_remote_addr != LLDB_INVALID_ADDRESS)
+ {
+ static_initializers.push_back(jitted_function.m_remote_addr);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+uint64_t
+IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ ConstString name_cs(Name.c_str());
+
+ lldb::addr_t ret = m_parent.FindSymbol(name_cs);
+
+ if (ret == LLDB_INVALID_ADDRESS)
{
if (log)
log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <not found>",
- name);
-
- m_parent.ReportSymbolLookupError(bare_name_cs);
-
+ Name.c_str());
+
+ m_parent.ReportSymbolLookupError(name_cs);
return 0xbad0bad0;
}
-
- if (log)
- log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
- name,
- symbol_load_addr);
-
- if (symbol_load_addr == 0)
- return 0xbad00add;
-
- return symbol_load_addr;
+ else
+ {
+ if (log)
+ log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
+ Name.c_str(),
+ ret);
+ return ret;
+ }
}
void *
IRExecutionUnit::MemoryManager::getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure) {
assert (sizeof(void *) == 8);
-
+
return (void*)getSymbolAddress(Name);
}
@@ -787,19 +1181,17 @@ IRExecutionUnit::GetRemoteRangeForLocal (lldb::addr_t local_address)
}
bool
-IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
+IRExecutionUnit::CommitOneAllocation (lldb::ProcessSP &process_sp,
+ Error &error,
+ AllocationRecord &record)
{
- bool ret = true;
-
- lldb_private::Error err;
-
- for (AllocationRecord &record : m_records)
+ if (record.m_process_address != LLDB_INVALID_ADDRESS)
+ {
+ return true;
+ }
+
+ switch (record.m_sect_type)
{
- if (record.m_process_address != LLDB_INVALID_ADDRESS)
- continue;
-
- switch (record.m_sect_type)
- {
case lldb::eSectionTypeInvalid:
case lldb::eSectionTypeDWARFDebugAbbrev:
case lldb::eSectionTypeDWARFDebugAddr:
@@ -818,7 +1210,7 @@ IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
case lldb::eSectionTypeDWARFAppleTypes:
case lldb::eSectionTypeDWARFAppleNamespaces:
case lldb::eSectionTypeDWARFAppleObjC:
- err.Clear();
+ error.Clear();
break;
default:
const bool zero_memory = false;
@@ -827,13 +1219,26 @@ IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
record.m_permissions,
eAllocationPolicyProcessOnly,
zero_memory,
- err);
+ error);
break;
- }
+ }
+
+ return error.Success();
+}
- if (!err.Success())
+bool
+IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
+{
+ bool ret = true;
+
+ lldb_private::Error err;
+
+ for (AllocationRecord &record : m_records)
+ {
+ ret = CommitOneAllocation(process_sp, err, record);
+
+ if (!ret)
{
- ret = false;
break;
}
}
@@ -856,6 +1261,8 @@ IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
void
IRExecutionUnit::ReportAllocations (llvm::ExecutionEngine &engine)
{
+ m_reported_allocations = true;
+
for (AllocationRecord &record : m_records)
{
if (record.m_process_address == LLDB_INVALID_ADDRESS)
diff --git a/source/Expression/IRInterpreter.cpp b/source/Expression/IRInterpreter.cpp
index a2b0c5b86851..0285248314b6 100644
--- a/source/Expression/IRInterpreter.cpp
+++ b/source/Expression/IRInterpreter.cpp
@@ -7,16 +7,19 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Expression/IRInterpreter.h"
+#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
-#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/DiagnosticManager.h"
+#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRMemoryMap.h"
-#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Host/Endian.h"
#include "lldb/Target/ABI.h"
@@ -33,6 +36,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
@@ -100,8 +104,9 @@ public:
ValueMap m_values;
DataLayout &m_target_data;
- lldb_private::IRMemoryMap &m_memory_map;
+ lldb_private::IRExecutionUnit &m_execution_unit;
const BasicBlock *m_bb;
+ const BasicBlock *m_prev_bb;
BasicBlock::const_iterator m_ii;
BasicBlock::const_iterator m_ie;
@@ -113,11 +118,13 @@ public:
size_t m_addr_byte_size;
InterpreterStackFrame (DataLayout &target_data,
- lldb_private::IRMemoryMap &memory_map,
+ lldb_private::IRExecutionUnit &execution_unit,
lldb::addr_t stack_frame_bottom,
lldb::addr_t stack_frame_top) :
m_target_data (target_data),
- m_memory_map (memory_map)
+ m_execution_unit (execution_unit),
+ m_bb (nullptr),
+ m_prev_bb (nullptr)
{
m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle : lldb::eByteOrderBig);
m_addr_byte_size = (target_data.getPointerSize(0));
@@ -133,6 +140,7 @@ public:
void Jump (const BasicBlock *bb)
{
+ m_prev_bb = m_bb;
m_bb = bb;
m_ii = m_bb->begin();
m_ie = m_bb->end();
@@ -202,7 +210,7 @@ public:
lldb_private::DataExtractor value_extractor;
lldb_private::Error extract_error;
- m_memory_map.GetMemoryData(value_extractor, process_address, value_size, extract_error);
+ m_execution_unit.GetMemoryData(value_extractor, process_address, value_size, extract_error);
if (!extract_error.Success())
return false;
@@ -227,7 +235,7 @@ public:
lldb_private::Scalar cast_scalar;
- if (!AssignToMatchType(cast_scalar, scalar.GetRawBits64(0), value->getType()))
+ if (!AssignToMatchType(cast_scalar, scalar.ULongLong(), value->getType()))
return false;
size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType());
@@ -241,7 +249,7 @@ public:
lldb_private::Error write_error;
- m_memory_map.WriteMemory(process_address, buf.GetBytes(), buf.GetByteSize(), write_error);
+ m_execution_unit.WriteMemory(process_address, buf.GetBytes(), buf.GetByteSize(), write_error);
return write_error.Success();
}
@@ -252,6 +260,17 @@ public:
{
default:
break;
+ case Value::FunctionVal:
+ if (const Function *constant_func = dyn_cast<Function>(constant))
+ {
+ lldb_private::ConstString name(constant_func->getName());
+ lldb::addr_t addr = m_execution_unit.FindSymbol(name);
+ if (addr == LLDB_INVALID_ADDRESS)
+ return false;
+ value = APInt(m_target_data.getPointerSizeInBits(), addr);
+ return true;
+ }
+ break;
case Value::ConstantIntVal:
if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant))
{
@@ -297,7 +316,8 @@ public:
SmallVector <Value *, 8> indices (op_cursor, op_end);
- uint64_t offset = m_target_data.getIndexedOffset(base->getType(), indices);
+ Type *src_elem_ty = cast<GEPOperator>(constant_expr)->getSourceElementType();
+ uint64_t offset = m_target_data.getIndexedOffsetInType(src_elem_ty, indices);
const bool is_signed = true;
value += APInt(value.getBitWidth(), offset, is_signed);
@@ -327,12 +347,12 @@ public:
lldb_private::Error write_error;
- m_memory_map.WritePointerToMemory(data_address, address, write_error);
+ m_execution_unit.WritePointerToMemory(data_address, address, write_error);
if (!write_error.Success())
{
lldb_private::Error free_error;
- m_memory_map.Free(data_address, free_error);
+ m_execution_unit.Free(data_address, free_error);
return false;
}
@@ -357,19 +377,18 @@ public:
if (!ResolveConstantValue(resolved_value, constant))
return false;
- lldb_private::StreamString buffer (lldb_private::Stream::eBinary,
- m_memory_map.GetAddressByteSize(),
- m_memory_map.GetByteOrder());
-
size_t constant_size = m_target_data.getTypeStoreSize(constant->getType());
+ lldb_private::DataBufferHeap buf(constant_size, 0);
- const uint64_t *raw_data = resolved_value.getRawData();
+ lldb_private::Error get_data_error;
- buffer.PutRawBytes(raw_data, constant_size, lldb_private::endian::InlHostByteOrder());
+ lldb_private::Scalar resolved_scalar(resolved_value.zextOrTrunc(llvm::NextPowerOf2(constant_size) * 8));
+ if (!resolved_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(), m_byte_order, get_data_error))
+ return false;
lldb_private::Error write_error;
- m_memory_map.WriteMemory(process_address, (const uint8_t*)buffer.GetData(), constant_size, write_error);
+ m_execution_unit.WriteMemory(process_address, buf.GetBytes(), buf.GetByteSize(), write_error);
return write_error.Success();
}
@@ -408,7 +427,7 @@ public:
lldb_private::Error read_error;
- m_memory_map.ReadMemory(buf.GetBytes(), addr, length, read_error);
+ m_execution_unit.ReadMemory(buf.GetBytes(), addr, length, read_error);
if (!read_error.Success())
return std::string("<couldn't read data>");
@@ -442,7 +461,7 @@ public:
if (!ResolveConstant (data_address, constant))
{
lldb_private::Error free_error;
- m_memory_map.Free(data_address, free_error);
+ m_execution_unit.Free(data_address, free_error);
return LLDB_INVALID_ADDRESS;
}
}
@@ -462,6 +481,47 @@ static const char *memory_write_error = "Interpreter couldn't writ
static const char *memory_read_error = "Interpreter couldn't read from memory";
static const char *infinite_loop_error = "Interpreter ran for too many cycles";
//static const char *bad_result_error = "Result of expression is in bad memory";
+static const char *too_many_functions_error = "Interpreter doesn't handle modules with multiple function bodies.";
+
+static bool
+CanResolveConstant (llvm::Constant *constant)
+{
+ switch (constant->getValueID())
+ {
+ default:
+ return false;
+ case Value::ConstantIntVal:
+ case Value::ConstantFPVal:
+ case Value::FunctionVal:
+ return true;
+ case Value::ConstantExprVal:
+ if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
+ {
+ switch (constant_expr->getOpcode())
+ {
+ default:
+ return false;
+ case Instruction::IntToPtr:
+ case Instruction::PtrToInt:
+ case Instruction::BitCast:
+ return CanResolveConstant(constant_expr->getOperand(0));
+ case Instruction::GetElementPtr:
+ {
+ ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
+ Constant *base = dyn_cast<Constant>(*op_cursor);
+ if (!base)
+ return false;
+
+ return CanResolveConstant(base);
+ }
+ }
+ } else {
+ return false;
+ }
+ case Value::ConstantPointerNullVal:
+ return true;
+ }
+}
bool
IRInterpreter::CanInterpret (llvm::Module &module,
@@ -480,7 +540,13 @@ IRInterpreter::CanInterpret (llvm::Module &module,
if (fi->begin() != fi->end())
{
if (saw_function_with_body)
+ {
+ if (log)
+ log->Printf("More than one function in the module has a body");
+ error.SetErrorToGenericError();
+ error.SetErrorString(too_many_functions_error);
return false;
+ }
saw_function_with_body = true;
}
}
@@ -507,6 +573,7 @@ IRInterpreter::CanInterpret (llvm::Module &module,
case Instruction::Alloca:
case Instruction::BitCast:
case Instruction::Br:
+ case Instruction::PHI:
break;
case Instruction::Call:
{
@@ -609,18 +676,30 @@ IRInterpreter::CanInterpret (llvm::Module &module,
return false;
}
}
+
+ if (Constant *constant = llvm::dyn_cast<Constant>(operand))
+ {
+ if (!CanResolveConstant(constant))
+ {
+ if (log)
+ log->Printf("Unsupported constant: %s", PrintValue(constant).c_str());
+ error.SetErrorString(unsupported_operand_error);
+ return false;
+ }
+ }
}
}
}
- return true;}
+ return true;
+}
bool
IRInterpreter::Interpret (llvm::Module &module,
llvm::Function &function,
llvm::ArrayRef<lldb::addr_t> args,
- lldb_private::IRMemoryMap &memory_map,
+ lldb_private::IRExecutionUnit &execution_unit,
lldb_private::Error &error,
lldb::addr_t stack_frame_bottom,
lldb::addr_t stack_frame_top,
@@ -642,7 +721,7 @@ IRInterpreter::Interpret (llvm::Module &module,
DataLayout data_layout(&module);
- InterpreterStackFrame frame(data_layout, memory_map, stack_frame_bottom, stack_frame_top);
+ InterpreterStackFrame frame(data_layout, execution_unit, stack_frame_bottom, stack_frame_top);
if (frame.m_frame_process_address == LLDB_INVALID_ADDRESS)
{
@@ -752,7 +831,9 @@ IRInterpreter::Interpret (llvm::Module &module,
result = L / R;
break;
case Instruction::UDiv:
- result = L.GetRawBits64(0) / R.GetRawBits64(1);
+ L.MakeUnsigned();
+ R.MakeUnsigned();
+ result = L / R;
break;
case Instruction::SRem:
L.MakeSigned();
@@ -760,7 +841,9 @@ IRInterpreter::Interpret (llvm::Module &module,
result = L % R;
break;
case Instruction::URem:
- result = L.GetRawBits64(0) % R.GetRawBits64(1);
+ L.MakeUnsigned();
+ R.MakeUnsigned();
+ result = L % R;
break;
case Instruction::Shl:
result = L << R;
@@ -848,7 +931,7 @@ IRInterpreter::Interpret (llvm::Module &module,
lldb_private::Error write_error;
- memory_map.WritePointerToMemory(P, R, write_error);
+ execution_unit.WritePointerToMemory(P, R, write_error);
if (!write_error.Success())
{
@@ -857,8 +940,8 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorToGenericError();
error.SetErrorString(memory_write_error);
lldb_private::Error free_error;
- memory_map.Free(P, free_error);
- memory_map.Free(R, free_error);
+ execution_unit.Free(P, free_error);
+ execution_unit.Free(R, free_error);
return false;
}
@@ -963,7 +1046,7 @@ IRInterpreter::Interpret (llvm::Module &module,
return false;
}
- if (C.GetRawBits64(0))
+ if (!C.IsZero())
frame.Jump(br_inst->getSuccessor(0));
else
frame.Jump(br_inst->getSuccessor(1));
@@ -985,6 +1068,46 @@ IRInterpreter::Interpret (llvm::Module &module,
}
}
continue;
+ case Instruction::PHI:
+ {
+ const PHINode *phi_inst = dyn_cast<PHINode>(inst);
+
+ if (!phi_inst)
+ {
+ if (log)
+ log->Printf("getOpcode() returns PHI, but instruction is not a PHINode");
+ error.SetErrorToGenericError();
+ error.SetErrorString(interpreter_internal_error);
+ return false;
+ }
+ if (!frame.m_prev_bb)
+ {
+ if (log)
+ log->Printf("Encountered PHI node without having jumped from another basic block");
+ error.SetErrorToGenericError();
+ error.SetErrorString(interpreter_internal_error);
+ return false;
+ }
+
+ Value* value = phi_inst->getIncomingValueForBlock(frame.m_prev_bb);
+ lldb_private::Scalar result;
+ if (!frame.EvaluateValue(result, value, module))
+ {
+ if (log)
+ log->Printf("Couldn't evaluate %s", PrintValue(value).c_str());
+ error.SetErrorToGenericError();
+ error.SetErrorString(bad_value_error);
+ return false;
+ }
+ frame.AssignValue(inst, result, module);
+
+ if (log)
+ {
+ log->Printf("Interpreted a %s", inst->getOpcodeName());
+ log->Printf(" Incoming value : %s", frame.SummarizeValue(value).c_str());
+ }
+ }
+ break;
case Instruction::GetElementPtr:
{
const GetElementPtrInst *gep_inst = dyn_cast<GetElementPtrInst>(inst);
@@ -999,7 +1122,7 @@ IRInterpreter::Interpret (llvm::Module &module,
}
const Value *pointer_operand = gep_inst->getPointerOperand();
- Type *pointer_type = pointer_operand->getType();
+ Type *src_elem_ty = gep_inst->getSourceElementType();
lldb_private::Scalar P;
@@ -1048,7 +1171,7 @@ IRInterpreter::Interpret (llvm::Module &module,
const_indices.push_back(constant_index);
}
- uint64_t offset = data_layout.getIndexedOffset(pointer_type, const_indices);
+ uint64_t offset = data_layout.getIndexedOffsetInType(src_elem_ty, const_indices);
lldb_private::Scalar Poffset = P + offset;
@@ -1114,16 +1237,24 @@ IRInterpreter::Interpret (llvm::Module &module,
result = (L != R);
break;
case CmpInst::ICMP_UGT:
- result = (L.GetRawBits64(0) > R.GetRawBits64(0));
+ L.MakeUnsigned();
+ R.MakeUnsigned();
+ result = (L > R);
break;
case CmpInst::ICMP_UGE:
- result = (L.GetRawBits64(0) >= R.GetRawBits64(0));
+ L.MakeUnsigned();
+ R.MakeUnsigned();
+ result = (L >= R);
break;
case CmpInst::ICMP_ULT:
- result = (L.GetRawBits64(0) < R.GetRawBits64(0));
+ L.MakeUnsigned();
+ R.MakeUnsigned();
+ result = (L < R);
break;
case CmpInst::ICMP_ULE:
- result = (L.GetRawBits64(0) <= R.GetRawBits64(0));
+ L.MakeUnsigned();
+ R.MakeUnsigned();
+ result = (L <= R);
break;
case CmpInst::ICMP_SGT:
L.MakeSigned();
@@ -1322,7 +1453,7 @@ IRInterpreter::Interpret (llvm::Module &module,
lldb::addr_t R;
lldb_private::Error read_error;
- memory_map.ReadPointerFromMemory(&R, P, read_error);
+ execution_unit.ReadPointerFromMemory(&R, P, read_error);
if (!read_error.Success())
{
@@ -1337,7 +1468,7 @@ IRInterpreter::Interpret (llvm::Module &module,
lldb_private::DataBufferHeap buffer(target_size, 0);
read_error.Clear();
- memory_map.ReadMemory(buffer.GetBytes(), R, buffer.GetByteSize(), read_error);
+ execution_unit.ReadMemory(buffer.GetBytes(), R, buffer.GetByteSize(), read_error);
if (!read_error.Success())
{
if (log)
@@ -1348,7 +1479,7 @@ IRInterpreter::Interpret (llvm::Module &module,
}
lldb_private::Error write_error;
- memory_map.WriteMemory(D, buffer.GetBytes(), buffer.GetByteSize(), write_error);
+ execution_unit.WriteMemory(D, buffer.GetBytes(), buffer.GetByteSize(), write_error);
if (!write_error.Success())
{
if (log)
@@ -1422,7 +1553,7 @@ IRInterpreter::Interpret (llvm::Module &module,
lldb::addr_t R;
lldb_private::Error read_error;
- memory_map.ReadPointerFromMemory(&R, P, read_error);
+ execution_unit.ReadPointerFromMemory(&R, P, read_error);
if (!read_error.Success())
{
@@ -1437,7 +1568,7 @@ IRInterpreter::Interpret (llvm::Module &module,
lldb_private::DataBufferHeap buffer(target_size, 0);
read_error.Clear();
- memory_map.ReadMemory(buffer.GetBytes(), D, buffer.GetByteSize(), read_error);
+ execution_unit.ReadMemory(buffer.GetBytes(), D, buffer.GetByteSize(), read_error);
if (!read_error.Success())
{
if (log)
@@ -1448,7 +1579,7 @@ IRInterpreter::Interpret (llvm::Module &module,
}
lldb_private::Error write_error;
- memory_map.WriteMemory(R, buffer.GetBytes(), buffer.GetByteSize(), write_error);
+ execution_unit.WriteMemory(R, buffer.GetBytes(), buffer.GetByteSize(), write_error);
if (!write_error.Success())
{
if (log)
@@ -1530,7 +1661,7 @@ IRInterpreter::Interpret (llvm::Module &module,
}
lldb_private::Address funcAddr(I.ULongLong(LLDB_INVALID_ADDRESS));
- lldb_private::StreamString error_stream;
+ lldb_private::DiagnosticManager diagnostics;
lldb_private::EvaluateExpressionOptions options;
// We generally receive a function pointer which we must dereference
@@ -1597,14 +1728,14 @@ IRInterpreter::Interpret (llvm::Module &module,
lldb::addr_t addr = tmp_op.ULongLong();
size_t dataSize = 0;
- if (memory_map.GetAllocSize(addr, dataSize))
+ if (execution_unit.GetAllocSize(addr, dataSize))
{
// Create the required buffer
rawArgs[i].size = dataSize;
rawArgs[i].data_ap.reset(new uint8_t[dataSize + 1]);
// Read string from host memory
- memory_map.ReadMemory(rawArgs[i].data_ap.get(), addr, dataSize, error);
+ execution_unit.ReadMemory(rawArgs[i].data_ap.get(), addr, dataSize, error);
if (error.Fail())
{
assert(!"we have failed to read the string from memory");
@@ -1635,31 +1766,24 @@ IRInterpreter::Interpret (llvm::Module &module,
llvm::ArrayRef<lldb_private::ABI::CallArgument> args(rawArgs, numArgs);
// Setup a thread plan to call the target function
- lldb::ThreadPlanSP call_plan_sp
- (
- new lldb_private::ThreadPlanCallFunctionUsingABI
- (
- exe_ctx.GetThreadRef(),
- funcAddr,
- *prototype,
- *returnType,
- args,
- options
- )
- );
+ lldb::ThreadPlanSP call_plan_sp(new lldb_private::ThreadPlanCallFunctionUsingABI(
+ exe_ctx.GetThreadRef(), funcAddr, *prototype, *returnType, args, options));
// Check if the plan is valid
- if (!call_plan_sp || !call_plan_sp->ValidatePlan(&error_stream))
+ lldb_private::StreamString ss;
+ if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss))
{
error.SetErrorToGenericError();
- error.SetErrorStringWithFormat("unable to make ThreadPlanCallFunctionUsingABI for 0x%llx", I.ULongLong());
+ error.SetErrorStringWithFormat("unable to make ThreadPlanCallFunctionUsingABI for 0x%llx",
+ I.ULongLong());
return false;
}
exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
// Execute the actual function call thread plan
- lldb::ExpressionResults res = exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options, error_stream);
+ lldb::ExpressionResults res =
+ exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
// Check that the thread plan completed successfully
if (res != lldb::ExpressionResults::eExpressionCompleted)
diff --git a/source/Expression/IRMemoryMap.cpp b/source/Expression/IRMemoryMap.cpp
index e96bddde7cbb..aa165722c437 100644
--- a/source/Expression/IRMemoryMap.cpp
+++ b/source/Expression/IRMemoryMap.cpp
@@ -13,8 +13,10 @@
#include "lldb/Core/Log.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Expression/IRMemoryMap.h"
+#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/LLDBAssert.h"
using namespace lldb_private;
@@ -47,37 +49,136 @@ IRMemoryMap::~IRMemoryMap ()
}
lldb::addr_t
-IRMemoryMap::FindSpace (size_t size, bool zero_memory)
+IRMemoryMap::FindSpace (size_t size)
{
+ // The FindSpace algorithm's job is to find a region of memory that the
+ // underlying process is unlikely to be using.
+ //
+ // The memory returned by this function will never be written to. The only
+ // point is that it should not shadow process memory if possible, so that
+ // expressions processing real values from the process do not use the
+ // wrong data.
+ //
+ // If the process can in fact allocate memory (CanJIT() lets us know this)
+ // then this can be accomplished just be allocating memory in the inferior.
+ // Then no guessing is required.
+
lldb::TargetSP target_sp = m_target_wp.lock();
lldb::ProcessSP process_sp = m_process_wp.lock();
+
+ const bool process_is_alive = process_sp && process_sp->IsAlive();
lldb::addr_t ret = LLDB_INVALID_ADDRESS;
if (size == 0)
return ret;
- if (process_sp && process_sp->CanJIT() && process_sp->IsAlive())
+ if (process_is_alive && process_sp->CanJIT())
{
Error alloc_error;
- if (!zero_memory)
- ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error);
- else
- ret = process_sp->CallocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error);
+ ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error);
if (!alloc_error.Success())
return LLDB_INVALID_ADDRESS;
else
return ret;
}
+
+ // At this point we know that we need to hunt.
+ //
+ // First, go to the end of the existing allocations we've made if there are
+ // any allocations. Otherwise start at the beginning of memory.
- ret = 0;
- if (!m_allocations.empty())
+ if (m_allocations.empty())
+ {
+ ret = 0x0;
+ }
+ else
+ {
+ auto back = m_allocations.rbegin();
+ lldb::addr_t addr = back->first;
+ size_t alloc_size = back->second.m_size;
+ ret = llvm::alignTo(addr+alloc_size, 4096);
+ }
+
+ // Now, if it's possible to use the GetMemoryRegionInfo API to detect mapped
+ // regions, walk forward through memory until a region is found that
+ // has adequate space for our allocation.
+ if (process_is_alive)
+ {
+ const uint64_t end_of_memory = process_sp->GetAddressByteSize() == 8 ?
+ 0xffffffffffffffffull : 0xffffffffull;
+
+ lldbassert(process_sp->GetAddressByteSize() == 4 || end_of_memory != 0xffffffffull);
+
+ MemoryRegionInfo region_info;
+ Error err = process_sp->GetMemoryRegionInfo(ret, region_info);
+ if (err.Success())
+ {
+ while (true)
+ {
+ if (region_info.GetReadable() != MemoryRegionInfo::OptionalBool::eNo ||
+ region_info.GetWritable() != MemoryRegionInfo::OptionalBool::eNo ||
+ region_info.GetExecutable() != MemoryRegionInfo::OptionalBool::eNo)
+ {
+ if (region_info.GetRange().GetRangeEnd() - 1 >= end_of_memory)
+ {
+ ret = LLDB_INVALID_ADDRESS;
+ break;
+ }
+ else
+ {
+ ret = region_info.GetRange().GetRangeEnd();
+ }
+ }
+ else if (ret + size < region_info.GetRange().GetRangeEnd())
+ {
+ return ret;
+ }
+ else
+ {
+ // ret stays the same. We just need to walk a bit further.
+ }
+
+ err = process_sp->GetMemoryRegionInfo(region_info.GetRange().GetRangeEnd(), region_info);
+ if (err.Fail())
+ {
+ lldbassert(!"GetMemoryRegionInfo() succeeded, then failed");
+ ret = LLDB_INVALID_ADDRESS;
+ break;
+ }
+ }
+ }
+ }
+
+ // We've tried our algorithm, and it didn't work. Now we have to reset back
+ // to the end of the allocations we've already reported, or use a 'sensible'
+ // default if this is our first allocation.
+
+ if (m_allocations.empty())
+ {
+ uint32_t address_byte_size = GetAddressByteSize();
+ if (address_byte_size != UINT32_MAX)
+ {
+ switch (address_byte_size)
+ {
+ case 8:
+ ret = 0xffffffff00000000ull;
+ break;
+ case 4:
+ ret = 0xee000000ull;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else
{
auto back = m_allocations.rbegin();
lldb::addr_t addr = back->first;
size_t alloc_size = back->second.m_size;
- ret = llvm::RoundUpToAlignment(addr+alloc_size, 4096);
+ ret = llvm::alignTo(addr+alloc_size, 4096);
}
return ret;
@@ -329,6 +430,13 @@ IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, Alloc
alignment,
policy);
+ if (zero_memory)
+ {
+ Error write_error;
+ std::vector<uint8_t> zero_buf(size, 0);
+ WriteMemory(aligned_address, zero_buf.data(), size, write_error);
+ }
+
if (log)
{
const char * policy_string;
@@ -784,6 +892,7 @@ IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_addre
return;
}
}
+ break;
case eAllocationPolicyHostOnly:
if (!allocation.m_data.GetByteSize())
{
diff --git a/source/Expression/LLVMUserExpression.cpp b/source/Expression/LLVMUserExpression.cpp
index eff0a2dc30d6..0b969806280e 100644
--- a/source/Expression/LLVMUserExpression.cpp
+++ b/source/Expression/LLVMUserExpression.cpp
@@ -18,6 +18,7 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionSourceCode.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
@@ -25,11 +26,11 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
-#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
@@ -58,7 +59,6 @@ LLVMUserExpression::LLVMUserExpression(ExecutionContextScope &exe_scope,
m_in_objectivec_method(false),
m_in_static_method(false),
m_needs_object_ptr(false),
- m_const_object(false),
m_target(NULL),
m_can_interpret(false),
m_materialized_address(LLDB_INVALID_ADDRESS)
@@ -76,8 +76,9 @@ LLVMUserExpression::~LLVMUserExpression()
}
lldb::ExpressionResults
-LLVMUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options,
- lldb::UserExpressionSP &shared_ptr_to_me, lldb::ExpressionVariableSP &result)
+LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me,
+ lldb::ExpressionVariableSP &result)
{
// The expression log is quite verbose, and if you're just tracking the execution of the
// expression, it's quite convenient to have these logs come out with the STEP log as well.
@@ -87,9 +88,10 @@ LLVMUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, con
{
lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
- if (!PrepareToExecuteJITExpression(error_stream, exe_ctx, struct_address))
+ if (!PrepareToExecuteJITExpression(diagnostic_manager, exe_ctx, struct_address))
{
- error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
return lldb::eExpressionSetupError;
}
@@ -103,7 +105,7 @@ LLVMUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, con
if (!module || !function)
{
- error_stream.Printf("Supposed to interpret, but nothing is there");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "supposed to interpret, but nothing is there");
return lldb::eExpressionSetupError;
}
@@ -111,9 +113,10 @@ LLVMUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, con
std::vector<lldb::addr_t> args;
- if (!AddArguments(exe_ctx, args, struct_address, error_stream))
+ if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager))
{
- error_stream.Printf("Errored out in %s, couldn't AddArguments", __FUNCTION__);
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "errored out in %s, couldn't AddArguments",
+ __FUNCTION__);
return lldb::eExpressionSetupError;
}
@@ -121,11 +124,12 @@ LLVMUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, con
function_stack_top = m_stack_frame_top;
IRInterpreter::Interpret(*module, *function, args, *m_execution_unit_sp.get(), interpreter_error,
- function_stack_bottom, function_stack_top, exe_ctx);
+ function_stack_bottom, function_stack_top, exe_ctx);
if (!interpreter_error.Success())
{
- error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "supposed to interpret, but failed: %s",
+ interpreter_error.AsCString());
return lldb::eExpressionDiscarded;
}
}
@@ -133,7 +137,7 @@ LLVMUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, con
{
if (!exe_ctx.HasThreadScope())
{
- error_stream.Printf("UserExpression::Execute called with no thread selected.");
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "%s called with no thread selected", __FUNCTION__);
return lldb::eExpressionSetupError;
}
@@ -141,17 +145,22 @@ LLVMUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, con
std::vector<lldb::addr_t> args;
- if (!AddArguments(exe_ctx, args, struct_address, error_stream))
+ if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager))
{
- error_stream.Printf("Errored out in %s, couldn't AddArguments", __FUNCTION__);
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "errored out in %s, couldn't AddArguments",
+ __FUNCTION__);
return lldb::eExpressionSetupError;
}
lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression(exe_ctx.GetThreadRef(), wrapper_address,
args, options, shared_ptr_to_me));
- if (!call_plan_sp || !call_plan_sp->ValidatePlan(&error_stream))
+ StreamString ss;
+ if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss))
+ {
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, ss.GetData());
return lldb::eExpressionSetupError;
+ }
ThreadPlanCallUserExpression *user_expression_plan =
static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get());
@@ -168,7 +177,7 @@ LLVMUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, con
exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
lldb::ExpressionResults execution_result =
- exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options, error_stream);
+ exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostic_manager);
if (exe_ctx.GetProcessPtr())
exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
@@ -187,20 +196,21 @@ LLVMUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, con
error_desc = real_stop_info_sp->GetDescription();
}
if (error_desc)
- error_stream.Printf("Execution was interrupted, reason: %s.", error_desc);
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "Execution was interrupted, reason: %s.",
+ error_desc);
else
- error_stream.PutCString("Execution was interrupted.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "Execution was interrupted.");
if ((execution_result == lldb::eExpressionInterrupted && options.DoesUnwindOnError()) ||
(execution_result == lldb::eExpressionHitBreakpoint && options.DoesIgnoreBreakpoints()))
- error_stream.PutCString(
- "\nThe process has been returned to the state before expression evaluation.");
+ diagnostic_manager.AppendMessageToDiagnostic(
+ "The process has been returned to the state before expression evaluation.");
else
{
if (execution_result == lldb::eExpressionHitBreakpoint)
user_expression_plan->TransferExpressionOwnership();
- error_stream.PutCString(
- "\nThe process has been left at the point where it was interrupted, "
+ diagnostic_manager.AppendMessageToDiagnostic(
+ "The process has been left at the point where it was interrupted, "
"use \"thread return -x\" to return to the state before expression evaluation.");
}
@@ -208,7 +218,8 @@ LLVMUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, con
}
else if (execution_result == lldb::eExpressionStoppedForDebug)
{
- error_stream.PutCString(
+ diagnostic_manager.PutCString(
+ eDiagnosticSeverityRemark,
"Execution was halted at the first instruction of the expression "
"function because \"debug\" was requested.\n"
"Use \"thread return -x\" to return to the state before expression evaluation.");
@@ -216,13 +227,13 @@ LLVMUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, con
}
else if (execution_result != lldb::eExpressionCompleted)
{
- error_stream.Printf("Couldn't execute function; result was %s\n",
- Process::ExecutionResultAsCString(execution_result));
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't execute function; result was %s",
+ Process::ExecutionResultAsCString(execution_result));
return execution_result;
}
}
- if (FinalizeJITExecution(error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
+ if (FinalizeJITExecution(diagnostic_manager, exe_ctx, result, function_stack_bottom, function_stack_top))
{
return lldb::eExpressionCompleted;
}
@@ -233,13 +244,14 @@ LLVMUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, con
}
else
{
- error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "Expression can't be run, because there is no JIT compiled function");
return lldb::eExpressionSetupError;
}
}
bool
-LLVMUserExpression::FinalizeJITExecution(Stream &error_stream, ExecutionContext &exe_ctx,
+LLVMUserExpression::FinalizeJITExecution(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
lldb::ExpressionVariableSP &result, lldb::addr_t function_stack_bottom,
lldb::addr_t function_stack_top)
{
@@ -250,7 +262,8 @@ LLVMUserExpression::FinalizeJITExecution(Stream &error_stream, ExecutionContext
if (!m_dematerializer_sp)
{
- error_stream.Printf("Couldn't apply expression side effects : no dematerializer is present");
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "Couldn't apply expression side effects : no dematerializer is present");
return false;
}
@@ -260,8 +273,8 @@ LLVMUserExpression::FinalizeJITExecution(Stream &error_stream, ExecutionContext
if (!dematerialize_error.Success())
{
- error_stream.Printf("Couldn't apply expression side effects : %s\n",
- dematerialize_error.AsCString("unknown error"));
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't apply expression side effects : %s",
+ dematerialize_error.AsCString("unknown error"));
return false;
}
@@ -276,7 +289,7 @@ LLVMUserExpression::FinalizeJITExecution(Stream &error_stream, ExecutionContext
}
bool
-LLVMUserExpression::PrepareToExecuteJITExpression(Stream &error_stream, ExecutionContext &exe_ctx,
+LLVMUserExpression::PrepareToExecuteJITExpression(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
lldb::addr_t &struct_address)
{
lldb::TargetSP target;
@@ -285,7 +298,8 @@ LLVMUserExpression::PrepareToExecuteJITExpression(Stream &error_stream, Executio
if (!LockAndCheckContext(exe_ctx, target, process, frame))
{
- error_stream.Printf("The context has changed before we could JIT the expression!\n");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "The context has changed before we could JIT the expression!");
return false;
}
@@ -309,7 +323,9 @@ LLVMUserExpression::PrepareToExecuteJITExpression(Stream &error_stream, Executio
if (!alloc_error.Success())
{
- error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "Couldn't allocate space for materialized struct: %s",
+ alloc_error.AsCString());
return false;
}
}
@@ -335,7 +351,8 @@ LLVMUserExpression::PrepareToExecuteJITExpression(Stream &error_stream, Executio
if (!alloc_error.Success())
{
- error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't allocate space for the stack frame: %s",
+ alloc_error.AsCString());
return false;
}
}
@@ -347,7 +364,8 @@ LLVMUserExpression::PrepareToExecuteJITExpression(Stream &error_stream, Executio
if (!materialize_error.Success())
{
- error_stream.Printf("Couldn't materialize: %s\n", materialize_error.AsCString());
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't materialize: %s",
+ materialize_error.AsCString());
return false;
}
}
diff --git a/source/Expression/Makefile b/source/Expression/Makefile
deleted file mode 100644
index 495f094d3900..000000000000
--- a/source/Expression/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Expression/Makefile --------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LIBRARYNAME := lldbExpression
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Expression/Materializer.cpp b/source/Expression/Materializer.cpp
index 8d68b4f79819..3575f5436d92 100644
--- a/source/Expression/Materializer.cpp
+++ b/source/Expression/Materializer.cpp
@@ -34,19 +34,19 @@ Materializer::AddStructMember (Entity &entity)
{
uint32_t size = entity.GetSize();
uint32_t alignment = entity.GetAlignment();
-
+
uint32_t ret;
-
+
if (m_current_offset == 0)
m_struct_alignment = alignment;
-
+
if (m_current_offset % alignment)
m_current_offset += (alignment - (m_current_offset % alignment));
-
+
ret = m_current_offset;
-
+
m_current_offset += size;
-
+
return ret;
}
@@ -54,15 +54,15 @@ void
Materializer::Entity::SetSizeAndAlignmentFromType (CompilerType &type)
{
m_size = type.GetByteSize(nullptr);
-
+
uint32_t bit_alignment = type.GetTypeBitAlign();
-
+
if (bit_alignment % 8)
{
bit_alignment += 8;
bit_alignment &= ~((uint32_t)0x111u);
}
-
+
m_alignment = bit_alignment / 8;
}
@@ -79,59 +79,59 @@ public:
m_size = 8;
m_alignment = 8;
}
-
+
void MakeAllocation (IRMemoryMap &map, Error &err)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
// Allocate a spare memory area to store the persistent variable's contents.
-
+
Error allocate_error;
const bool zero_memory = false;
-
+
lldb::addr_t mem = map.Malloc(m_persistent_variable_sp->GetByteSize(),
8,
lldb::ePermissionsReadable | lldb::ePermissionsWritable,
IRMemoryMap::eAllocationPolicyMirror,
zero_memory,
allocate_error);
-
+
if (!allocate_error.Success())
{
err.SetErrorStringWithFormat("couldn't allocate a memory area to store %s: %s", m_persistent_variable_sp->GetName().GetCString(), allocate_error.AsCString());
return;
}
-
+
if (log)
log->Printf("Allocated %s (0x%" PRIx64 ") successfully", m_persistent_variable_sp->GetName().GetCString(), mem);
-
+
// Put the location of the spare memory into the live data of the ValueObject.
-
+
m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope(),
m_persistent_variable_sp->GetCompilerType(),
m_persistent_variable_sp->GetName(),
mem,
eAddressTypeLoad,
map.GetAddressByteSize());
-
+
// Clear the flag if the variable will never be deallocated.
-
+
if (m_persistent_variable_sp->m_flags & ExpressionVariable::EVKeepInTarget)
{
Error leak_error;
map.Leak(mem, leak_error);
m_persistent_variable_sp->m_flags &= ~ExpressionVariable::EVNeedsAllocation;
}
-
+
// Write the contents of the variable to the area.
-
+
Error write_error;
-
+
map.WriteMemory (mem,
m_persistent_variable_sp->GetValueBytes(),
m_persistent_variable_sp->GetByteSize(),
write_error);
-
+
if (!write_error.Success())
{
err.SetErrorStringWithFormat ("couldn't write %s to the target: %s", m_persistent_variable_sp->GetName().AsCString(),
@@ -139,21 +139,21 @@ public:
return;
}
}
-
+
void DestroyAllocation (IRMemoryMap &map, Error &err)
{
Error deallocate_error;
-
+
map.Free((lldb::addr_t)m_persistent_variable_sp->m_live_sp->GetValue().GetScalar().ULongLong(), deallocate_error);
-
+
m_persistent_variable_sp->m_live_sp.reset();
-
+
if (!deallocate_error.Success())
{
err.SetErrorStringWithFormat ("couldn't deallocate memory for %s: %s", m_persistent_variable_sp->GetName().GetCString(), deallocate_error.AsCString());
}
}
-
+
void Materialize(lldb::StackFrameSP &frame_sp,
IRMemoryMap &map,
lldb::addr_t process_address,
@@ -162,7 +162,7 @@ public:
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
const lldb::addr_t load_addr = process_address + m_offset;
-
+
if (log)
{
log->Printf("EntityPersistentVariable::Materialize [address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]",
@@ -170,26 +170,26 @@ public:
m_persistent_variable_sp->GetName().AsCString(),
m_persistent_variable_sp->m_flags);
}
-
+
if (m_persistent_variable_sp->m_flags & ExpressionVariable::EVNeedsAllocation)
{
MakeAllocation(map, err);
m_persistent_variable_sp->m_flags |= ExpressionVariable::EVIsLLDBAllocated;
-
+
if (!err.Success())
return;
}
-
+
if ((m_persistent_variable_sp->m_flags & ExpressionVariable::EVIsProgramReference && m_persistent_variable_sp->m_live_sp) ||
m_persistent_variable_sp->m_flags & ExpressionVariable::EVIsLLDBAllocated)
{
Error write_error;
-
+
map.WriteScalarToMemory(load_addr,
m_persistent_variable_sp->m_live_sp->GetValue().GetScalar(),
map.GetAddressByteSize(),
write_error);
-
+
if (!write_error.Success())
{
err.SetErrorStringWithFormat("couldn't write the location of %s to memory: %s", m_persistent_variable_sp->GetName().AsCString(), write_error.AsCString());
@@ -201,7 +201,7 @@ public:
return;
}
}
-
+
void Dematerialize(lldb::StackFrameSP &frame_sp,
IRMemoryMap &map,
lldb::addr_t process_address,
@@ -210,7 +210,7 @@ public:
Error &err) override
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
const lldb::addr_t load_addr = process_address + m_offset;
if (log)
@@ -220,7 +220,7 @@ public:
m_persistent_variable_sp->GetName().AsCString(),
m_persistent_variable_sp->m_flags);
}
-
+
if (m_delegate)
{
m_delegate->DidDematerialize(m_persistent_variable_sp);
@@ -234,25 +234,25 @@ public:
{
// If the reference comes from the program, then the ClangExpressionVariable's
// live variable data hasn't been set up yet. Do this now.
-
+
lldb::addr_t location;
Error read_error;
-
+
map.ReadPointerFromMemory(&location, load_addr, read_error);
-
+
if (!read_error.Success())
{
err.SetErrorStringWithFormat("couldn't read the address of program-allocated variable %s: %s", m_persistent_variable_sp->GetName().GetCString(), read_error.AsCString());
return;
}
-
+
m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope (),
m_persistent_variable_sp.get()->GetCompilerType(),
m_persistent_variable_sp->GetName(),
location,
eAddressTypeLoad,
m_persistent_variable_sp->GetByteSize());
-
+
if (frame_top != LLDB_INVALID_ADDRESS &&
frame_bottom != LLDB_INVALID_ADDRESS &&
location >= frame_bottom &&
@@ -267,44 +267,44 @@ public:
m_persistent_variable_sp->m_flags &= ~ExpressionVariable::EVIsProgramReference;
}
}
-
+
lldb::addr_t mem = m_persistent_variable_sp->m_live_sp->GetValue().GetScalar().ULongLong();
-
+
if (!m_persistent_variable_sp->m_live_sp)
{
err.SetErrorStringWithFormat("couldn't find the memory area used to store %s", m_persistent_variable_sp->GetName().GetCString());
return;
}
-
+
if (m_persistent_variable_sp->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad)
{
err.SetErrorStringWithFormat("the address of the memory area for %s is in an incorrect format", m_persistent_variable_sp->GetName().GetCString());
return;
}
-
+
if (m_persistent_variable_sp->m_flags & ExpressionVariable::EVNeedsFreezeDry ||
m_persistent_variable_sp->m_flags & ExpressionVariable::EVKeepInTarget)
- {
+ {
if (log)
log->Printf("Dematerializing %s from 0x%" PRIx64 " (size = %llu)", m_persistent_variable_sp->GetName().GetCString(), (uint64_t)mem, (unsigned long long)m_persistent_variable_sp->GetByteSize());
-
+
// Read the contents of the spare memory area
-
+
m_persistent_variable_sp->ValueUpdated ();
-
+
Error read_error;
-
+
map.ReadMemory(m_persistent_variable_sp->GetValueBytes(),
mem,
m_persistent_variable_sp->GetByteSize(),
read_error);
-
+
if (!read_error.Success())
{
err.SetErrorStringWithFormat ("couldn't read the contents of %s from memory: %s", m_persistent_variable_sp->GetName().GetCString(), read_error.AsCString());
return;
}
-
+
m_persistent_variable_sp->m_flags &= ~ExpressionVariable::EVNeedsFreezeDry;
}
}
@@ -313,13 +313,13 @@ public:
err.SetErrorStringWithFormat("no dematerialization happened for persistent variable %s", m_persistent_variable_sp->GetName().AsCString());
return;
}
-
+
lldb::ProcessSP process_sp = map.GetBestExecutionContextScope()->CalculateProcess();
if (!process_sp ||
!process_sp->CanJIT())
{
// Allocations are not persistent so persistent variables cannot stay materialized.
-
+
m_persistent_variable_sp->m_flags |= ExpressionVariable::EVNeedsAllocation;
DestroyAllocation(map, err);
@@ -334,24 +334,24 @@ public:
return;
}
}
-
+
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
{
StreamString dump_stream;
-
+
Error err;
-
+
const lldb::addr_t load_addr = process_address + m_offset;
dump_stream.Printf("0x%" PRIx64 ": EntityPersistentVariable (%s)\n", load_addr, m_persistent_variable_sp->GetName().AsCString());
-
+
{
dump_stream.Printf("Pointer:\n");
-
+
DataBufferHeap data (m_size, 0);
-
+
map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
-
+
if (!err.Success())
{
dump_stream.Printf(" <could not be read>\n");
@@ -359,20 +359,20 @@ public:
else
{
DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
-
+
extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
-
+
dump_stream.PutChar('\n');
}
}
-
+
{
dump_stream.Printf("Target:\n");
-
+
lldb::addr_t target_address;
-
+
map.ReadPointerFromMemory (&target_address, load_addr, err);
-
+
if (!err.Success())
{
dump_stream.Printf(" <could not be read>\n");
@@ -380,9 +380,9 @@ public:
else
{
DataBufferHeap data (m_persistent_variable_sp->GetByteSize(), 0);
-
+
map.ReadMemory(data.GetBytes(), target_address, m_persistent_variable_sp->GetByteSize(), err);
-
+
if (!err.Success())
{
dump_stream.Printf(" <could not be read>\n");
@@ -390,17 +390,17 @@ public:
else
{
DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
-
+
extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, target_address);
-
+
dump_stream.PutChar('\n');
}
}
}
-
+
log->PutCString(dump_stream.GetData());
}
-
+
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
{
}
@@ -437,14 +437,14 @@ public:
m_alignment = 8;
m_is_reference = m_variable_sp->GetType()->GetForwardCompilerType ().IsReferenceType();
}
-
+
void Materialize(lldb::StackFrameSP &frame_sp,
IRMemoryMap &map,
lldb::addr_t process_address,
Error &err) override
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
const lldb::addr_t load_addr = process_address + m_offset;
if (log)
{
@@ -452,46 +452,46 @@ public:
(uint64_t)load_addr,
m_variable_sp->GetName().AsCString());
}
-
+
ExecutionContextScope *scope = frame_sp.get();
-
+
if (!scope)
scope = map.GetBestExecutionContextScope();
-
+
lldb::ValueObjectSP valobj_sp = ValueObjectVariable::Create(scope, m_variable_sp);
-
+
if (!valobj_sp)
{
err.SetErrorStringWithFormat("couldn't get a value object for variable %s", m_variable_sp->GetName().AsCString());
return;
}
-
+
Error valobj_error = valobj_sp->GetError();
-
+
if (valobj_error.Fail())
{
err.SetErrorStringWithFormat("couldn't get the value of variable %s: %s", m_variable_sp->GetName().AsCString(), valobj_error.AsCString());
return;
}
-
+
if (m_is_reference)
{
DataExtractor valobj_extractor;
Error extract_error;
valobj_sp->GetData(valobj_extractor, extract_error);
-
+
if (!extract_error.Success())
{
err.SetErrorStringWithFormat("couldn't read contents of reference variable %s: %s", m_variable_sp->GetName().AsCString(), extract_error.AsCString());
return;
}
-
+
lldb::offset_t offset = 0;
lldb::addr_t reference_addr = valobj_extractor.GetAddress(&offset);
-
+
Error write_error;
map.WritePointerToMemory(load_addr, reference_addr, write_error);
-
+
if (!write_error.Success())
{
err.SetErrorStringWithFormat("couldn't write the contents of reference variable %s to memory: %s", m_variable_sp->GetName().AsCString(), write_error.AsCString());
@@ -507,7 +507,7 @@ public:
{
Error write_error;
map.WritePointerToMemory(load_addr, addr_of_valobj, write_error);
-
+
if (!write_error.Success())
{
err.SetErrorStringWithFormat("couldn't write the address of variable %s to memory: %s", m_variable_sp->GetName().AsCString(), write_error.AsCString());
@@ -524,14 +524,14 @@ public:
err.SetErrorStringWithFormat("couldn't get the value of %s: %s", m_variable_sp->GetName().AsCString(), extract_error.AsCString());
return;
}
-
+
if (m_temporary_allocation != LLDB_INVALID_ADDRESS)
{
err.SetErrorStringWithFormat("trying to create a temporary region for %s but one exists", m_variable_sp->GetName().AsCString());
return;
}
-
- if (data.GetByteSize() != m_variable_sp->GetType()->GetByteSize())
+
+ if (data.GetByteSize() < m_variable_sp->GetType()->GetByteSize())
{
if (data.GetByteSize() == 0 && m_variable_sp->LocationExpression().IsValid() == false)
{
@@ -539,20 +539,20 @@ public:
}
else
{
- err.SetErrorStringWithFormat("size of variable %s (%" PRIu64 ") disagrees with the ValueObject's size (%" PRIu64 ")",
+ err.SetErrorStringWithFormat("size of variable %s (%" PRIu64 ") is larger than the ValueObject's size (%" PRIu64 ")",
m_variable_sp->GetName().AsCString(),
m_variable_sp->GetType()->GetByteSize(),
data.GetByteSize());
}
return;
}
-
+
size_t bit_align = m_variable_sp->GetType()->GetLayoutCompilerType ().GetTypeBitAlign();
size_t byte_align = (bit_align + 7) / 8;
-
+
if (!byte_align)
byte_align = 1;
-
+
Error alloc_error;
const bool zero_memory = false;
@@ -562,31 +562,31 @@ public:
IRMemoryMap::eAllocationPolicyMirror,
zero_memory,
alloc_error);
-
+
m_temporary_allocation_size = data.GetByteSize();
-
+
m_original_data.reset(new DataBufferHeap(data.GetDataStart(), data.GetByteSize()));
-
+
if (!alloc_error.Success())
{
err.SetErrorStringWithFormat("couldn't allocate a temporary region for %s: %s", m_variable_sp->GetName().AsCString(), alloc_error.AsCString());
return;
}
-
+
Error write_error;
-
+
map.WriteMemory(m_temporary_allocation, data.GetDataStart(), data.GetByteSize(), write_error);
-
+
if (!write_error.Success())
{
err.SetErrorStringWithFormat("couldn't write to the temporary region for %s: %s", m_variable_sp->GetName().AsCString(), write_error.AsCString());
return;
}
-
+
Error pointer_write_error;
-
+
map.WritePointerToMemory(load_addr, m_temporary_allocation, pointer_write_error);
-
+
if (!pointer_write_error.Success())
{
err.SetErrorStringWithFormat("couldn't write the address of the temporary region for %s: %s", m_variable_sp->GetName().AsCString(), pointer_write_error.AsCString());
@@ -594,7 +594,7 @@ public:
}
}
}
-
+
void Dematerialize(lldb::StackFrameSP &frame_sp,
IRMemoryMap &map,
lldb::addr_t process_address,
@@ -611,36 +611,36 @@ public:
(uint64_t)load_addr,
m_variable_sp->GetName().AsCString());
}
-
+
if (m_temporary_allocation != LLDB_INVALID_ADDRESS)
{
ExecutionContextScope *scope = frame_sp.get();
-
+
if (!scope)
scope = map.GetBestExecutionContextScope();
-
+
lldb::ValueObjectSP valobj_sp = ValueObjectVariable::Create(scope, m_variable_sp);
-
+
if (!valobj_sp)
{
err.SetErrorStringWithFormat("couldn't get a value object for variable %s", m_variable_sp->GetName().AsCString());
return;
}
-
+
lldb_private::DataExtractor data;
-
+
Error extract_error;
-
+
map.GetMemoryData(data, m_temporary_allocation, valobj_sp->GetByteSize(), extract_error);
-
+
if (!extract_error.Success())
{
err.SetErrorStringWithFormat("couldn't get the data for variable %s", m_variable_sp->GetName().AsCString());
return;
}
-
+
bool actually_write = true;
-
+
if (m_original_data)
{
if ((data.GetByteSize() == m_original_data->GetByteSize()) &&
@@ -649,54 +649,54 @@ public:
actually_write = false;
}
}
-
+
Error set_error;
-
+
if (actually_write)
{
valobj_sp->SetData(data, set_error);
-
+
if (!set_error.Success())
{
err.SetErrorStringWithFormat("couldn't write the new contents of %s back into the variable", m_variable_sp->GetName().AsCString());
return;
}
}
-
+
Error free_error;
-
+
map.Free(m_temporary_allocation, free_error);
-
+
if (!free_error.Success())
{
err.SetErrorStringWithFormat("couldn't free the temporary region for %s: %s", m_variable_sp->GetName().AsCString(), free_error.AsCString());
return;
}
-
+
m_original_data.reset();
m_temporary_allocation = LLDB_INVALID_ADDRESS;
m_temporary_allocation_size = 0;
}
}
-
+
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
{
StreamString dump_stream;
const lldb::addr_t load_addr = process_address + m_offset;
dump_stream.Printf("0x%" PRIx64 ": EntityVariable\n", load_addr);
-
+
Error err;
-
+
lldb::addr_t ptr = LLDB_INVALID_ADDRESS;
-
+
{
dump_stream.Printf("Pointer:\n");
-
+
DataBufferHeap data (m_size, 0);
-
+
map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
-
+
if (!err.Success())
{
dump_stream.Printf(" <could not be read>\n");
@@ -704,17 +704,17 @@ public:
else
{
DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
-
+
extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
-
+
lldb::offset_t offset;
-
+
ptr = extractor.GetPointer(&offset);
-
+
dump_stream.PutChar('\n');
}
}
-
+
if (m_temporary_allocation == LLDB_INVALID_ADDRESS)
{
dump_stream.Printf("Points to process memory:\n");
@@ -723,7 +723,7 @@ public:
{
dump_stream.Printf("Temporary allocation:\n");
}
-
+
if (ptr == LLDB_INVALID_ADDRESS)
{
dump_stream.Printf(" <could not be be found>\n");
@@ -731,9 +731,9 @@ public:
else
{
DataBufferHeap data (m_temporary_allocation_size, 0);
-
+
map.ReadMemory(data.GetBytes(), m_temporary_allocation, m_temporary_allocation_size, err);
-
+
if (!err.Success())
{
dump_stream.Printf(" <could not be read>\n");
@@ -741,24 +741,24 @@ public:
else
{
DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
-
+
extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
-
+
dump_stream.PutChar('\n');
}
}
-
+
log->PutCString(dump_stream.GetData());
}
-
+
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
{
if (m_temporary_allocation != LLDB_INVALID_ADDRESS)
{
Error free_error;
-
+
map.Free(m_temporary_allocation, free_error);
-
+
m_temporary_allocation = LLDB_INVALID_ADDRESS;
m_temporary_allocation_size = 0;
}
@@ -802,7 +802,7 @@ public:
m_size = 8;
m_alignment = 8;
}
-
+
void Materialize(lldb::StackFrameSP &frame_sp,
IRMemoryMap &map,
lldb::addr_t process_address,
@@ -815,16 +815,16 @@ public:
err.SetErrorString("Trying to create a temporary region for the result but one exists");
return;
}
-
+
const lldb::addr_t load_addr = process_address + m_offset;
size_t byte_size = m_type.GetByteSize(nullptr);
size_t bit_align = m_type.GetTypeBitAlign();
size_t byte_align = (bit_align + 7) / 8;
-
+
if (!byte_align)
byte_align = 1;
-
+
Error alloc_error;
const bool zero_memory = true;
@@ -835,24 +835,24 @@ public:
zero_memory,
alloc_error);
m_temporary_allocation_size = byte_size;
-
+
if (!alloc_error.Success())
{
err.SetErrorStringWithFormat("couldn't allocate a temporary region for the result: %s", alloc_error.AsCString());
return;
}
-
+
Error pointer_write_error;
-
+
map.WritePointerToMemory(load_addr, m_temporary_allocation, pointer_write_error);
-
+
if (!pointer_write_error.Success())
{
err.SetErrorStringWithFormat("couldn't write the address of the temporary region for the result: %s", pointer_write_error.AsCString());
}
}
}
-
+
void Dematerialize(lldb::StackFrameSP &frame_sp,
IRMemoryMap &map,
lldb::addr_t process_address,
@@ -861,73 +861,73 @@ public:
Error &err) override
{
err.Clear();
-
+
ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope();
-
+
if (!exe_scope)
{
err.SetErrorString("Couldn't dematerialize a result variable: invalid execution context scope");
return;
}
-
+
lldb::addr_t address;
Error read_error;
const lldb::addr_t load_addr = process_address + m_offset;
-
+
map.ReadPointerFromMemory (&address, load_addr, read_error);
-
+
if (!read_error.Success())
{
err.SetErrorString("Couldn't dematerialize a result variable: couldn't read its address");
return;
}
-
+
lldb::TargetSP target_sp = exe_scope->CalculateTarget();
-
+
if (!target_sp)
{
err.SetErrorString("Couldn't dematerialize a result variable: no target");
return;
}
-
+
Error type_system_error;
TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(&type_system_error, m_type.GetMinimumLanguage());
-
+
if (!type_system)
{
err.SetErrorStringWithFormat("Couldn't dematerialize a result variable: couldn't get the corresponding type system: %s", type_system_error.AsCString());
return;
}
-
+
PersistentExpressionState *persistent_state = type_system->GetPersistentExpressionState();
-
+
if (!persistent_state)
{
err.SetErrorString("Couldn't dematerialize a result variable: corresponding type system doesn't handle persistent variables");
return;
}
-
+
ConstString name = m_delegate ? m_delegate->GetName() : persistent_state->GetNextPersistentVariableName();
-
+
lldb::ExpressionVariableSP ret = persistent_state->CreatePersistentVariable(exe_scope,
name,
m_type,
map.GetByteOrder(),
map.GetAddressByteSize());
-
+
if (!ret)
{
err.SetErrorStringWithFormat("couldn't dematerialize a result variable: failed to make persistent variable %s", name.AsCString());
return;
}
-
+
lldb::ProcessSP process_sp = map.GetBestExecutionContextScope()->CalculateProcess();
-
+
if (m_delegate)
{
m_delegate->DidDematerialize(ret);
}
-
+
bool can_persist = (m_is_program_reference && process_sp && process_sp->CanJIT() && !(address >= frame_bottom && address < frame_top));
if (can_persist && m_keep_in_memory)
@@ -939,24 +939,24 @@ public:
eAddressTypeLoad,
map.GetAddressByteSize());
}
-
+
ret->ValueUpdated();
-
+
const size_t pvar_byte_size = ret->GetByteSize();
uint8_t *pvar_data = ret->GetValueBytes();
-
+
map.ReadMemory(pvar_data, address, pvar_byte_size, read_error);
-
+
if (!read_error.Success())
{
err.SetErrorString("Couldn't dematerialize a result variable: couldn't read its memory");
return;
}
-
+
if (!can_persist || !m_keep_in_memory)
{
ret->m_flags |= ExpressionVariable::EVNeedsAllocation;
-
+
if (m_temporary_allocation != LLDB_INVALID_ADDRESS)
{
Error free_error;
@@ -967,30 +967,30 @@ public:
{
ret->m_flags |= ExpressionVariable::EVIsLLDBAllocated;
}
-
+
m_temporary_allocation = LLDB_INVALID_ADDRESS;
m_temporary_allocation_size = 0;
}
-
+
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
{
StreamString dump_stream;
-
+
const lldb::addr_t load_addr = process_address + m_offset;
dump_stream.Printf("0x%" PRIx64 ": EntityResultVariable\n", load_addr);
-
+
Error err;
-
+
lldb::addr_t ptr = LLDB_INVALID_ADDRESS;
-
+
{
dump_stream.Printf("Pointer:\n");
-
+
DataBufferHeap data (m_size, 0);
-
+
map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
-
+
if (!err.Success())
{
dump_stream.Printf(" <could not be read>\n");
@@ -998,17 +998,17 @@ public:
else
{
DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
-
+
extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
-
+
lldb::offset_t offset;
-
+
ptr = extractor.GetPointer(&offset);
-
+
dump_stream.PutChar('\n');
}
}
-
+
if (m_temporary_allocation == LLDB_INVALID_ADDRESS)
{
dump_stream.Printf("Points to process memory:\n");
@@ -1017,7 +1017,7 @@ public:
{
dump_stream.Printf("Temporary allocation:\n");
}
-
+
if (ptr == LLDB_INVALID_ADDRESS)
{
dump_stream.Printf(" <could not be be found>\n");
@@ -1025,9 +1025,9 @@ public:
else
{
DataBufferHeap data (m_temporary_allocation_size, 0);
-
+
map.ReadMemory(data.GetBytes(), m_temporary_allocation, m_temporary_allocation_size, err);
-
+
if (!err.Success())
{
dump_stream.Printf(" <could not be read>\n");
@@ -1035,25 +1035,25 @@ public:
else
{
DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
-
+
extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
-
+
dump_stream.PutChar('\n');
}
}
-
+
log->PutCString(dump_stream.GetData());
}
-
+
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
{
if (!m_keep_in_memory && m_temporary_allocation != LLDB_INVALID_ADDRESS)
{
Error free_error;
-
+
map.Free(m_temporary_allocation, free_error);
}
-
+
m_temporary_allocation = LLDB_INVALID_ADDRESS;
m_temporary_allocation_size = 0;
}
@@ -1062,7 +1062,7 @@ private:
CompilerType m_type;
bool m_is_program_reference;
bool m_keep_in_memory;
-
+
lldb::addr_t m_temporary_allocation;
size_t m_temporary_allocation_size;
Materializer::PersistentVariableDelegate *m_delegate;
@@ -1093,7 +1093,7 @@ public:
m_size = 8;
m_alignment = 8;
}
-
+
void Materialize(lldb::StackFrameSP &frame_sp,
IRMemoryMap &map,
lldb::addr_t process_address,
@@ -1109,38 +1109,38 @@ public:
(uint64_t)load_addr,
m_symbol.GetName().AsCString());
}
-
+
const Address sym_address = m_symbol.GetAddress();
ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope();
-
+
lldb::TargetSP target_sp;
-
+
if (exe_scope)
target_sp = map.GetBestExecutionContextScope()->CalculateTarget();
-
+
if (!target_sp)
{
err.SetErrorStringWithFormat("couldn't resolve symbol %s because there is no target", m_symbol.GetName().AsCString());
return;
}
-
+
lldb::addr_t resolved_address = sym_address.GetLoadAddress(target_sp.get());
-
+
if (resolved_address == LLDB_INVALID_ADDRESS)
resolved_address = sym_address.GetFileAddress();
-
+
Error pointer_write_error;
-
+
map.WritePointerToMemory(load_addr, resolved_address, pointer_write_error);
-
+
if (!pointer_write_error.Success())
{
err.SetErrorStringWithFormat("couldn't write the address of symbol %s: %s", m_symbol.GetName().AsCString(), pointer_write_error.AsCString());
return;
}
}
-
+
void Dematerialize(lldb::StackFrameSP &frame_sp,
IRMemoryMap &map,
lldb::addr_t process_address,
@@ -1158,27 +1158,27 @@ public:
(uint64_t)load_addr,
m_symbol.GetName().AsCString());
}
-
+
// no work needs to be done
}
-
+
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
{
StreamString dump_stream;
-
+
Error err;
-
+
const lldb::addr_t load_addr = process_address + m_offset;
dump_stream.Printf("0x%" PRIx64 ": EntitySymbol (%s)\n", load_addr, m_symbol.GetName().AsCString());
-
+
{
dump_stream.Printf("Pointer:\n");
-
+
DataBufferHeap data (m_size, 0);
-
+
map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
-
+
if (!err.Success())
{
dump_stream.Printf(" <could not be read>\n");
@@ -1186,16 +1186,16 @@ public:
else
{
DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
-
+
extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
-
+
dump_stream.PutChar('\n');
}
}
-
+
log->PutCString(dump_stream.GetData());
}
-
+
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
{
}
@@ -1225,14 +1225,14 @@ public:
m_size = m_register_info.byte_size;
m_alignment = m_register_info.byte_size;
}
-
+
void Materialize(lldb::StackFrameSP &frame_sp,
IRMemoryMap &map,
lldb::addr_t process_address,
Error &err) override
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
const lldb::addr_t load_addr = process_address + m_offset;
if (log)
@@ -1243,37 +1243,37 @@ public:
}
RegisterValue reg_value;
-
+
if (!frame_sp.get())
{
err.SetErrorStringWithFormat("couldn't materialize register %s without a stack frame", m_register_info.name);
return;
}
-
+
lldb::RegisterContextSP reg_context_sp = frame_sp->GetRegisterContext();
-
+
if (!reg_context_sp->ReadRegister(&m_register_info, reg_value))
{
err.SetErrorStringWithFormat("couldn't read the value of register %s", m_register_info.name);
return;
}
-
+
DataExtractor register_data;
-
+
if (!reg_value.GetData(register_data))
{
err.SetErrorStringWithFormat("couldn't get the data for register %s", m_register_info.name);
return;
}
-
+
if (register_data.GetByteSize() != m_register_info.byte_size)
{
err.SetErrorStringWithFormat("data for register %s had size %llu but we expected %llu", m_register_info.name, (unsigned long long)register_data.GetByteSize(), (unsigned long long)m_register_info.byte_size);
return;
}
-
+
m_register_contents.reset(new DataBufferHeap(register_data.GetDataStart(), register_data.GetByteSize()));
-
+
Error write_error;
map.WriteMemory(load_addr, register_data.GetDataStart(), register_data.GetByteSize(), write_error);
@@ -1284,7 +1284,7 @@ public:
return;
}
}
-
+
void Dematerialize(lldb::StackFrameSP &frame_sp,
IRMemoryMap &map,
lldb::addr_t process_address,
@@ -1293,7 +1293,7 @@ public:
Error &err) override
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
const lldb::addr_t load_addr = process_address + m_offset;
if (log)
@@ -1302,64 +1302,64 @@ public:
(uint64_t)load_addr,
m_register_info.name);
}
-
+
Error extract_error;
-
+
DataExtractor register_data;
-
+
if (!frame_sp.get())
{
err.SetErrorStringWithFormat("couldn't dematerialize register %s without a stack frame", m_register_info.name);
return;
}
-
+
lldb::RegisterContextSP reg_context_sp = frame_sp->GetRegisterContext();
-
+
map.GetMemoryData(register_data, load_addr, m_register_info.byte_size, extract_error);
-
+
if (!extract_error.Success())
{
err.SetErrorStringWithFormat("couldn't get the data for register %s: %s", m_register_info.name, extract_error.AsCString());
return;
}
-
+
if (!memcmp(register_data.GetDataStart(), m_register_contents->GetBytes(), register_data.GetByteSize()))
{
// No write required, and in particular we avoid errors if the register wasn't writable
-
+
m_register_contents.reset();
return;
}
-
+
m_register_contents.reset();
-
+
RegisterValue register_value (const_cast<uint8_t*>(register_data.GetDataStart()), register_data.GetByteSize(), register_data.GetByteOrder());
-
+
if (!reg_context_sp->WriteRegister(&m_register_info, register_value))
{
err.SetErrorStringWithFormat("couldn't write the value of register %s", m_register_info.name);
return;
}
}
-
+
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
{
StreamString dump_stream;
-
+
Error err;
-
+
const lldb::addr_t load_addr = process_address + m_offset;
-
+
dump_stream.Printf("0x%" PRIx64 ": EntityRegister (%s)\n", load_addr, m_register_info.name);
-
+
{
dump_stream.Printf("Value:\n");
-
+
DataBufferHeap data (m_size, 0);
-
+
map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
-
+
if (!err.Success())
{
dump_stream.Printf(" <could not be read>\n");
@@ -1367,16 +1367,16 @@ public:
else
{
DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
-
+
extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
-
+
dump_stream.PutChar('\n');
}
}
-
+
log->PutCString(dump_stream.GetData());
}
-
+
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
{
}
@@ -1406,7 +1406,7 @@ Materializer::Materializer () :
Materializer::~Materializer ()
{
DematerializerSP dematerializer_sp = m_dematerializer_wp.lock();
-
+
if (dematerializer_sp)
dematerializer_sp->Wipe();
}
@@ -1507,7 +1507,7 @@ Materializer::Dematerializer::Wipe ()
{
if (!IsValid())
return;
-
+
for (EntityUP &entity_up : m_materializer->m_entities)
{
entity_up->Wipe (*m_map, m_process_address);
diff --git a/source/Expression/REPL.cpp b/source/Expression/REPL.cpp
index 1727a13abd06..30f256002fc8 100644
--- a/source/Expression/REPL.cpp
+++ b/source/Expression/REPL.cpp
@@ -363,6 +363,7 @@ REPL::IOHandlerInputComplete (IOHandler &io_handler, std::string &code)
result_valobj_sp,
error,
0, // Line offset
+ nullptr, // Fixed Expression
&jit_module_sp);
//CommandInterpreter &ci = debugger.GetCommandInterpreter();
@@ -410,7 +411,7 @@ REPL::IOHandlerInputComplete (IOHandler &io_handler, std::string &code)
case lldb::eExpressionSetupError:
case lldb::eExpressionParseError:
add_to_code = false;
- // Fall through
+ LLVM_FALLTHROUGH;
case lldb::eExpressionDiscarded:
error_sp->Printf("%s\n", error.AsCString());
break;
diff --git a/source/Expression/UserExpression.cpp b/source/Expression/UserExpression.cpp
index 70f004ba25c9..3e2e07e9cb22 100644
--- a/source/Expression/UserExpression.cpp
+++ b/source/Expression/UserExpression.cpp
@@ -16,18 +16,19 @@
#include <string>
#include <map>
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionSourceCode.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Expression/UserExpression.h"
-#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
@@ -159,6 +160,7 @@ UserExpression::Evaluate (ExecutionContext &exe_ctx,
lldb::ValueObjectSP &result_valobj_sp,
Error &error,
uint32_t line_offset,
+ std::string *fixed_expression,
lldb::ModuleSP *jit_module_sp_ptr)
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
@@ -193,6 +195,11 @@ UserExpression::Evaluate (ExecutionContext &exe_ctx,
if (process == NULL || !process->CanJIT())
execution_policy = eExecutionPolicyNever;
+
+ // We need to set the expression execution thread here, turns out parse can call functions in the process of
+ // looking up symbols, which will escape the context set by exe_ctx passed to Execute.
+ lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP();
+ ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(thread_sp);
const char *full_prefix = NULL;
const char *option_prefix = options.GetPrefix();
@@ -232,8 +239,6 @@ UserExpression::Evaluate (ExecutionContext &exe_ctx,
log->Printf ("== [UserExpression::Evaluate] Getting expression: %s ==", error.AsCString());
return lldb::eExpressionSetupError;
}
-
- StreamString error_stream;
if (log)
log->Printf("== [UserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
@@ -244,23 +249,75 @@ UserExpression::Evaluate (ExecutionContext &exe_ctx,
if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
{
error.SetErrorString ("expression interrupted by callback before parse");
- result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
+ result_valobj_sp = ValueObjectConstResult::Create(exe_ctx.GetBestExecutionContextScope(), error);
return lldb::eExpressionInterrupted;
}
- if (!user_expression_sp->Parse (error_stream,
- exe_ctx,
- execution_policy,
- keep_expression_in_memory,
- generate_debug_info))
+ DiagnosticManager diagnostic_manager;
+
+ bool parse_success = user_expression_sp->Parse(diagnostic_manager,
+ exe_ctx,
+ execution_policy,
+ keep_expression_in_memory,
+ generate_debug_info);
+
+ // Calculate the fixed expression always, since we need it for errors.
+ std::string tmp_fixed_expression;
+ if (fixed_expression == nullptr)
+ fixed_expression = &tmp_fixed_expression;
+
+ const char *fixed_text = user_expression_sp->GetFixedText();
+ if (fixed_text != nullptr)
+ fixed_expression->append(fixed_text);
+
+ // If there is a fixed expression, try to parse it:
+ if (!parse_success)
{
execution_results = lldb::eExpressionParseError;
- if (error_stream.GetString().empty())
- error.SetExpressionError (execution_results, "expression failed to parse, unknown error");
- else
- error.SetExpressionError (execution_results, error_stream.GetString().c_str());
+ if (fixed_expression && !fixed_expression->empty() && options.GetAutoApplyFixIts())
+ {
+ lldb::UserExpressionSP fixed_expression_sp(target->GetUserExpressionForLanguage (fixed_expression->c_str(),
+ full_prefix,
+ language,
+ desired_type,
+ options,
+ error));
+ DiagnosticManager fixed_diagnostic_manager;
+ parse_success = fixed_expression_sp->Parse(fixed_diagnostic_manager,
+ exe_ctx,
+ execution_policy,
+ keep_expression_in_memory,
+ generate_debug_info);
+ if (parse_success)
+ {
+ diagnostic_manager.Clear();
+ user_expression_sp = fixed_expression_sp;
+ }
+ else
+ {
+ // If the fixed expression failed to parse, don't tell the user about, that won't help.
+ fixed_expression->clear();
+ }
+ }
+
+ if (!parse_success)
+ {
+ if (!fixed_expression->empty() && target->GetEnableNotifyAboutFixIts())
+ {
+ error.SetExpressionErrorWithFormat(execution_results, "expression failed to parse, fixed expression suggested:\n %s",
+ fixed_expression->c_str());
+ }
+ else
+ {
+ if (!diagnostic_manager.Diagnostics().size())
+ error.SetExpressionError(execution_results, "expression failed to parse, unknown error");
+ else
+ error.SetExpressionError(execution_results, diagnostic_manager.GetString().c_str());
+ }
+ }
}
- else
+
+ if (parse_success)
{
// If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module if one was created
if (jit_module_sp_ptr)
@@ -274,8 +331,13 @@ UserExpression::Evaluate (ExecutionContext &exe_ctx,
if (log)
log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
- if (error_stream.GetString().empty())
- error.SetExpressionError (lldb::eExpressionSetupError, "expression needed to run but couldn't");
+ if (!diagnostic_manager.Diagnostics().size())
+ error.SetExpressionError(lldb::eExpressionSetupError, "expression needed to run but couldn't");
+ }
+ else if (execution_policy == eExecutionPolicyTopLevel)
+ {
+ error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric);
+ return lldb::eExpressionCompleted;
}
else
{
@@ -286,31 +348,23 @@ UserExpression::Evaluate (ExecutionContext &exe_ctx,
return lldb::eExpressionInterrupted;
}
- error_stream.GetString().clear();
+ diagnostic_manager.Clear();
if (log)
log->Printf("== [UserExpression::Evaluate] Executing expression ==");
- execution_results = user_expression_sp->Execute (error_stream,
- exe_ctx,
- options,
- user_expression_sp,
- expr_result);
-
- if (options.GetResultIsInternal() && expr_result && process)
- {
- process->GetTarget().GetPersistentExpressionStateForLanguage(language)->RemovePersistentVariable (expr_result);
- }
+ execution_results =
+ user_expression_sp->Execute(diagnostic_manager, exe_ctx, options, user_expression_sp, expr_result);
if (execution_results != lldb::eExpressionCompleted)
{
if (log)
log->Printf("== [UserExpression::Evaluate] Execution completed abnormally ==");
- if (error_stream.GetString().empty())
- error.SetExpressionError (execution_results, "expression failed to execute, unknown error");
+ if (!diagnostic_manager.Diagnostics().size())
+ error.SetExpressionError(execution_results, "expression failed to execute, unknown error");
else
- error.SetExpressionError (execution_results, error_stream.GetString().c_str());
+ error.SetExpressionError(execution_results, diagnostic_manager.GetString().c_str());
}
else
{
@@ -346,3 +400,21 @@ UserExpression::Evaluate (ExecutionContext &exe_ctx,
return execution_results;
}
+
+lldb::ExpressionResults
+UserExpression::Execute(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options,
+ lldb::UserExpressionSP &shared_ptr_to_me,
+ lldb::ExpressionVariableSP &result_var)
+{
+ lldb::ExpressionResults expr_result = DoExecute(diagnostic_manager, exe_ctx, options, shared_ptr_to_me, result_var);
+ Target *target = exe_ctx.GetTargetPtr();
+ if (options.GetResultIsInternal() && result_var && target)
+ {
+ target->GetPersistentExpressionStateForLanguage(m_language)->RemovePersistentVariable (result_var);
+ }
+ return expr_result;
+}
+
+
diff --git a/source/Expression/UtilityFunction.cpp b/source/Expression/UtilityFunction.cpp
index f93e358d35df..2ff77f093db2 100644
--- a/source/Expression/UtilityFunction.cpp
+++ b/source/Expression/UtilityFunction.cpp
@@ -20,10 +20,11 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
-#include "lldb/Expression/FunctionCaller.h"
-#include "lldb/Expression/UtilityFunction.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionSourceCode.h"
+#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/IRExecutionUnit.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/Host.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
@@ -69,14 +70,17 @@ UtilityFunction::~UtilityFunction ()
// FIXME: We should check that every time this is called it is called with the same return type & arguments...
FunctionCaller *
-UtilityFunction::MakeFunctionCaller (const CompilerType &return_type, const ValueList &arg_value_list, Error &error)
+UtilityFunction::MakeFunctionCaller (const CompilerType &return_type, const ValueList &arg_value_list, lldb::ThreadSP thread_to_use_sp, Error &error)
{
if (m_caller_up)
return m_caller_up.get();
ProcessSP process_sp = m_jit_process_wp.lock();
if (!process_sp)
+ {
+ error.SetErrorString("Can't make a function caller without a process.");
return nullptr;
+ }
Address impl_code_address;
impl_code_address.SetOffset(StartAddress());
@@ -96,26 +100,24 @@ UtilityFunction::MakeFunctionCaller (const CompilerType &return_type, const Valu
}
if (m_caller_up)
{
- StreamString errors;
- errors.Clear();
- unsigned num_errors = m_caller_up->CompileFunction(errors);
+ DiagnosticManager diagnostics;
+
+ unsigned num_errors = m_caller_up->CompileFunction(thread_to_use_sp, diagnostics);
if (num_errors)
{
- error.SetErrorStringWithFormat ("Error compiling %s caller function: \"%s\".",
- m_function_name.c_str(),
- errors.GetData());
+ error.SetErrorStringWithFormat("Error compiling %s caller function: \"%s\".", m_function_name.c_str(),
+ diagnostics.GetString().c_str());
m_caller_up.reset();
return nullptr;
}
-
- errors.Clear();
+
+ diagnostics.Clear();
ExecutionContext exe_ctx(process_sp);
-
- if (!m_caller_up->WriteFunctionWrapper(exe_ctx, errors))
+
+ if (!m_caller_up->WriteFunctionWrapper(exe_ctx, diagnostics))
{
- error.SetErrorStringWithFormat ("Error inserting caller function for %s: \"%s\".",
- m_function_name.c_str(),
- errors.GetData());
+ error.SetErrorStringWithFormat("Error inserting caller function for %s: \"%s\".", m_function_name.c_str(),
+ diagnostics.GetString().c_str());
m_caller_up.reset();
return nullptr;
}
diff --git a/source/Host/Makefile b/source/Host/Makefile
deleted file mode 100644
index da90c8c364a3..000000000000
--- a/source/Host/Makefile
+++ /dev/null
@@ -1,65 +0,0 @@
-##===- source/Host/Makefile --------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LEVEL := $(LLDB_LEVEL)/../..
-
-include $(LEVEL)/Makefile.config
-
-define DIR_SOURCES
-SOURCES += $$(addprefix $(1)/,$$(notdir $$(wildcard $$(PROJ_SRC_DIR)/$(1)/*.cpp \
- $$(PROJ_SRC_DIR)/*.cc $$(PROJ_SRC_DIR)/$(1)/*.c $$(PROJ_SRC_DIR)/$(1)/*.mm)))
-endef
-
-$(eval $(call DIR_SOURCES,common))
-
-ifeq ($(HOST_OS),Darwin)
-$(eval $(call DIR_SOURCES,posix))
-$(eval $(call DIR_SOURCES,macosx))
-CFCPP_SOURCES = \
- $(addprefix macosx/cfcpp/,$(notdir $(wildcard $(PROJ_SRC_DIR)/macosx/cfcpp/*.cpp)))
-SOURCES += $(CFCPP_SOURCES)
-
-CFCPP_BaseNameSources := $(sort $(basename $(CFCPP_SOURCES)))
-CFCPP_OBJECTS := $(CFCPP_BaseNameSources:%=$(ObjDir)/%.o)
-
-# Make sure the cfcpp output directory exists
-$(CFCPP_OBJECTS): $(ObjDir)/cfcpp/.dir
-endif
-
-ifeq ($(HOST_OS),Linux)
-$(eval $(call DIR_SOURCES,posix))
-$(eval $(call DIR_SOURCES,linux))
-endif
-
-ifneq (,$(filter $(HOST_OS), FreeBSD GNU/kFreeBSD))
-$(eval $(call DIR_SOURCES,posix))
-$(eval $(call DIR_SOURCES,freebsd))
-endif
-
-ifeq ($(HOST_OS),NetBSD)
-$(eval $(call DIR_SOURCES,posix))
-$(eval $(call DIR_SOURCES,netbsd))
-endif
-
-ifeq ($(HOST_OS),MingW)
-$(eval $(call DIR_SOURCES,windows))
-SOURCES += posix/ConnectionFileDescriptorPosix.cpp
-endif
-
-ifeq ($(HOST_OS),Android)
-$(eval $(call DIR_SOURCES,posix))
-$(eval $(call DIR_SOURCES,linux))
-$(eval $(call DIR_SOURCES,android))
-endif
-
-LIBRARYNAME := lldbHost
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Host/android/LibcGlue.cpp b/source/Host/android/LibcGlue.cpp
index 3842fb6c2a8e..091c11d15535 100644
--- a/source/Host/android/LibcGlue.cpp
+++ b/source/Host/android/LibcGlue.cpp
@@ -27,11 +27,6 @@ time_t timegm(struct tm* t)
return (time_t) timegm64(t);
}
-int signalfd (int fd, const sigset_t *mask, int flags)
-{
- return syscall(__NR_signalfd4, fd, mask, _NSIG / 8, flags);
-}
-
int posix_openpt(int flags)
{
return open("/dev/ptmx", flags);
diff --git a/source/Host/common/Editline.cpp b/source/Host/common/Editline.cpp
index 4640154c6cb1..d7209feb46db 100644
--- a/source/Host/common/Editline.cpp
+++ b/source/Host/common/Editline.cpp
@@ -19,7 +19,6 @@
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Utility/LLDBAssert.h"
using namespace lldb_private;
@@ -227,9 +226,9 @@ namespace lldb_private
GetHistory (const std::string &prefix)
{
typedef std::map<std::string, EditlineHistoryWP> WeakHistoryMap;
- static Mutex g_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_mutex;
static WeakHistoryMap g_weak_map;
- Mutex::Locker locker (g_mutex);
+ std::lock_guard<std::recursive_mutex> guard(g_mutex);
WeakHistoryMap::const_iterator pos = g_weak_map.find (prefix);
EditlineHistorySP history_sp;
if (pos != g_weak_map.end())
@@ -587,9 +586,9 @@ Editline::GetCharacter (EditLineCharType * c)
// (blocking operation), so we do not hold the mutex indefinitely. This gives a chance
// for someone to interrupt us. After Read returns, immediately lock the mutex again and
// check if we were interrupted.
- m_output_mutex.Unlock();
+ m_output_mutex.unlock();
int read_count = m_input_connection.Read(&ch, 1, UINT32_MAX, status, NULL);
- m_output_mutex.Lock();
+ m_output_mutex.lock();
if (m_editor_status == EditorStatus::Interrupted)
{
while (read_count > 0 && status == lldb::eConnectionStatusSuccess)
@@ -658,41 +657,9 @@ Editline::BreakLineCommand (int ch)
// Establish the new cursor position at the start of a line when inserting a line break
m_revert_cursor_index = 0;
- // Don't perform end of input detection or automatic formatting when pasting
+ // Don't perform automatic formatting when pasting
if (!IsInputPending (m_input_file))
{
- // If this is the end of the last line, treat this as a potential exit
- if (m_current_line_index == m_input_lines.size() - 1 && new_line_fragment.length() == 0)
- {
- bool end_of_input = true;
- if (m_is_input_complete_callback)
- {
- SaveEditedLine();
- auto lines = GetInputAsStringList();
- end_of_input = m_is_input_complete_callback (this, lines, m_is_input_complete_callback_baton);
-
- // The completion test is allowed to change the input lines when complete
- if (end_of_input)
- {
- m_input_lines.clear();
- for (unsigned index = 0; index < lines.GetSize(); index++)
- {
-#if LLDB_EDITLINE_USE_WCHAR
- m_input_lines.insert (m_input_lines.end(), m_utf8conv.from_bytes (lines[index]));
-#else
- m_input_lines.insert (m_input_lines.end(), lines[index]);
-#endif
- }
- }
- }
- if (end_of_input)
- {
- fprintf (m_output_file, "\n");
- m_editor_status = EditorStatus::Complete;
- return CC_NEWLINE;
- }
- }
-
// Apply smart indentation
if (m_fix_indentation_callback)
{
@@ -721,7 +688,49 @@ Editline::BreakLineCommand (int ch)
}
unsigned char
-Editline::DeleteNextCharCommand (int ch)
+Editline::EndOrAddLineCommand(int ch)
+{
+ // Don't perform end of input detection when pasting, always treat this as a line break
+ if (IsInputPending(m_input_file))
+ {
+ return BreakLineCommand(ch);
+ }
+
+ // Save any edits to this line
+ SaveEditedLine();
+
+ // If this is the end of the last line, consider whether to add a line instead
+ const LineInfoW *info = el_wline(m_editline);
+ if (m_current_line_index == m_input_lines.size() - 1 && info->cursor == info->lastchar)
+ {
+ if (m_is_input_complete_callback)
+ {
+ auto lines = GetInputAsStringList();
+ if (!m_is_input_complete_callback(this, lines, m_is_input_complete_callback_baton))
+ {
+ return BreakLineCommand(ch);
+ }
+
+ // The completion test is allowed to change the input lines when complete
+ m_input_lines.clear();
+ for (unsigned index = 0; index < lines.GetSize(); index++)
+ {
+#if LLDB_EDITLINE_USE_WCHAR
+ m_input_lines.insert(m_input_lines.end(), m_utf8conv.from_bytes(lines[index]));
+#else
+ m_input_lines.insert(m_input_lines.end(), lines[index]);
+#endif
+ }
+ }
+ }
+ MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockEnd);
+ fprintf(m_output_file, "\n");
+ m_editor_status = EditorStatus::Complete;
+ return CC_NEWLINE;
+}
+
+unsigned char
+Editline::DeleteNextCharCommand(int ch)
{
LineInfoW * info = const_cast<LineInfoW *>(el_wline (m_editline));
@@ -861,7 +870,23 @@ Editline::NextLineCommand (int ch)
}
unsigned char
-Editline::FixIndentationCommand (int ch)
+Editline::PreviousHistoryCommand(int ch)
+{
+ SaveEditedLine();
+
+ return RecallHistory(true);
+}
+
+unsigned char
+Editline::NextHistoryCommand(int ch)
+{
+ SaveEditedLine();
+
+ return RecallHistory(false);
+}
+
+unsigned char
+Editline::FixIndentationCommand(int ch)
{
if (!m_fix_indentation_callback)
return CC_NORM;
@@ -1075,36 +1100,46 @@ Editline::ConfigureEditor (bool multiline)
}));
// Commands used for multiline support, registered whether or not they're used
- el_set (m_editline, EL_ADDFN, "lldb-break-line", "Insert a line break",
- (EditlineCommandCallbackType)([] (EditLine * editline, int ch) {
- return Editline::InstanceFor (editline)->BreakLineCommand (ch);
- }));
- el_set (m_editline, EL_ADDFN, "lldb-delete-next-char", "Delete next character",
- (EditlineCommandCallbackType)([] (EditLine * editline, int ch) {
- return Editline::InstanceFor (editline)->DeleteNextCharCommand (ch);
- }));
- el_set (m_editline, EL_ADDFN, "lldb-delete-previous-char", "Delete previous character",
- (EditlineCommandCallbackType)([] (EditLine * editline, int ch) {
- return Editline::InstanceFor (editline)->DeletePreviousCharCommand (ch);
- }));
- el_set (m_editline, EL_ADDFN, "lldb-previous-line", "Move to previous line",
- (EditlineCommandCallbackType)([] (EditLine * editline, int ch) {
- return Editline::InstanceFor (editline)->PreviousLineCommand (ch);
- }));
- el_set (m_editline, EL_ADDFN, "lldb-next-line", "Move to next line",
- (EditlineCommandCallbackType)([] (EditLine * editline, int ch) {
- return Editline::InstanceFor (editline)->NextLineCommand (ch);
- }));
- el_set (m_editline, EL_ADDFN, "lldb-buffer-start", "Move to start of buffer",
- (EditlineCommandCallbackType)([] (EditLine * editline, int ch) {
- return Editline::InstanceFor (editline)->BufferStartCommand (ch);
- }));
- el_set (m_editline, EL_ADDFN, "lldb-buffer-end", "Move to end of buffer",
- (EditlineCommandCallbackType)([] (EditLine * editline, int ch) {
- return Editline::InstanceFor (editline)->BufferEndCommand (ch);
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-break-line"), EditLineConstString("Insert a line break"),
+ (EditlineCommandCallbackType)(
+ [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->BreakLineCommand(ch); }));
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-end-or-add-line"),
+ EditLineConstString("End editing or continue when incomplete"),
+ (EditlineCommandCallbackType)(
+ [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->EndOrAddLineCommand(ch); }));
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-delete-next-char"),
+ EditLineConstString("Delete next character"), (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
+ return Editline::InstanceFor(editline)->DeleteNextCharCommand(ch);
+ }));
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-delete-previous-char"),
+ EditLineConstString("Delete previous character"),
+ (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
+ return Editline::InstanceFor(editline)->DeletePreviousCharCommand(ch);
}));
- el_set (m_editline, EL_ADDFN, "lldb-fix-indentation", "Fix line indentation",
- (EditlineCommandCallbackType)([] (EditLine * editline, int ch) {
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-previous-line"),
+ EditLineConstString("Move to previous line"), (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
+ return Editline::InstanceFor(editline)->PreviousLineCommand(ch);
+ }));
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-next-line"), EditLineConstString("Move to next line"),
+ (EditlineCommandCallbackType)(
+ [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->NextLineCommand(ch); }));
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-previous-history"),
+ EditLineConstString("Move to previous history"),
+ (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
+ return Editline::InstanceFor(editline)->PreviousHistoryCommand(ch);
+ }));
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-next-history"), EditLineConstString("Move to next history"),
+ (EditlineCommandCallbackType)(
+ [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->NextHistoryCommand(ch); }));
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-buffer-start"),
+ EditLineConstString("Move to start of buffer"),
+ (EditlineCommandCallbackType)(
+ [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->BufferStartCommand(ch); }));
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-buffer-end"), EditLineConstString("Move to end of buffer"),
+ (EditlineCommandCallbackType)(
+ [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->BufferEndCommand(ch); }));
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-fix-indentation"),
+ EditLineConstString("Fix line indentation"), (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
return Editline::InstanceFor (editline)->FixIndentationCommand (ch);
}));
@@ -1115,9 +1150,11 @@ Editline::ConfigureEditor (bool multiline)
EditlineCommandCallbackType complete_callback = [] (EditLine * editline, int ch) {
return Editline::InstanceFor (editline)->TabCommand (ch);
};
- el_set (m_editline, EL_ADDFN, "lldb-complete", "Invoke completion", complete_callback);
- el_set (m_editline, EL_ADDFN, "lldb_complete", "Invoke completion", complete_callback);
-
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-complete"), EditLineConstString("Invoke completion"),
+ complete_callback);
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb_complete"), EditLineConstString("Invoke completion"),
+ complete_callback);
+
// General bindings we don't mind being overridden
if (!multiline) {
el_set (m_editline, EL_BIND, "^r", "em-inc-search-prev", NULL); // Cycle through backwards search, entering string
@@ -1129,10 +1166,10 @@ Editline::ConfigureEditor (bool multiline)
el_source (m_editline, NULL);
// Register an internal binding that external developers shouldn't use
- el_set (m_editline, EL_ADDFN, "lldb-revert-line", "Revert line to saved state",
- (EditlineCommandCallbackType)([] (EditLine * editline, int ch) {
- return Editline::InstanceFor (editline)->RevertLineCommand (ch);
- }));
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-revert-line"),
+ EditLineConstString("Revert line to saved state"),
+ (EditlineCommandCallbackType)(
+ [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->RevertLineCommand(ch); }));
// Register keys that perform auto-indent correction
if (m_fix_indentation_callback && m_fix_indentation_callback_chars)
@@ -1150,8 +1187,10 @@ Editline::ConfigureEditor (bool multiline)
// Multi-line editor bindings
if (multiline)
{
- el_set (m_editline, EL_BIND, "\n", "lldb-break-line", NULL);
- el_set (m_editline, EL_BIND, "\r", "lldb-break-line", NULL);
+ el_set(m_editline, EL_BIND, "\n", "lldb-end-or-add-line", NULL);
+ el_set(m_editline, EL_BIND, "\r", "lldb-end-or-add-line", NULL);
+ el_set(m_editline, EL_BIND, ESCAPE "\n", "lldb-break-line", NULL);
+ el_set(m_editline, EL_BIND, ESCAPE "\r", "lldb-break-line", NULL);
el_set (m_editline, EL_BIND, "^p", "lldb-previous-line", NULL);
el_set (m_editline, EL_BIND, "^n", "lldb-next-line", NULL);
el_set (m_editline, EL_BIND, "^?", "lldb-delete-previous-char", NULL);
@@ -1166,6 +1205,10 @@ Editline::ConfigureEditor (bool multiline)
el_set (m_editline, EL_BIND, ESCAPE ">", "lldb-buffer-end", NULL);
el_set (m_editline, EL_BIND, ESCAPE "[A", "lldb-previous-line", NULL);
el_set (m_editline, EL_BIND, ESCAPE "[B", "lldb-next-line", NULL);
+ el_set(m_editline, EL_BIND, ESCAPE ESCAPE "[A", "lldb-previous-history", NULL);
+ el_set(m_editline, EL_BIND, ESCAPE ESCAPE "[B", "lldb-next-history", NULL);
+ el_set(m_editline, EL_BIND, ESCAPE "[1;3A", "lldb-previous-history", NULL);
+ el_set(m_editline, EL_BIND, ESCAPE "[1;3B", "lldb-next-history", NULL);
}
else
{
@@ -1209,6 +1252,32 @@ Editline::Editline (const char * editline_name, FILE * input_file, FILE * output
// Get a shared history instance
m_editor_name = (editline_name == nullptr) ? "lldb-tmp" : editline_name;
m_history_sp = EditlineHistory::GetHistory (m_editor_name);
+
+#ifdef USE_SETUPTERM_WORKAROUND
+ if (m_output_file)
+ {
+ const int term_fd = fileno(m_output_file);
+ if (term_fd != -1)
+ {
+ static std::mutex *g_init_terminal_fds_mutex_ptr = nullptr;
+ static std::set<int> *g_init_terminal_fds_ptr = nullptr;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, [&]() {
+ g_init_terminal_fds_mutex_ptr = new std::mutex(); // NOTE: Leak to avoid C++ destructor chain issues
+ g_init_terminal_fds_ptr = new std::set<int>(); // NOTE: Leak to avoid C++ destructor chain issues
+ });
+
+ // We must make sure to initialize the terminal a given file descriptor
+ // only once. If we do this multiple times, we start leaking memory.
+ std::lock_guard<std::mutex> guard(*g_init_terminal_fds_mutex_ptr);
+ if (g_init_terminal_fds_ptr->find(term_fd) == g_init_terminal_fds_ptr->end())
+ {
+ g_init_terminal_fds_ptr->insert(term_fd);
+ setupterm((char *)0, term_fd, (int *)0);
+ }
+ }
+ }
+#endif
}
Editline::~Editline()
@@ -1284,7 +1353,7 @@ bool
Editline::Interrupt()
{
bool result = true;
- Mutex::Locker locker(m_output_mutex);
+ std::lock_guard<std::mutex> guard(m_output_mutex);
if (m_editor_status == EditorStatus::Editing) {
fprintf(m_output_file, "^C\n");
result = m_input_connection.InterruptRead();
@@ -1297,7 +1366,7 @@ bool
Editline::Cancel()
{
bool result = true;
- Mutex::Locker locker(m_output_mutex);
+ std::lock_guard<std::mutex> guard(m_output_mutex);
if (m_editor_status == EditorStatus::Editing) {
MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
fprintf(m_output_file, ANSI_CLEAR_BELOW);
@@ -1338,8 +1407,8 @@ Editline::GetLine (std::string &line, bool &interrupted)
ConfigureEditor (false);
m_input_lines = std::vector<EditLineStringType>();
m_input_lines.insert (m_input_lines.begin(), EditLineConstString(""));
-
- Mutex::Locker locker(m_output_mutex);
+
+ std::lock_guard<std::mutex> guard(m_output_mutex);
lldbassert(m_editor_status != EditorStatus::Editing);
if (m_editor_status == EditorStatus::Interrupted)
@@ -1354,10 +1423,6 @@ Editline::GetLine (std::string &line, bool &interrupted)
m_editor_status = EditorStatus::Editing;
m_revert_cursor_index = -1;
-#ifdef USE_SETUPTERM_WORKAROUND
- setupterm((char *)0, fileno(m_output_file), (int *)0);
-#endif
-
int count;
auto input = el_wgets (m_editline, &count);
@@ -1392,8 +1457,8 @@ Editline::GetLines (int first_line_number, StringList &lines, bool &interrupted)
SetBaseLineNumber (first_line_number);
m_input_lines = std::vector<EditLineStringType>();
m_input_lines.insert (m_input_lines.begin(), EditLineConstString(""));
-
- Mutex::Locker locker(m_output_mutex);
+
+ std::lock_guard<std::mutex> guard(m_output_mutex);
// Begin the line editing loop
DisplayInput();
SetCurrentLine (0);
@@ -1404,9 +1469,6 @@ Editline::GetLines (int first_line_number, StringList &lines, bool &interrupted)
m_revert_cursor_index = -1;
while (m_editor_status == EditorStatus::Editing)
{
-#ifdef USE_SETUPTERM_WORKAROUND
- setupterm((char *)0, fileno(m_output_file), (int *)0);
-#endif
int count;
m_current_line_rows = -1;
el_wpush (m_editline, EditLineConstString("\x1b[^")); // Revert to the existing line content
@@ -1427,7 +1489,7 @@ Editline::GetLines (int first_line_number, StringList &lines, bool &interrupted)
void
Editline::PrintAsync (Stream *stream, const char *s, size_t len)
{
- Mutex::Locker locker(m_output_mutex);
+ std::lock_guard<std::mutex> guard(m_output_mutex);
if (m_editor_status == EditorStatus::Editing)
{
MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp
index 71a6149cd614..9d4ab3d9c55e 100644
--- a/source/Host/common/File.cpp
+++ b/source/Host/common/File.cpp
@@ -14,7 +14,6 @@
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
-#include <sys/stat.h>
#ifdef _WIN32
#include "lldb/Host/windows/windows.h"
@@ -22,6 +21,7 @@
#include <sys/ioctl.h>
#endif
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Process.h" // for llvm::sys::Process::FileDescriptorHasColors()
#include "lldb/Core/DataBufferHeap.h"
@@ -29,6 +29,7 @@
#include "lldb/Core/Log.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/FileSystem.h"
using namespace lldb;
using namespace lldb_private;
@@ -109,27 +110,6 @@ File::File (const FileSpec& filespec,
}
}
-File::File (const File &rhs) :
- IOObject(eFDTypeFile, false),
- m_descriptor (kInvalidDescriptor),
- m_stream (kInvalidStream),
- m_options (0),
- m_own_stream (false),
- m_is_interactive (eLazyBoolCalculate),
- m_is_real_terminal (eLazyBoolCalculate)
-{
- Duplicate (rhs);
-}
-
-
-File &
-File::operator = (const File &rhs)
-{
- if (this != &rhs)
- Duplicate (rhs);
- return *this;
-}
-
File::~File()
{
Close ();
@@ -191,7 +171,7 @@ File::GetStream ()
#ifdef _WIN32
m_descriptor = ::_dup(GetDescriptor());
#else
- m_descriptor = ::fcntl(GetDescriptor(), F_DUPFD);
+ m_descriptor = dup(GetDescriptor());
#endif
m_should_close_fd = true;
}
@@ -215,7 +195,6 @@ File::GetStream ()
return m_stream;
}
-
void
File::SetStream (FILE *fh, bool transfer_ownership)
{
@@ -226,35 +205,6 @@ File::SetStream (FILE *fh, bool transfer_ownership)
}
Error
-File::Duplicate (const File &rhs)
-{
- Error error;
- if (IsValid ())
- Close();
-
- if (rhs.DescriptorIsValid())
- {
-#ifdef _WIN32
- m_descriptor = ::_dup(rhs.GetDescriptor());
-#else
- m_descriptor = ::fcntl(rhs.GetDescriptor(), F_DUPFD);
-#endif
- if (!DescriptorIsValid())
- error.SetErrorToErrno();
- else
- {
- m_options = rhs.m_options;
- m_should_close_fd = true;
- }
- }
- else
- {
- error.SetErrorString ("invalid file to duplicate");
- }
- return error;
-}
-
-Error
File::Open (const char *path, uint32_t options, uint32_t permissions)
{
Error error;
@@ -288,7 +238,7 @@ File::Open (const char *path, uint32_t options, uint32_t permissions)
oflag |= O_RDONLY;
#ifndef _WIN32
- if (options & eOpenoptionDontFollowSymlinks)
+ if (options & eOpenOptionDontFollowSymlinks)
oflag |= O_NOFOLLOW;
#endif
}
@@ -318,7 +268,18 @@ File::Open (const char *path, uint32_t options, uint32_t permissions)
do
{
+#ifdef _WIN32
+ std::wstring wpath;
+ if (!llvm::ConvertUTF8toWide(path, wpath))
+ {
+ m_descriptor = -1;
+ error.SetErrorString("Error converting path to UTF-16");
+ return error;
+ }
+ ::_wsopen_s(&m_descriptor, wpath.c_str(), oflag, _SH_DENYNO, mode);
+#else
m_descriptor = ::open(path, oflag, mode);
+#endif
} while (m_descriptor < 0 && errno == EINTR);
if (!DescriptorIsValid())
@@ -338,7 +299,8 @@ File::GetPermissions(const FileSpec &file_spec, Error &error)
if (file_spec)
{
struct stat file_stats;
- if (::stat(file_spec.GetCString(), &file_stats) == -1)
+ int stat_result = FileSystem::Stat(file_spec.GetCString(), &file_stats);
+ if (stat_result == -1)
error.SetErrorToErrno();
else
{
@@ -399,6 +361,15 @@ File::Close ()
return error;
}
+void
+File::Clear ()
+{
+ m_stream = nullptr;
+ m_descriptor = -1;
+ m_options = 0;
+ m_own_stream = false;
+ m_is_interactive = m_supports_colors = m_is_real_terminal = eLazyBoolCalculate;
+}
Error
File::GetFileSpec (FileSpec &file_spec) const
diff --git a/source/Host/common/FileSpec.cpp b/source/Host/common/FileSpec.cpp
index 8885a791d88c..53c0ab40e676 100644
--- a/source/Host/common/FileSpec.cpp
+++ b/source/Host/common/FileSpec.cpp
@@ -17,7 +17,6 @@
#ifndef _MSC_VER
#include <libgen.h>
#endif
-#include <sys/stat.h>
#include <set>
#include <string.h>
#include <fstream>
@@ -40,6 +39,7 @@
#include "lldb/Utility/CleanUp.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
@@ -57,10 +57,22 @@ PathSyntaxIsPosix(FileSpec::PathSyntax syntax)
FileSystem::GetNativePathSyntax() == FileSpec::ePathSyntaxPosix));
}
+const char *
+GetPathSeparators(FileSpec::PathSyntax syntax)
+{
+ return PathSyntaxIsPosix(syntax) ? "/" : "\\/";
+}
+
char
-GetPathSeparator(FileSpec::PathSyntax syntax)
+GetPrefferedPathSeparator(FileSpec::PathSyntax syntax)
+{
+ return GetPathSeparators(syntax)[0];
+}
+
+bool
+IsPathSeparator(char value, FileSpec::PathSyntax syntax)
{
- return PathSyntaxIsPosix(syntax) ? '/' : '\\';
+ return value == '/' || (!PathSyntaxIsPosix(syntax) && value == '\\');
}
void
@@ -90,12 +102,73 @@ GetFileStats (const FileSpec *file_spec, struct stat *stats_ptr)
{
char resolved_path[PATH_MAX];
if (file_spec->GetPath (resolved_path, sizeof(resolved_path)))
- return ::stat (resolved_path, stats_ptr) == 0;
+ return FileSystem::Stat(resolved_path, stats_ptr) == 0;
return false;
}
+size_t
+FilenamePos(llvm::StringRef str, FileSpec::PathSyntax syntax)
+{
+ if (str.size() == 2 && IsPathSeparator(str[0], syntax) && str[0] == str[1])
+ return 0;
+
+ if (str.size() > 0 && IsPathSeparator(str.back(), syntax))
+ return str.size() - 1;
+
+ size_t pos = str.find_last_of(GetPathSeparators(syntax), str.size() - 1);
+
+ if (!PathSyntaxIsPosix(syntax) && pos == llvm::StringRef::npos)
+ pos = str.find_last_of(':', str.size() - 2);
+
+ if (pos == llvm::StringRef::npos || (pos == 1 && IsPathSeparator(str[0], syntax)))
+ return 0;
+
+ return pos + 1;
+}
+
+size_t
+RootDirStart(llvm::StringRef str, FileSpec::PathSyntax syntax)
+{
+ // case "c:/"
+ if (!PathSyntaxIsPosix(syntax) && (str.size() > 2 && str[1] == ':' && IsPathSeparator(str[2], syntax)))
+ return 2;
+
+ // case "//"
+ if (str.size() == 2 && IsPathSeparator(str[0], syntax) && str[0] == str[1])
+ return llvm::StringRef::npos;
+
+ // case "//net"
+ if (str.size() > 3 && IsPathSeparator(str[0], syntax) && str[0] == str[1] && !IsPathSeparator(str[2], syntax))
+ return str.find_first_of(GetPathSeparators(syntax), 2);
+
+ // case "/"
+ if (str.size() > 0 && IsPathSeparator(str[0], syntax))
+ return 0;
+
+ return llvm::StringRef::npos;
}
+size_t
+ParentPathEnd(llvm::StringRef path, FileSpec::PathSyntax syntax)
+{
+ size_t end_pos = FilenamePos(path, syntax);
+
+ bool filename_was_sep = path.size() > 0 && IsPathSeparator(path[end_pos], syntax);
+
+ // Skip separators except for root dir.
+ size_t root_dir_pos = RootDirStart(path.substr(0, end_pos), syntax);
+
+ while (end_pos > 0 && (end_pos - 1) != root_dir_pos && IsPathSeparator(path[end_pos - 1], syntax))
+ --end_pos;
+
+ if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
+ return llvm::StringRef::npos;
+
+ return end_pos;
+}
+
+} // end anonymous namespace
+
// Resolves the username part of a path of the form ~user/other/directories, and
// writes the result into dst_path. This will also resolve "~" to the current user.
// If you want to complete "~" to the list of users, pass it to ResolvePartialUsername.
@@ -112,8 +185,22 @@ FileSpec::ResolveUsername (llvm::SmallVectorImpl<char> &path)
{
// A path of ~/ resolves to the current user's home dir
llvm::SmallString<64> home_dir;
+ // llvm::sys::path::home_directory() only checks if "HOME" is set in the
+ // environment and does nothing else to locate the user home directory
if (!llvm::sys::path::home_directory(home_dir))
- return;
+ {
+ struct passwd *pw = getpwuid(getuid());
+ if (pw && pw->pw_dir && pw->pw_dir[0])
+ {
+ // Update our environemnt so llvm::sys::path::home_directory() works next time
+ setenv("HOME", pw->pw_dir, 0);
+ home_dir.assign(llvm::StringRef(pw->pw_dir));
+ }
+ else
+ {
+ return;
+ }
+ }
// Overwrite the ~ with the first character of the homedir, and insert
// the rest. This way we only trigger one move, whereas an insert
@@ -206,15 +293,10 @@ FileSpec::Resolve (llvm::SmallVectorImpl<char> &path)
#endif // #ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
// Save a copy of the original path that's passed in
- llvm::SmallString<PATH_MAX> original_path(path.begin(), path.end());
+ llvm::SmallString<128> original_path(path.begin(), path.end());
llvm::sys::fs::make_absolute(path);
-
-
- path.push_back(0); // Be sure we have a nul terminated string
- path.pop_back();
- struct stat file_stats;
- if (::stat (path.data(), &file_stats) != 0)
+ if (!llvm::sys::fs::exists(path))
{
path.clear();
path.append(original_path.begin(), original_path.end());
@@ -318,30 +400,34 @@ FileSpec::SetFile (const char *pathname, bool resolve, PathSyntax syntax)
if (pathname == NULL || pathname[0] == '\0')
return;
- llvm::SmallString<64> normalized(pathname);
+ llvm::SmallString<64> resolved(pathname);
if (resolve)
{
- FileSpec::Resolve (normalized);
+ FileSpec::Resolve (resolved);
m_is_resolved = true;
}
- // Only normalize after resolving the path. Resolution will modify the path
- // string, potentially adding wrong kinds of slashes to the path, that need
- // to be re-normalized.
- Normalize(normalized, syntax);
+ Normalize(resolved, syntax);
- llvm::StringRef resolve_path_ref(normalized.c_str());
- llvm::StringRef filename_ref = llvm::sys::path::filename(resolve_path_ref);
- if (!filename_ref.empty())
+ llvm::StringRef resolve_path_ref(resolved.c_str());
+ size_t dir_end = ParentPathEnd(resolve_path_ref, syntax);
+ if (dir_end == 0)
{
- m_filename.SetString (filename_ref);
- llvm::StringRef directory_ref = llvm::sys::path::parent_path(resolve_path_ref);
- if (!directory_ref.empty())
- m_directory.SetString(directory_ref);
+ m_filename.SetString(resolve_path_ref);
+ return;
}
- else
- m_directory.SetCString(normalized.c_str());
+
+ m_directory.SetString(resolve_path_ref.substr(0, dir_end));
+
+ size_t filename_begin = dir_end;
+ size_t root_dir_start = RootDirStart(resolve_path_ref, syntax);
+ while (filename_begin != llvm::StringRef::npos && filename_begin < resolve_path_ref.size() &&
+ filename_begin != root_dir_start && IsPathSeparator(resolve_path_ref[filename_begin], syntax))
+ ++filename_begin;
+ m_filename.SetString((filename_begin == llvm::StringRef::npos || filename_begin >= resolve_path_ref.size())
+ ? "."
+ : resolve_path_ref.substr(filename_begin));
}
void
@@ -390,66 +476,78 @@ FileSpec::operator!() const
return !m_directory && !m_filename;
}
+bool
+FileSpec::DirectoryEquals(const FileSpec &rhs) const
+{
+ const bool case_sensitive = IsCaseSensitive() || rhs.IsCaseSensitive();
+ return ConstString::Equals(m_directory, rhs.m_directory, case_sensitive);
+}
+
+bool
+FileSpec::FileEquals(const FileSpec &rhs) const
+{
+ const bool case_sensitive = IsCaseSensitive() || rhs.IsCaseSensitive();
+ return ConstString::Equals(m_filename, rhs.m_filename, case_sensitive);
+}
+
//------------------------------------------------------------------
// Equal to operator
//------------------------------------------------------------------
bool
FileSpec::operator== (const FileSpec& rhs) const
{
- if (m_filename == rhs.m_filename)
+ if (!FileEquals(rhs))
+ return false;
+ if (DirectoryEquals(rhs))
+ return true;
+
+ // TODO: determine if we want to keep this code in here.
+ // The code below was added to handle a case where we were
+ // trying to set a file and line breakpoint and one path
+ // was resolved, and the other not and the directory was
+ // in a mount point that resolved to a more complete path:
+ // "/tmp/a.c" == "/private/tmp/a.c". I might end up pulling
+ // this out...
+ if (IsResolved() && rhs.IsResolved())
{
- if (m_directory == rhs.m_directory)
- return true;
-
- // TODO: determine if we want to keep this code in here.
- // The code below was added to handle a case where we were
- // trying to set a file and line breakpoint and one path
- // was resolved, and the other not and the directory was
- // in a mount point that resolved to a more complete path:
- // "/tmp/a.c" == "/private/tmp/a.c". I might end up pulling
- // this out...
- if (IsResolved() && rhs.IsResolved())
- {
- // Both paths are resolved, no need to look further...
- return false;
- }
-
- FileSpec resolved_lhs(*this);
+ // Both paths are resolved, no need to look further...
+ return false;
+ }
- // If "this" isn't resolved, resolve it
- if (!IsResolved())
+ FileSpec resolved_lhs(*this);
+
+ // If "this" isn't resolved, resolve it
+ if (!IsResolved())
+ {
+ if (resolved_lhs.ResolvePath())
{
- if (resolved_lhs.ResolvePath())
- {
- // This path wasn't resolved but now it is. Check if the resolved
- // directory is the same as our unresolved directory, and if so,
- // we can mark this object as resolved to avoid more future resolves
- m_is_resolved = (m_directory == resolved_lhs.m_directory);
- }
- else
- return false;
+ // This path wasn't resolved but now it is. Check if the resolved
+ // directory is the same as our unresolved directory, and if so,
+ // we can mark this object as resolved to avoid more future resolves
+ m_is_resolved = (m_directory == resolved_lhs.m_directory);
}
-
- FileSpec resolved_rhs(rhs);
- if (!rhs.IsResolved())
+ else
+ return false;
+ }
+
+ FileSpec resolved_rhs(rhs);
+ if (!rhs.IsResolved())
+ {
+ if (resolved_rhs.ResolvePath())
{
- if (resolved_rhs.ResolvePath())
- {
- // rhs's path wasn't resolved but now it is. Check if the resolved
- // directory is the same as rhs's unresolved directory, and if so,
- // we can mark this object as resolved to avoid more future resolves
- rhs.m_is_resolved = (rhs.m_directory == resolved_rhs.m_directory);
- }
- else
- return false;
+ // rhs's path wasn't resolved but now it is. Check if the resolved
+ // directory is the same as rhs's unresolved directory, and if so,
+ // we can mark this object as resolved to avoid more future resolves
+ rhs.m_is_resolved = (rhs.m_directory == resolved_rhs.m_directory);
}
-
- // If we reach this point in the code we were able to resolve both paths
- // and since we only resolve the paths if the basenames are equal, then
- // we can just check if both directories are equal...
- return resolved_lhs.GetDirectory() == resolved_rhs.GetDirectory();
+ else
+ return false;
}
- return false;
+
+ // If we reach this point in the code we were able to resolve both paths
+ // and since we only resolve the paths if the basenames are equal, then
+ // we can just check if both directories are equal...
+ return DirectoryEquals(rhs);
}
//------------------------------------------------------------------
@@ -507,6 +605,9 @@ FileSpec::Compare(const FileSpec& a, const FileSpec& b, bool full)
{
int result = 0;
+ // case sensitivity of compare
+ const bool case_sensitive = a.IsCaseSensitive() || b.IsCaseSensitive();
+
// If full is true, then we must compare both the directory and filename.
// If full is false, then if either directory is empty, then we match on
@@ -516,32 +617,35 @@ FileSpec::Compare(const FileSpec& a, const FileSpec& b, bool full)
if (full || (a.m_directory && b.m_directory))
{
- result = ConstString::Compare(a.m_directory, b.m_directory);
+ result = ConstString::Compare(a.m_directory, b.m_directory, case_sensitive);
if (result)
return result;
}
- return ConstString::Compare (a.m_filename, b.m_filename);
+ return ConstString::Compare(a.m_filename, b.m_filename, case_sensitive);
}
bool
FileSpec::Equal (const FileSpec& a, const FileSpec& b, bool full, bool remove_backups)
{
+ // case sensitivity of equality test
+ const bool case_sensitive = a.IsCaseSensitive() || b.IsCaseSensitive();
+
if (!full && (a.GetDirectory().IsEmpty() || b.GetDirectory().IsEmpty()))
- return a.m_filename == b.m_filename;
+ return ConstString::Equals(a.m_filename, b.m_filename, case_sensitive);
else if (remove_backups == false)
return a == b;
else
{
- if (a.m_filename != b.m_filename)
+ if (!ConstString::Equals(a.m_filename, b.m_filename, case_sensitive))
return false;
- if (a.m_directory == b.m_directory)
+ if (ConstString::Equals(a.m_directory, b.m_directory, case_sensitive))
return true;
ConstString a_without_dots;
ConstString b_without_dots;
RemoveBackupDots (a.m_directory, a_without_dots);
RemoveBackupDots (b.m_directory, b_without_dots);
- return a_without_dots == b_without_dots;
+ return ConstString::Equals(a_without_dots, b_without_dots, case_sensitive);
}
}
@@ -670,7 +774,7 @@ FileSpec::Dump(Stream *s) const
{
std::string path{GetPath(true)};
s->PutCString(path.c_str());
- char path_separator = GetPathSeparator(m_syntax);
+ char path_separator = GetPrefferedPathSeparator(m_syntax);
if (!m_filename && !path.empty() && path.back() != path_separator)
s->PutChar(path_separator);
}
@@ -797,7 +901,10 @@ FileSpec::IsSymbolicLink () const
return false;
#ifdef _WIN32
- auto attrs = ::GetFileAttributes (resolved_path);
+ std::wstring wpath;
+ if (!llvm::ConvertUTF8toWide(resolved_path, wpath))
+ return false;
+ auto attrs = ::GetFileAttributesW(wpath.c_str());
if (attrs == INVALID_FILE_ATTRIBUTES)
return false;
@@ -900,11 +1007,10 @@ void
FileSpec::GetPath(llvm::SmallVectorImpl<char> &path, bool denormalize) const
{
path.append(m_directory.GetStringRef().begin(), m_directory.GetStringRef().end());
- if (m_directory)
- path.insert(path.end(), '/');
+ if (m_directory && m_filename && !IsPathSeparator(m_directory.GetStringRef().back(), m_syntax))
+ path.insert(path.end(), GetPrefferedPathSeparator(m_syntax));
path.append(m_filename.GetStringRef().begin(), m_filename.GetStringRef().end());
Normalize(path, m_syntax);
- if (path.size() > 1 && path.back() == '/') path.pop_back();
if (denormalize && !path.empty())
Denormalize(path, m_syntax);
}
@@ -1096,12 +1202,18 @@ FileSpec::ForEachItemInDirectory (const char *dir_path, DirectoryCallback const
{
if (dir_path && dir_path[0])
{
-#if _WIN32
+#ifdef _WIN32
std::string szDir(dir_path);
szDir += "\\*";
- WIN32_FIND_DATA ffd;
- HANDLE hFind = FindFirstFile(szDir.c_str(), &ffd);
+ std::wstring wszDir;
+ if (!llvm::ConvertUTF8toWide(szDir, wszDir))
+ {
+ return eEnumerateDirectoryResultNext;
+ }
+
+ WIN32_FIND_DATAW ffd;
+ HANDLE hFind = FindFirstFileW(wszDir.c_str(), &ffd);
if (hFind == INVALID_HANDLE_VALUE)
{
@@ -1113,12 +1225,12 @@ FileSpec::ForEachItemInDirectory (const char *dir_path, DirectoryCallback const
FileSpec::FileType file_type = eFileTypeUnknown;
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
- size_t len = strlen(ffd.cFileName);
+ size_t len = wcslen(ffd.cFileName);
- if (len == 1 && ffd.cFileName[0] == '.')
+ if (len == 1 && ffd.cFileName[0] == L'.')
continue;
- if (len == 2 && ffd.cFileName[0] == '.' && ffd.cFileName[1] == '.')
+ if (len == 2 && ffd.cFileName[0] == L'.' && ffd.cFileName[1] == L'.')
continue;
file_type = eFileTypeDirectory;
@@ -1132,12 +1244,19 @@ FileSpec::ForEachItemInDirectory (const char *dir_path, DirectoryCallback const
file_type = eFileTypeRegular;
}
- char child_path[MAX_PATH];
- const int child_path_len = ::snprintf (child_path, sizeof(child_path), "%s\\%s", dir_path, ffd.cFileName);
- if (child_path_len < (int)(sizeof(child_path) - 1))
+ std::string fileName;
+ if (!llvm::convertWideToUTF8(ffd.cFileName, fileName))
+ {
+ continue;
+ }
+
+ std::vector<char> child_path(PATH_MAX);
+ const int child_path_len =
+ ::snprintf(child_path.data(), child_path.size(), "%s\\%s", dir_path, fileName.c_str());
+ if (child_path_len < (int)(child_path.size() - 1))
{
// Don't resolve the file type or path
- FileSpec child_path_spec (child_path, false);
+ FileSpec child_path_spec(child_path.data(), false);
EnumerateDirectoryResult result = callback (file_type, child_path_spec);
@@ -1150,7 +1269,8 @@ FileSpec::ForEachItemInDirectory (const char *dir_path, DirectoryCallback const
break;
case eEnumerateDirectoryResultEnter: // Recurse into the current entry if it is a directory or symlink, or next if not
- if (FileSpec::ForEachItemInDirectory(child_path, callback) == eEnumerateDirectoryResultQuit)
+ if (FileSpec::ForEachItemInDirectory(child_path.data(), callback) ==
+ eEnumerateDirectoryResultQuit)
{
// The subdirectory returned Quit, which means to
// stop all directory enumerations at all levels.
@@ -1167,7 +1287,7 @@ FileSpec::ForEachItemInDirectory (const char *dir_path, DirectoryCallback const
return eEnumerateDirectoryResultQuit;
}
}
- } while (FindNextFile(hFind, &ffd) != 0);
+ } while (FindNextFileW(hFind, &ffd) != 0);
FindClose(hFind);
#else
@@ -1313,17 +1433,9 @@ FileSpec::EnumerateDirectory
FileSpec
FileSpec::CopyByAppendingPathComponent (const char *new_path) const
{
- const bool resolve = false;
- if (m_filename.IsEmpty() && m_directory.IsEmpty())
- return FileSpec(new_path,resolve);
- StreamString stream;
- if (m_filename.IsEmpty())
- stream.Printf("%s/%s",m_directory.GetCString(),new_path);
- else if (m_directory.IsEmpty())
- stream.Printf("%s/%s",m_filename.GetCString(),new_path);
- else
- stream.Printf("%s/%s/%s",m_directory.GetCString(), m_filename.GetCString(),new_path);
- return FileSpec(stream.GetData(),resolve);
+ FileSpec ret = *this;
+ ret.AppendPathComponent(new_path);
+ return ret;
}
FileSpec
@@ -1424,20 +1536,26 @@ void
FileSpec::AppendPathComponent(const char *new_path)
{
if (!new_path) return;
- const bool resolve = false;
- if (m_filename.IsEmpty() && m_directory.IsEmpty())
+
+ StreamString stream;
+ if (!m_directory.IsEmpty())
{
- SetFile(new_path, resolve);
- return;
+ stream.PutCString(m_directory.GetCString());
+ if (!IsPathSeparator(m_directory.GetStringRef().back(), m_syntax))
+ stream.PutChar(GetPrefferedPathSeparator(m_syntax));
}
- StreamString stream;
- if (m_filename.IsEmpty() || (m_filename.GetLength() == 1 && m_filename.GetCString()[0] == '.'))
- stream.Printf("%s/%s", m_directory.GetCString(), new_path);
- else if (m_directory.IsEmpty())
- stream.Printf("%s/%s", m_filename.GetCString(), new_path);
- else
- stream.Printf("%s/%s/%s", m_directory.GetCString(), m_filename.GetCString(), new_path);
- SetFile(stream.GetData(), resolve);
+
+ if (!m_filename.IsEmpty())
+ {
+ stream.PutCString(m_filename.GetCString());
+ if (!IsPathSeparator(m_filename.GetStringRef().back(), m_syntax))
+ stream.PutChar(GetPrefferedPathSeparator(m_syntax));
+ }
+
+ stream.PutCString(new_path);
+
+ const bool resolve = false;
+ SetFile(stream.GetData(), resolve, m_syntax);
}
void
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index e89f4def478c..656caa5e0d19 100644
--- a/source/Host/common/Host.cpp
+++ b/source/Host/common/Host.cpp
@@ -39,8 +39,10 @@
#include <pthread_np.h>
#endif
-// C++ includes
-#include <limits>
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
@@ -91,7 +93,6 @@ struct MonitorInfo
{
lldb::pid_t pid; // The process ID to monitor
Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals
- void *callback_baton; // The callback baton for the callback function
bool monitor_signals; // If true, call the callback when "pid" gets signaled.
};
@@ -99,13 +100,13 @@ static thread_result_t
MonitorChildProcessThreadFunction (void *arg);
HostThread
-Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals)
+Host::StartMonitoringChildProcess(const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid,
+ bool monitor_signals)
{
MonitorInfo * info_ptr = new MonitorInfo();
info_ptr->pid = pid;
info_ptr->callback = callback;
- info_ptr->callback_baton = callback_baton;
info_ptr->monitor_signals = monitor_signals;
char thread_name[256];
@@ -182,7 +183,6 @@ MonitorChildProcessThreadFunction (void *arg)
MonitorInfo *info = (MonitorInfo *)arg;
const Host::MonitorChildProcessCallback callback = info->callback;
- void * const callback_baton = info->callback_baton;
const bool monitor_signals = info->monitor_signals;
assert (info->pid <= UINT32_MAX);
@@ -283,8 +283,8 @@ MonitorChildProcessThreadFunction (void *arg)
{
bool callback_return = false;
if (callback)
- callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status);
-
+ callback_return = callback(wait_pid, exited, signal, exit_status);
+
// If our process exited, then this thread should exit
if (exited && wait_pid == abs(pid))
{
@@ -498,7 +498,6 @@ struct ShellInfo
{
ShellInfo () :
process_reaped (false),
- can_delete (false),
pid (LLDB_INVALID_PROCESS_ID),
signo(-1),
status(-1)
@@ -506,33 +505,23 @@ struct ShellInfo
}
lldb_private::Predicate<bool> process_reaped;
- lldb_private::Predicate<bool> can_delete;
lldb::pid_t pid;
int signo;
int status;
};
static bool
-MonitorShellCommand (void *callback_baton,
- lldb::pid_t pid,
- bool exited, // True if the process did exit
- int signo, // Zero for no signal
- int status) // Exit value of process if signal is zero
+MonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid,
+ bool exited, // True if the process did exit
+ int signo, // Zero for no signal
+ int status) // Exit value of process if signal is zero
{
- ShellInfo *shell_info = (ShellInfo *)callback_baton;
shell_info->pid = pid;
shell_info->signo = signo;
shell_info->status = status;
// Let the thread running Host::RunShellCommand() know that the process
// exited and that ShellInfo has been filled in by broadcasting to it
- shell_info->process_reaped.SetValue(1, eBroadcastAlways);
- // Now wait for a handshake back from that thread running Host::RunShellCommand
- // so we know that we can delete shell_info_ptr
- shell_info->can_delete.WaitForValueEqualTo(true);
- // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete...
- usleep(1000);
- // Now delete the shell info that was passed into this function
- delete shell_info;
+ shell_info->process_reaped.SetValue(true, eBroadcastAlways);
return true;
}
@@ -615,13 +604,14 @@ Host::RunShellCommand(const Args &args,
launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true);
launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true);
}
-
- // The process monitor callback will delete the 'shell_info_ptr' below...
- std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo());
-
+
+ std::shared_ptr<ShellInfo> shell_info_sp(new ShellInfo());
const bool monitor_signals = false;
- launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals);
-
+ launch_info.SetMonitorProcessCallback(std::bind(MonitorShellCommand, shell_info_sp, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3,
+ std::placeholders::_4),
+ monitor_signals);
+
error = LaunchProcess (launch_info);
const lldb::pid_t pid = launch_info.GetProcessID();
@@ -630,11 +620,6 @@ Host::RunShellCommand(const Args &args,
if (error.Success())
{
- // The process successfully launched, so we can defer ownership of
- // "shell_info" to the MonitorShellCommand callback function that will
- // get called when the process dies. We release the unique pointer as it
- // doesn't need to delete the ShellInfo anymore.
- ShellInfo *shell_info = shell_info_ap.release();
TimeValue *timeout_ptr = nullptr;
TimeValue timeout_time(TimeValue::Now());
if (timeout_sec > 0) {
@@ -642,7 +627,7 @@ Host::RunShellCommand(const Args &args,
timeout_ptr = &timeout_time;
}
bool timed_out = false;
- shell_info->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out);
+ shell_info_sp->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out);
if (timed_out)
{
error.SetErrorString("timed out waiting for shell command to complete");
@@ -653,16 +638,16 @@ Host::RunShellCommand(const Args &args,
timeout_time = TimeValue::Now();
timeout_time.OffsetWithSeconds(1);
timed_out = false;
- shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
+ shell_info_sp->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
}
else
{
if (status_ptr)
- *status_ptr = shell_info->status;
-
+ *status_ptr = shell_info_sp->status;
+
if (signo_ptr)
- *signo_ptr = shell_info->signo;
-
+ *signo_ptr = shell_info_sp->signo;
+
if (command_output_ptr)
{
command_output_ptr->clear();
@@ -683,14 +668,10 @@ Host::RunShellCommand(const Args &args,
}
}
}
- shell_info->can_delete.SetValue(true, eBroadcastAlways);
}
if (FileSystem::GetFileExists(output_file_spec))
FileSystem::Unlink(output_file_spec);
- // Handshake with the monitor thread, or just let it know in advance that
- // it can delete "shell_info" in case we timed out and were not able to kill
- // the process...
return error;
}
diff --git a/source/Host/common/HostInfoBase.cpp b/source/Host/common/HostInfoBase.cpp
index f7ba755b5bab..2bff4d9a670f 100644
--- a/source/Host/common/HostInfoBase.cpp
+++ b/source/Host/common/HostInfoBase.cpp
@@ -31,19 +31,6 @@ using namespace lldb_private;
namespace
{
- void
- CleanupProcessSpecificLLDBTempDir()
- {
- // Get the process specific LLDB temporary directory and delete it.
- FileSpec tmpdir_file_spec;
- if (!HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
- return;
-
- // Remove the LLDB temporary directory if we have one. Set "recurse" to
- // true to all files that were created for the LLDB process can be cleaned up.
- FileSystem::DeleteDirectory(tmpdir_file_spec, true);
- }
-
//----------------------------------------------------------------------
// The HostInfoBaseFields is a work around for windows not supporting
// static variables correctly in a thread safe way. Really each of the
@@ -54,6 +41,16 @@ namespace
struct HostInfoBaseFields
{
+ ~HostInfoBaseFields()
+ {
+ if (m_lldb_process_tmp_dir.Exists())
+ {
+ // Remove the LLDB temporary directory if we have one. Set "recurse" to
+ // true to all files that were created for the LLDB process can be cleaned up.
+ FileSystem::DeleteDirectory(m_lldb_process_tmp_dir, true);
+ }
+ }
+
uint32_t m_number_cpus;
std::string m_vendor_string;
std::string m_os_string;
@@ -82,6 +79,13 @@ HostInfoBase::Initialize()
g_fields = new HostInfoBaseFields();
}
+void
+HostInfoBase::Terminate()
+{
+ delete g_fields;
+ g_fields = nullptr;
+}
+
uint32_t
HostInfoBase::GetNumberCPUS()
{
@@ -335,9 +339,6 @@ HostInfoBase::ComputeProcessTempFileDirectory(FileSpec &file_spec)
if (!FileSystem::MakeDirectory(temp_file_spec, eFilePermissionsDirectoryDefault).Success())
return false;
- // Make an atexit handler to clean up the process specify LLDB temp dir
- // and all of its contents.
- ::atexit(CleanupProcessSpecificLLDBTempDir);
file_spec.GetDirectory().SetCString(temp_file_spec.GetCString());
return true;
}
@@ -419,6 +420,7 @@ HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_6
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
case llvm::Triple::sparcv9:
+ case llvm::Triple::systemz:
arch_64.SetTriple(triple);
break;
}
diff --git a/source/Host/common/HostProcess.cpp b/source/Host/common/HostProcess.cpp
index 58a214693a52..0262e1c03c20 100644
--- a/source/Host/common/HostProcess.cpp
+++ b/source/Host/common/HostProcess.cpp
@@ -49,9 +49,9 @@ bool HostProcess::IsRunning() const
}
HostThread
-HostProcess::StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals)
+HostProcess::StartMonitoring(const Host::MonitorChildProcessCallback &callback, bool monitor_signals)
{
- return m_native_process->StartMonitoring(callback, callback_baton, monitor_signals);
+ return m_native_process->StartMonitoring(callback, monitor_signals);
}
HostNativeProcessBase &HostProcess::GetNativeProcess()
diff --git a/source/Host/common/MonitoringProcessLauncher.cpp b/source/Host/common/MonitoringProcessLauncher.cpp
index 0fad44a9ec08..2845155987e3 100644
--- a/source/Host/common/MonitoringProcessLauncher.cpp
+++ b/source/Host/common/MonitoringProcessLauncher.cpp
@@ -75,12 +75,10 @@ MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info, E
Host::MonitorChildProcessCallback callback = launch_info.GetMonitorProcessCallback();
- void *baton = nullptr;
bool monitor_signals = false;
if (callback)
{
// If the ProcessLaunchInfo specified a callback, use that.
- baton = launch_info.GetMonitorProcessBaton();
monitor_signals = launch_info.GetMonitorSignals();
}
else
@@ -88,7 +86,7 @@ MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info, E
callback = Process::SetProcessExitStatus;
}
- process.StartMonitoring(callback, baton, monitor_signals);
+ process.StartMonitoring(callback, monitor_signals);
if (log)
log->PutCString("started monitoring child process.");
}
diff --git a/source/Host/common/NativeBreakpointList.cpp b/source/Host/common/NativeBreakpointList.cpp
index 52b9baf5f537..67873a06dd27 100644
--- a/source/Host/common/NativeBreakpointList.cpp
+++ b/source/Host/common/NativeBreakpointList.cpp
@@ -17,8 +17,7 @@
using namespace lldb;
using namespace lldb_private;
-NativeBreakpointList::NativeBreakpointList () :
- m_mutex (Mutex::eMutexTypeRecursive)
+NativeBreakpointList::NativeBreakpointList() : m_mutex()
{
}
@@ -29,7 +28,7 @@ NativeBreakpointList::AddRef (lldb::addr_t addr, size_t size_hint, bool hardware
if (log)
log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false");
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Check if the breakpoint is already set.
auto iter = m_breakpoints.find (addr);
@@ -72,7 +71,7 @@ NativeBreakpointList::DecRef (lldb::addr_t addr)
if (log)
log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Check if the breakpoint is already set.
auto iter = m_breakpoints.find (addr);
@@ -136,7 +135,7 @@ NativeBreakpointList::EnableBreakpoint (lldb::addr_t addr)
if (log)
log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Ensure we have said breakpoint.
auto iter = m_breakpoints.find (addr);
@@ -159,7 +158,7 @@ NativeBreakpointList::DisableBreakpoint (lldb::addr_t addr)
if (log)
log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Ensure we have said breakpoint.
auto iter = m_breakpoints.find (addr);
@@ -182,7 +181,7 @@ NativeBreakpointList::GetBreakpoint (lldb::addr_t addr, NativeBreakpointSP &brea
if (log)
log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Ensure we have said breakpoint.
auto iter = m_breakpoints.find (addr);
diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp
index 7d2f4012bf85..dfac0cb5645c 100644
--- a/source/Host/common/NativeProcessProtocol.cpp
+++ b/source/Host/common/NativeProcessProtocol.cpp
@@ -26,22 +26,22 @@ using namespace lldb_private;
// NativeProcessProtocol Members
// -----------------------------------------------------------------------------
-NativeProcessProtocol::NativeProcessProtocol (lldb::pid_t pid) :
- m_pid (pid),
- m_threads (),
- m_current_thread_id (LLDB_INVALID_THREAD_ID),
- m_threads_mutex (Mutex::eMutexTypeRecursive),
- m_state (lldb::eStateInvalid),
- m_state_mutex (Mutex::eMutexTypeRecursive),
- m_exit_type (eExitTypeInvalid),
- m_exit_status (0),
- m_exit_description (),
- m_delegates_mutex (Mutex::eMutexTypeRecursive),
- m_delegates (),
- m_breakpoint_list (),
- m_watchpoint_list (),
- m_terminal_fd (-1),
- m_stop_id (0)
+NativeProcessProtocol::NativeProcessProtocol(lldb::pid_t pid)
+ : m_pid(pid),
+ m_threads(),
+ m_current_thread_id(LLDB_INVALID_THREAD_ID),
+ m_threads_mutex(),
+ m_state(lldb::eStateInvalid),
+ m_state_mutex(),
+ m_exit_type(eExitTypeInvalid),
+ m_exit_status(0),
+ m_exit_description(),
+ m_delegates_mutex(),
+ m_delegates(),
+ m_breakpoint_list(),
+ m_watchpoint_list(),
+ m_terminal_fd(-1),
+ m_stop_id(0)
{
}
@@ -117,7 +117,7 @@ NativeProcessProtocol::SetExitStatus (ExitType exit_type, int status, const char
NativeThreadProtocolSP
NativeProcessProtocol::GetThreadAtIndex (uint32_t idx)
{
- Mutex::Locker locker (m_threads_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
if (idx < m_threads.size ())
return m_threads[idx];
return NativeThreadProtocolSP ();
@@ -137,7 +137,7 @@ NativeProcessProtocol::GetThreadByIDUnlocked (lldb::tid_t tid)
NativeThreadProtocolSP
NativeProcessProtocol::GetThreadByID (lldb::tid_t tid)
{
- Mutex::Locker locker (m_threads_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
return GetThreadByIDUnlocked (tid);
}
@@ -221,7 +221,7 @@ NativeProcessProtocol::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t w
// conceivable that if there are more threads than hardware
// watchpoints available, some of the threads will fail to set
// hardware watchpoints while software ones may be available.
- Mutex::Locker locker (m_threads_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
for (auto thread_sp : m_threads)
{
assert (thread_sp && "thread list should not have a NULL thread!");
@@ -276,7 +276,7 @@ NativeProcessProtocol::RemoveWatchpoint (lldb::addr_t addr)
Error overall_error;
- Mutex::Locker locker (m_threads_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
for (auto thread_sp : m_threads)
{
assert (thread_sp && "thread list should not have a NULL thread!");
@@ -300,7 +300,7 @@ NativeProcessProtocol::RemoveWatchpoint (lldb::addr_t addr)
bool
NativeProcessProtocol::RegisterNativeDelegate (NativeDelegate &native_delegate)
{
- Mutex::Locker locker (m_delegates_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex);
if (std::find (m_delegates.begin (), m_delegates.end (), &native_delegate) != m_delegates.end ())
return false;
@@ -312,7 +312,7 @@ NativeProcessProtocol::RegisterNativeDelegate (NativeDelegate &native_delegate)
bool
NativeProcessProtocol::UnregisterNativeDelegate (NativeDelegate &native_delegate)
{
- Mutex::Locker locker (m_delegates_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex);
const auto initial_size = m_delegates.size ();
m_delegates.erase (remove (m_delegates.begin (), m_delegates.end (), &native_delegate), m_delegates.end ());
@@ -327,7 +327,7 @@ NativeProcessProtocol::SynchronouslyNotifyProcessStateChanged (lldb::StateType s
{
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- Mutex::Locker locker (m_delegates_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex);
for (auto native_delegate: m_delegates)
native_delegate->ProcessStateChanged (this, state);
@@ -354,7 +354,7 @@ NativeProcessProtocol::NotifyDidExec ()
log->Printf ("NativeProcessProtocol::%s - preparing to call delegates", __FUNCTION__);
{
- Mutex::Locker locker (m_delegates_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex);
for (auto native_delegate: m_delegates)
native_delegate->DidExec (this);
}
@@ -394,14 +394,14 @@ NativeProcessProtocol::DisableBreakpoint (lldb::addr_t addr)
lldb::StateType
NativeProcessProtocol::GetState () const
{
- Mutex::Locker locker (m_state_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
return m_state;
}
void
NativeProcessProtocol::SetState (lldb::StateType state, bool notify_delegates)
{
- Mutex::Locker locker (m_state_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
if (state == m_state)
return;
@@ -426,8 +426,8 @@ NativeProcessProtocol::SetState (lldb::StateType state, bool notify_delegates)
uint32_t NativeProcessProtocol::GetStopID () const
{
- Mutex::Locker locker (m_state_mutex);
- return m_stop_id;
+ std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
+ return m_stop_id;
}
void
diff --git a/source/Host/common/OptionParser.cpp b/source/Host/common/OptionParser.cpp
index a9784592a738..16a29a1583d5 100644
--- a/source/Host/common/OptionParser.cpp
+++ b/source/Host/common/OptionParser.cpp
@@ -16,10 +16,10 @@
using namespace lldb_private;
void
-OptionParser::Prepare(Mutex::Locker &locker)
+OptionParser::Prepare(std::unique_lock<std::mutex> &lock)
{
- static Mutex g_mutex(Mutex::eMutexTypeNormal);
- locker.Lock(g_mutex);
+ static std::mutex g_mutex;
+ lock = std::unique_lock<std::mutex>(g_mutex);
#ifdef __GLIBC__
optind = 0;
#else
diff --git a/source/Host/common/Socket.cpp b/source/Host/common/Socket.cpp
index 91a5e37424e6..ea049ae6933e 100644
--- a/source/Host/common/Socket.cpp
+++ b/source/Host/common/Socket.cpp
@@ -268,7 +268,7 @@ Socket::DecodeHostAndPort(llvm::StringRef host_and_port,
{
bool ok = false;
port = StringConvert::ToUInt32 (port_str.c_str(), UINT32_MAX, 10, &ok);
- if (ok && port < UINT16_MAX)
+ if (ok && port <= UINT16_MAX)
{
if (error_ptr)
error_ptr->Clear();
diff --git a/source/Host/common/SocketAddress.cpp b/source/Host/common/SocketAddress.cpp
index c8b1687c378e..1dc43ea6294c 100644
--- a/source/Host/common/SocketAddress.cpp
+++ b/source/Host/common/SocketAddress.cpp
@@ -185,14 +185,12 @@ SocketAddress::GetIPAddress () const
{
case AF_INET:
if (inet_ntop(GetFamily(), &m_socket_addr.sa_ipv4.sin_addr, str, sizeof(str)))
- {
return str;
- }
+ break;
case AF_INET6:
if (inet_ntop(GetFamily(), &m_socket_addr.sa_ipv6.sin6_addr, str, sizeof(str)))
- {
return str;
- }
+ break;
}
return "";
}
diff --git a/source/Host/common/SoftwareBreakpoint.cpp b/source/Host/common/SoftwareBreakpoint.cpp
index 5a6f78372b3f..51cb34ffe6dd 100644
--- a/source/Host/common/SoftwareBreakpoint.cpp
+++ b/source/Host/common/SoftwareBreakpoint.cpp
@@ -12,7 +12,6 @@
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Host/Debug.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
diff --git a/source/Host/common/TCPSocket.cpp b/source/Host/common/TCPSocket.cpp
index b23055ee7d87..07b0cdf908f5 100644
--- a/source/Host/common/TCPSocket.cpp
+++ b/source/Host/common/TCPSocket.cpp
@@ -112,9 +112,6 @@ TCPSocket::Connect(llvm::StringRef name)
if (!DecodeHostAndPort (name, host_str, port_str, port, &error))
return error;
- // Enable local address reuse
- SetOptionReuseAddress();
-
struct sockaddr_in sa;
::memset (&sa, 0, sizeof (sa));
sa.sin_family = kDomain;
diff --git a/source/Host/common/UDPSocket.cpp b/source/Host/common/UDPSocket.cpp
index 8297232ae723..9a2028e97a40 100644
--- a/source/Host/common/UDPSocket.cpp
+++ b/source/Host/common/UDPSocket.cpp
@@ -27,7 +27,7 @@ namespace {
const int kDomain = AF_INET;
const int kType = SOCK_DGRAM;
-const Error kNotSupported("Not supported");
+static const char *g_not_supported_error = "Not supported";
}
@@ -55,19 +55,19 @@ UDPSocket::Send(const void *buf, const size_t num_bytes)
Error
UDPSocket::Connect(llvm::StringRef name)
{
- return kNotSupported;
+ return Error("%s", g_not_supported_error);
}
Error
UDPSocket::Listen(llvm::StringRef name, int backlog)
{
- return kNotSupported;
+ return Error("%s", g_not_supported_error);
}
Error
UDPSocket::Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
{
- return kNotSupported;
+ return Error("%s", g_not_supported_error);
}
Error
diff --git a/source/Host/linux/Host.cpp b/source/Host/linux/Host.cpp
index cb7369fe7aec..62bf5362de01 100644
--- a/source/Host/linux/Host.cpp
+++ b/source/Host/linux/Host.cpp
@@ -8,12 +8,14 @@
//===----------------------------------------------------------------------===//
// C Includes
-#include <stdio.h>
-#include <sys/utsname.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#include <dirent.h>
+#include <errno.h>
#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
// C++ Includes
// Other libraries and framework includes
@@ -291,15 +293,25 @@ GetProcessAndStatInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info, Proce
::memset (&stat_info, 0, sizeof(stat_info));
stat_info.ppid = LLDB_INVALID_PROCESS_ID;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
// Use special code here because proc/[pid]/exe is a symbolic link.
char link_path[PATH_MAX];
char exe_path[PATH_MAX] = "";
if (snprintf (link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", pid) <= 0)
+ {
+ if (log)
+ log->Printf("%s: failed to sprintf pid %" PRIu64, __FUNCTION__, pid);
return false;
+ }
ssize_t len = readlink (link_path, exe_path, sizeof(exe_path) - 1);
if (len <= 0)
+ {
+ if (log)
+ log->Printf("%s: failed to read link %s: %s", __FUNCTION__, link_path, strerror(errno));
return false;
+ }
// readlink does not append a null byte.
exe_path[len] = 0;
diff --git a/source/Host/linux/HostInfoLinux.cpp b/source/Host/linux/HostInfoLinux.cpp
index 4732a2a571b6..0d0ba3323d6c 100644
--- a/source/Host/linux/HostInfoLinux.cpp
+++ b/source/Host/linux/HostInfoLinux.cpp
@@ -235,7 +235,7 @@ HostInfoLinux::ComputeSupportExeDirectory(FileSpec &file_spec)
bool
HostInfoLinux::ComputeSystemPluginsDirectory(FileSpec &file_spec)
{
- FileSpec temp_file("/usr/lib/lldb", true);
+ FileSpec temp_file("/usr/lib/lldb/plugins", true);
file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
return true;
}
diff --git a/source/Host/macosx/Host.mm b/source/Host/macosx/Host.mm
index 2db27a276e4a..8bd2e2f2b257 100644
--- a/source/Host/macosx/Host.mm
+++ b/source/Host/macosx/Host.mm
@@ -556,10 +556,10 @@ LaunchInNewTerminalWithAppleScript (const char *exe_path, ProcessLaunchInfo &lau
// On MacOSX CrashReporter will display a string for each shared library if
// the shared library has an exported symbol named "__crashreporter_info__".
-static Mutex&
-GetCrashReporterMutex ()
+static std::mutex &
+GetCrashReporterMutex()
{
- static Mutex g_mutex;
+ static std::mutex g_mutex;
return g_mutex;
}
@@ -573,8 +573,8 @@ void
Host::SetCrashDescriptionWithFormat (const char *format, ...)
{
static StreamString g_crash_description;
- Mutex::Locker locker (GetCrashReporterMutex ());
-
+ std::lock_guard<std::mutex> guard(GetCrashReporterMutex());
+
if (format)
{
va_list args;
@@ -593,7 +593,7 @@ Host::SetCrashDescriptionWithFormat (const char *format, ...)
void
Host::SetCrashDescription (const char *cstr)
{
- Mutex::Locker locker (GetCrashReporterMutex ());
+ std::lock_guard<std::mutex> guard(GetCrashReporterMutex());
static std::string g_crash_description;
if (cstr)
{
@@ -1334,7 +1334,6 @@ Host::LaunchProcess (ProcessLaunchInfo &launch_info)
callback = Process::SetProcessExitStatus;
StartMonitoringChildProcess (callback,
- NULL,
pid,
monitor_signals);
}
@@ -1449,7 +1448,8 @@ Host::ShellExpandArguments (ProcessLaunchInfo &launch_info)
}
HostThread
-Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals)
+Host::StartMonitoringChildProcess(const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid,
+ bool monitor_signals)
{
unsigned long mask = DISPATCH_PROC_EXIT;
if (monitor_signals)
@@ -1458,26 +1458,25 @@ Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, vo
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
- dispatch_source_t source = ::dispatch_source_create (DISPATCH_SOURCE_TYPE_PROC,
- pid,
- mask,
+ dispatch_source_t source = ::dispatch_source_create (DISPATCH_SOURCE_TYPE_PROC,
+ pid,
+ mask,
::dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT,0));
if (log)
- log->Printf ("Host::StartMonitoringChildProcess (callback=%p, baton=%p, pid=%i, monitor_signals=%i) source = %p\n",
- callback,
- callback_baton,
- (int)pid,
- monitor_signals,
- source);
+ log->Printf("Host::StartMonitoringChildProcess "
+ "(callback, pid=%i, monitor_signals=%i) "
+ "source = %p\n",
+ static_cast<int>(pid), monitor_signals, reinterpret_cast<void *>(source));
if (source)
{
+ Host::MonitorChildProcessCallback callback_copy = callback;
::dispatch_source_set_cancel_handler (source, ^{
::dispatch_release (source);
});
::dispatch_source_set_event_handler (source, ^{
-
+
int status= 0;
int wait_pid = 0;
bool cancel = false;
@@ -1523,10 +1522,10 @@ Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, vo
status_cstr,
signal,
exit_status);
-
- if (callback)
- cancel = callback (callback_baton, pid, exited, signal, exit_status);
-
+
+ if (callback_copy)
+ cancel = callback_copy(pid, exited, signal, exit_status);
+
if (exited || cancel)
{
::dispatch_source_cancel(source);
diff --git a/source/Host/macosx/HostInfoMacOSX.mm b/source/Host/macosx/HostInfoMacOSX.mm
index f5a0540e8774..8b664f0a44bd 100644
--- a/source/Host/macosx/HostInfoMacOSX.mm
+++ b/source/Host/macosx/HostInfoMacOSX.mm
@@ -370,3 +370,9 @@ HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch
}
}
}
+
+uint32_t
+HostInfoMacOSX::GetMaxThreadNameLength()
+{
+ return 64;
+}
diff --git a/source/Host/macosx/ThisThread.cpp b/source/Host/macosx/ThisThread.cpp
index 95c7f2bf1e38..6f1c88f67309 100644
--- a/source/Host/macosx/ThisThread.cpp
+++ b/source/Host/macosx/ThisThread.cpp
@@ -10,30 +10,20 @@
#include "lldb/Host/ThisThread.h"
#include <pthread.h>
+#include "llvm/ADT/SmallVector.h"
using namespace lldb_private;
void
ThisThread::SetName(llvm::StringRef name)
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
- ::pthread_setname_np(name);
+#if defined (__APPLE__)
+ ::pthread_setname_np(name.str().c_str());
#endif
}
void
ThisThread::GetName(llvm::SmallVectorImpl<char> &name)
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
- char pthread_name[1024];
- dispatch_queue_t current_queue = ::dispatch_get_current_queue();
- if (current_queue != NULL)
- {
- const char *queue_name = dispatch_queue_get_label(current_queue);
- if (queue_name && queue_name[0])
- {
- name = queue_name;
- }
- }
-#endif
+ // FIXME - implement this.
}
diff --git a/source/Host/netbsd/Makefile b/source/Host/netbsd/Makefile
deleted file mode 100644
index 2502cc49c15b..000000000000
--- a/source/Host/netbsd/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Host/netbsd/Makefile --------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../..
-LIBRARYNAME := lldbHostNetBSD
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
index dbbd5a1dcc3c..52d65b1e9a97 100644
--- a/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -79,12 +79,12 @@ GetURLAddress(const char *url, const char *scheme)
}
ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit)
- : Connection()
- , m_pipe()
- , m_mutex(Mutex::eMutexTypeRecursive)
- , m_shutting_down(false)
- , m_waiting_for_accept(false)
- , m_child_processes_inherit(child_processes_inherit)
+ : Connection(),
+ m_pipe(),
+ m_mutex(),
+ m_shutting_down(false),
+ m_waiting_for_accept(false),
+ m_child_processes_inherit(child_processes_inherit)
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
if (log)
@@ -92,30 +92,30 @@ ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit)
}
ConnectionFileDescriptor::ConnectionFileDescriptor(int fd, bool owns_fd)
- : Connection()
- , m_pipe()
- , m_mutex(Mutex::eMutexTypeRecursive)
- , m_shutting_down(false)
- , m_waiting_for_accept(false)
- , m_child_processes_inherit(false)
+ : Connection(),
+ m_pipe(),
+ m_mutex(),
+ m_shutting_down(false),
+ m_waiting_for_accept(false),
+ m_child_processes_inherit(false)
{
m_write_sp.reset(new File(fd, owns_fd));
m_read_sp.reset(new File(fd, false));
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
if (log)
- log->Printf("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)", static_cast<void *>(this), fd,
- owns_fd);
+ log->Printf("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)",
+ static_cast<void *>(this), fd, owns_fd);
OpenCommandPipe();
}
-ConnectionFileDescriptor::ConnectionFileDescriptor(Socket* socket)
- : Connection()
- , m_pipe()
- , m_mutex(Mutex::eMutexTypeRecursive)
- , m_shutting_down(false)
- , m_waiting_for_accept(false)
- , m_child_processes_inherit(false)
+ConnectionFileDescriptor::ConnectionFileDescriptor(Socket *socket)
+ : Connection(),
+ m_pipe(),
+ m_mutex(),
+ m_shutting_down(false),
+ m_waiting_for_accept(false),
+ m_child_processes_inherit(false)
{
InitializeSocket(socket);
}
@@ -170,7 +170,7 @@ ConnectionFileDescriptor::IsConnected() const
ConnectionStatus
ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
if (log)
log->Printf("%p ConnectionFileDescriptor::Connect (url = '%s')", static_cast<void *>(this), s);
@@ -374,10 +374,8 @@ ConnectionFileDescriptor::Disconnect(Error *error_ptr)
m_shutting_down = true;
- Mutex::Locker locker;
- bool got_lock = locker.TryLock(m_mutex);
-
- if (!got_lock)
+ std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock);
+ if (!locker.try_lock())
{
if (m_pipe.CanWrite())
{
@@ -392,7 +390,7 @@ ConnectionFileDescriptor::Disconnect(Error *error_ptr)
log->Printf("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, but no command pipe is available.",
static_cast<void *>(this));
}
- locker.Lock(m_mutex);
+ locker.lock();
}
Error error = m_read_sp->Close();
@@ -415,9 +413,8 @@ ConnectionFileDescriptor::Read(void *dst, size_t dst_len, uint32_t timeout_usec,
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- Mutex::Locker locker;
- bool got_lock = locker.TryLock(m_mutex);
- if (!got_lock)
+ std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock);
+ if (!locker.try_lock())
{
if (log)
log->Printf("%p ConnectionFileDescriptor::Read () failed to get the connection lock.", static_cast<void *>(this));
diff --git a/source/Host/posix/DomainSocket.cpp b/source/Host/posix/DomainSocket.cpp
index b4427e305f3e..9dc147196c08 100644
--- a/source/Host/posix/DomainSocket.cpp
+++ b/source/Host/posix/DomainSocket.cpp
@@ -21,7 +21,7 @@ using namespace lldb_private;
#ifdef __ANDROID__
// Android does not have SUN_LEN
#ifndef SUN_LEN
-#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path))
+#define SUN_LEN(ptr) (offsetof(struct sockaddr_un, sun_path) + strlen((ptr)->sun_path))
#endif
#endif // #ifdef __ANDROID__
diff --git a/source/Host/posix/FileSystem.cpp b/source/Host/posix/FileSystem.cpp
index 1f2e7db0e1e4..c8fa1bc9cf47 100644
--- a/source/Host/posix/FileSystem.cpp
+++ b/source/Host/posix/FileSystem.cpp
@@ -54,30 +54,32 @@ FileSystem::MakeDirectory(const FileSpec &file_spec, uint32_t file_permissions)
switch (error.GetError())
{
case ENOENT:
- {
- // Parent directory doesn't exist, so lets make it if we can
- // Make the parent directory and try again
- FileSpec parent_file_spec{file_spec.GetDirectory().GetCString(), false};
- error = MakeDirectory(parent_file_spec, file_permissions);
- if (error.Fail())
- return error;
- // Try and make the directory again now that the parent directory was made successfully
- if (::mkdir(file_spec.GetCString(), file_permissions) == -1)
{
- error.SetErrorToErrno();
+ // Parent directory doesn't exist, so lets make it if we can
+ // Make the parent directory and try again
+ FileSpec parent_file_spec{file_spec.GetDirectory().GetCString(), false};
+ error = MakeDirectory(parent_file_spec, file_permissions);
+ if (error.Fail())
+ return error;
+ // Try and make the directory again now that the parent directory was made successfully
+ if (::mkdir(file_spec.GetCString(), file_permissions) == -1)
+ {
+ error.SetErrorToErrno();
+ }
return error;
}
- }
+ break;
case EEXIST:
- {
- if (file_spec.IsDirectory())
- return Error{}; // It is a directory and it already exists
- }
+ {
+ if (file_spec.IsDirectory())
+ return Error(); // It is a directory and it already exists
+ }
+ break;
}
}
return error;
}
- return Error{"empty path"};
+ return Error("empty path");
}
Error
@@ -297,3 +299,15 @@ FileSystem::IsLocal(const FileSpec &spec)
return false;
}
#endif
+
+FILE *
+FileSystem::Fopen(const char *path, const char *mode)
+{
+ return ::fopen(path, mode);
+}
+
+int
+FileSystem::Stat(const char *path, struct stat *stats)
+{
+ return ::stat(path, stats);
+}
diff --git a/source/Host/posix/HostInfoPosix.cpp b/source/Host/posix/HostInfoPosix.cpp
index cfdbf5635ad1..d0ef2ca37061 100644
--- a/source/Host/posix/HostInfoPosix.cpp
+++ b/source/Host/posix/HostInfoPosix.cpp
@@ -242,3 +242,14 @@ HostInfoPosix::ComputePythonDirectory(FileSpec &file_spec)
return false;
#endif
}
+
+bool
+HostInfoPosix::GetEnvironmentVar(const std::string &var_name, std::string &var)
+{
+ if (const char *pvar = ::getenv(var_name.c_str()))
+ {
+ var = std::string(pvar);
+ return true;
+ }
+ return false;
+}
diff --git a/source/Host/posix/HostProcessPosix.cpp b/source/Host/posix/HostProcessPosix.cpp
index 5761a79da27f..93844d9b99d3 100644
--- a/source/Host/posix/HostProcessPosix.cpp
+++ b/source/Host/posix/HostProcessPosix.cpp
@@ -107,7 +107,7 @@ bool HostProcessPosix::IsRunning() const
}
HostThread
-HostProcessPosix::StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals)
+HostProcessPosix::StartMonitoring(const Host::MonitorChildProcessCallback &callback, bool monitor_signals)
{
- return Host::StartMonitoringChildProcess(callback, callback_baton, m_process, monitor_signals);
+ return Host::StartMonitoringChildProcess(callback, m_process, monitor_signals);
}
diff --git a/source/Host/posix/HostThreadPosix.cpp b/source/Host/posix/HostThreadPosix.cpp
index 9c4892431938..f1a6d6f83142 100644
--- a/source/Host/posix/HostThreadPosix.cpp
+++ b/source/Host/posix/HostThreadPosix.cpp
@@ -53,13 +53,18 @@ Error
HostThreadPosix::Cancel()
{
Error error;
+ if (IsJoinable())
+ {
#ifndef __ANDROID__
- int err = ::pthread_cancel(m_thread);
- error.SetError(err, eErrorTypePOSIX);
+#ifndef __FreeBSD__
+ assert(false && "someone is calling HostThread::Cancel()");
+#endif
+ int err = ::pthread_cancel(m_thread);
+ error.SetError(err, eErrorTypePOSIX);
#else
- error.SetErrorString("HostThreadPosix::Cancel() not supported on Android");
+ error.SetErrorString("HostThreadPosix::Cancel() not supported on Android");
#endif
-
+ }
return error;
}
@@ -67,8 +72,11 @@ Error
HostThreadPosix::Detach()
{
Error error;
- int err = ::pthread_detach(m_thread);
- error.SetError(err, eErrorTypePOSIX);
+ if (IsJoinable())
+ {
+ int err = ::pthread_detach(m_thread);
+ error.SetError(err, eErrorTypePOSIX);
+ }
Reset();
return error;
}
diff --git a/source/Host/windows/ConnectionGenericFileWindows.cpp b/source/Host/windows/ConnectionGenericFileWindows.cpp
index eebf3d4f633c..9743ed48b8ef 100644
--- a/source/Host/windows/ConnectionGenericFileWindows.cpp
+++ b/source/Host/windows/ConnectionGenericFileWindows.cpp
@@ -14,6 +14,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ConvertUTF.h"
using namespace lldb;
using namespace lldb_private;
@@ -138,7 +139,15 @@ ConnectionGenericFile::Connect(const char *s, Error *error_ptr)
// Open the file for overlapped access. If it does not exist, create it. We open it overlapped
// so that we can issue asynchronous reads and then use WaitForMultipleObjects to allow the read
// to be interrupted by an event object.
- m_file = ::CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
+ std::wstring wpath;
+ if (!llvm::ConvertUTF8toWide(path, wpath))
+ {
+ if (error_ptr)
+ error_ptr->SetError(1, eErrorTypeGeneric);
+ return eConnectionStatusError;
+ }
+ m_file = ::CreateFileW(wpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS,
+ FILE_FLAG_OVERLAPPED, NULL);
if (m_file == INVALID_HANDLE_VALUE)
{
if (error_ptr)
diff --git a/source/Host/windows/FileSystem.cpp b/source/Host/windows/FileSystem.cpp
index 2cca12b92711..3e881f5d9b2b 100644
--- a/source/Host/windows/FileSystem.cpp
+++ b/source/Host/windows/FileSystem.cpp
@@ -15,6 +15,8 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/windows/AutoHandle.h"
+
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
using namespace lldb_private;
@@ -22,6 +24,8 @@ using namespace lldb_private;
const char *
FileSystem::DEV_NULL = "nul";
+const char *FileSystem::PATH_CONVERSION_ERROR = "Error converting path between UTF-8 and native encoding";
+
FileSpec::PathSyntax
FileSystem::GetNativePathSyntax()
{
@@ -47,25 +51,32 @@ Error
FileSystem::DeleteDirectory(const FileSpec &file_spec, bool recurse)
{
Error error;
+ std::wstring path_buffer;
+ if (!llvm::ConvertUTF8toWide(file_spec.GetPath(), path_buffer))
+ {
+ error.SetErrorString(PATH_CONVERSION_ERROR);
+ return error;
+ }
if (!recurse)
{
- BOOL result = ::RemoveDirectory(file_spec.GetCString());
+ BOOL result = ::RemoveDirectoryW(path_buffer.c_str());
if (!result)
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
}
else
{
// SHFileOperation() accepts a list of paths, and so must be double-null-terminated to
- // indicate the end of the list.
- std::string path_buffer{file_spec.GetPath()};
+ // indicate the end of the list. The first null terminator is there only in the backing
+ // store but not the actual vector contents, and so we need to push twice.
+ path_buffer.push_back(0);
path_buffer.push_back(0);
- SHFILEOPSTRUCT shfos = {0};
+ SHFILEOPSTRUCTW shfos = {0};
shfos.wFunc = FO_DELETE;
- shfos.pFrom = path_buffer.c_str();
+ shfos.pFrom = (LPCWSTR)path_buffer.data();
shfos.fFlags = FOF_NO_UI;
- int result = ::SHFileOperation(&shfos);
+ int result = ::SHFileOperationW(&shfos);
// TODO(zturner): Correctly handle the intricacies of SHFileOperation return values.
if (result != 0)
error.SetErrorStringWithFormat("SHFileOperation failed");
@@ -121,7 +132,10 @@ Error
FileSystem::Hardlink(const FileSpec &src, const FileSpec &dst)
{
Error error;
- if (!::CreateHardLink(src.GetCString(), dst.GetCString(), nullptr))
+ std::wstring wsrc, wdst;
+ if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) || !llvm::ConvertUTF8toWide(dst.GetCString(), wdst))
+ error.SetErrorString(PATH_CONVERSION_ERROR);
+ else if (!::CreateHardLinkW(wsrc.c_str(), wdst.c_str(), nullptr))
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
}
@@ -129,13 +143,12 @@ FileSystem::Hardlink(const FileSpec &src, const FileSpec &dst)
int
FileSystem::GetHardlinkCount(const FileSpec &file_spec)
{
- HANDLE file_handle = ::CreateFile(file_spec.GetCString(),
- FILE_READ_ATTRIBUTES,
- FILE_SHARE_READ,
- nullptr,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- nullptr);
+ std::wstring path;
+ if (!llvm::ConvertUTF8toWide(file_spec.GetCString(), path))
+ return -1;
+
+ HANDLE file_handle = ::CreateFileW(path.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, nullptr);
if (file_handle == INVALID_HANDLE_VALUE)
return -1;
@@ -152,7 +165,12 @@ Error
FileSystem::Symlink(const FileSpec &src, const FileSpec &dst)
{
Error error;
- DWORD attrib = ::GetFileAttributes(dst.GetCString());
+ std::wstring wsrc, wdst;
+ if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) || !llvm::ConvertUTF8toWide(dst.GetCString(), wdst))
+ error.SetErrorString(PATH_CONVERSION_ERROR);
+ if (error.Fail())
+ return error;
+ DWORD attrib = ::GetFileAttributesW(wdst.c_str());
if (attrib == INVALID_FILE_ATTRIBUTES)
{
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
@@ -160,7 +178,7 @@ FileSystem::Symlink(const FileSpec &src, const FileSpec &dst)
}
bool is_directory = !!(attrib & FILE_ATTRIBUTE_DIRECTORY);
DWORD flag = is_directory ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
- BOOL result = ::CreateSymbolicLink(src.GetCString(), dst.GetCString(), flag);
+ BOOL result = ::CreateSymbolicLinkW(wsrc.c_str(), wdst.c_str(), flag);
if (!result)
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
@@ -170,7 +188,13 @@ Error
FileSystem::Unlink(const FileSpec &file_spec)
{
Error error;
- BOOL result = ::DeleteFile(file_spec.GetCString());
+ std::wstring path;
+ if (!llvm::ConvertUTF8toWide(file_spec.GetCString(), path))
+ {
+ error.SetErrorString(PATH_CONVERSION_ERROR);
+ return error;
+ }
+ BOOL result = ::DeleteFileW(path.c_str());
if (!result)
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
@@ -180,23 +204,31 @@ Error
FileSystem::Readlink(const FileSpec &src, FileSpec &dst)
{
Error error;
- HANDLE h = ::CreateFile(src.GetCString(), GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_OPEN_REPARSE_POINT, NULL);
+ std::wstring wsrc;
+ if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc))
+ {
+ error.SetErrorString(PATH_CONVERSION_ERROR);
+ return error;
+ }
+
+ HANDLE h = ::CreateFileW(wsrc.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT, NULL);
if (h == INVALID_HANDLE_VALUE)
{
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
}
- char buf[PATH_MAX];
+ std::vector<wchar_t> buf(PATH_MAX + 1);
// Subtract 1 from the path length since this function does not add a null terminator.
- DWORD result = ::GetFinalPathNameByHandle(h, buf, sizeof(buf) - 1,
- FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ DWORD result = ::GetFinalPathNameByHandleW(h, buf.data(), buf.size() - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ std::string path;
if (result == 0)
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
+ else if (!llvm::convertWideToUTF8(buf.data(), path))
+ error.SetErrorString(PATH_CONVERSION_ERROR);
else
- dst.SetFile(buf, false);
+ dst.SetFile(path, false);
::CloseHandle(h);
return error;
@@ -219,3 +251,43 @@ FileSystem::IsLocal(const FileSpec &spec)
return false;
}
+
+FILE *
+FileSystem::Fopen(const char *path, const char *mode)
+{
+ std::wstring wpath, wmode;
+ if (!llvm::ConvertUTF8toWide(path, wpath))
+ return nullptr;
+ if (!llvm::ConvertUTF8toWide(mode, wmode))
+ return nullptr;
+ FILE *file;
+ if (_wfopen_s(&file, wpath.c_str(), wmode.c_str()) != 0)
+ return nullptr;
+ return file;
+}
+
+int
+FileSystem::Stat(const char *path, struct stat *stats)
+{
+ std::wstring wpath;
+ if (!llvm::ConvertUTF8toWide(path, wpath))
+ {
+ errno = EINVAL;
+ return -EINVAL;
+ }
+ int stat_result;
+#ifdef _USE_32BIT_TIME_T
+ struct _stat32 file_stats;
+ stat_result = ::_wstat32(wpath.c_str(), &file_stats);
+#else
+ struct _stat64i32 file_stats;
+ stat_result = ::_wstat64i32(wpath.c_str(), &file_stats);
+#endif
+ if (stat_result == 0)
+ {
+ static_assert(sizeof(struct stat) == sizeof(file_stats),
+ "stat and _stat32/_stat64i32 must have the same layout");
+ *stats = *reinterpret_cast<struct stat *>(&file_stats);
+ }
+ return stat_result;
+}
diff --git a/source/Host/windows/Host.cpp b/source/Host/windows/Host.cpp
index 2c9a139df256..1b4eeb8d4f60 100644
--- a/source/Host/windows/Host.cpp
+++ b/source/Host/windows/Host.cpp
@@ -26,6 +26,8 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StructuredData.h"
+#include "llvm/Support/ConvertUTF.h"
+
// Windows includes
#include <TlHelp32.h>
@@ -68,12 +70,11 @@ namespace
bool GetExecutableForProcess(const AutoHandle &handle, std::string &path)
{
// Get the process image path. MAX_PATH isn't long enough, paths can actually be up to 32KB.
- std::vector<char> buffer(32768);
+ std::vector<wchar_t> buffer(PATH_MAX);
DWORD dwSize = buffer.size();
- if (!::QueryFullProcessImageNameA(handle.get(), 0, &buffer[0], &dwSize))
+ if (!::QueryFullProcessImageNameW(handle.get(), 0, &buffer[0], &dwSize))
return false;
- path.assign(&buffer[0]);
- return true;
+ return llvm::convertWideToUTF8(buffer.data(), path);
}
void GetProcessExecutableAndTriple(const AutoHandle &handle, ProcessInstanceInfo &process)
@@ -156,15 +157,17 @@ Host::GetModuleFileSpecForHostAddress (const void *host_addr)
if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)host_addr, &hmodule))
return module_filespec;
- std::vector<char> buffer(MAX_PATH);
+ std::vector<wchar_t> buffer(PATH_MAX);
DWORD chars_copied = 0;
do {
- chars_copied = ::GetModuleFileName(hmodule, &buffer[0], buffer.size());
+ chars_copied = ::GetModuleFileNameW(hmodule, &buffer[0], buffer.size());
if (chars_copied == buffer.size() && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
buffer.resize(buffer.size() * 2);
} while (chars_copied >= buffer.size());
-
- module_filespec.SetFile(&buffer[0], false);
+ std::string path;
+ if (!llvm::convertWideToUTF8(buffer.data(), path))
+ return module_filespec;
+ module_filespec.SetFile(path, false);
return module_filespec;
}
@@ -177,23 +180,25 @@ Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstance
if (!snapshot.IsValid())
return 0;
- PROCESSENTRY32 pe = {0};
- pe.dwSize = sizeof(PROCESSENTRY32);
- if (Process32First(snapshot.get(), &pe))
+ PROCESSENTRY32W pe = {0};
+ pe.dwSize = sizeof(PROCESSENTRY32W);
+ if (Process32FirstW(snapshot.get(), &pe))
{
do
{
AutoHandle handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pe.th32ProcessID), nullptr);
ProcessInstanceInfo process;
- process.SetExecutableFile(FileSpec(pe.szExeFile, false), true);
+ std::string exeFile;
+ llvm::convertWideToUTF8(pe.szExeFile, exeFile);
+ process.SetExecutableFile(FileSpec(exeFile, false), true);
process.SetProcessID(pe.th32ProcessID);
process.SetParentProcessID(pe.th32ParentProcessID);
GetProcessExecutableAndTriple(handle, process);
if (match_info.MatchAllProcesses() || match_info.Matches(process))
process_infos.Append(process);
- } while (Process32Next(snapshot.get(), &pe));
+ } while (Process32NextW(snapshot.get(), &pe));
}
return process_infos.GetSize();
}
@@ -216,7 +221,8 @@ Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
}
HostThread
-Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals)
+Host::StartMonitoringChildProcess(const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid,
+ bool monitor_signals)
{
return HostThread();
}
@@ -312,15 +318,21 @@ Host::GetEnvironment(StringList &env)
{
// The environment block on Windows is a contiguous buffer of NULL terminated strings,
// where the end of the environment block is indicated by two consecutive NULLs.
- LPCH environment_block = ::GetEnvironmentStrings();
+ LPWCH environment_block = ::GetEnvironmentStringsW();
env.Clear();
- while (*environment_block != '\0')
+ while (*environment_block != L'\0')
{
- llvm::StringRef current_var(environment_block);
+ std::string current_var;
+ auto current_var_size = wcslen(environment_block) + 1;
+ if (!llvm::convertWideToUTF8(environment_block, current_var))
+ {
+ environment_block += current_var_size;
+ continue;
+ }
if (current_var[0] != '=')
env.AppendString(current_var);
- environment_block += current_var.size()+1;
+ environment_block += current_var_size;
}
return env.GetSize();
}
diff --git a/source/Host/windows/HostInfoWindows.cpp b/source/Host/windows/HostInfoWindows.cpp
index 6dce71d9172a..6b2190294081 100644
--- a/source/Host/windows/HostInfoWindows.cpp
+++ b/source/Host/windows/HostInfoWindows.cpp
@@ -9,18 +9,35 @@
#include "lldb/Host/windows/windows.h"
+#include <objbase.h>
+
#include <mutex> // std::once
#include "lldb/Host/windows/HostInfoWindows.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
using namespace lldb_private;
FileSpec HostInfoWindows::m_program_filespec;
+void
+HostInfoWindows::Initialize()
+{
+ ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
+ HostInfoBase::Initialize();
+}
+
+void
+HostInfoWindows::Terminate()
+{
+ HostInfoBase::Terminate();
+ ::CoUninitialize();
+}
+
size_t
HostInfoWindows::GetPageSize()
{
@@ -76,23 +93,24 @@ HostInfoWindows::GetOSKernelDescription(std::string &s)
bool
HostInfoWindows::GetHostname(std::string &s)
{
- char buffer[MAX_COMPUTERNAME_LENGTH + 1];
+ wchar_t buffer[MAX_COMPUTERNAME_LENGTH + 1];
DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
- if (!::GetComputerName(buffer, &dwSize))
+ if (!::GetComputerNameW(buffer, &dwSize))
return false;
- s.assign(buffer, buffer + dwSize);
- return true;
+ return llvm::convertWideToUTF8(buffer, s);
}
FileSpec
HostInfoWindows::GetProgramFileSpec()
{
static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
- char buffer[PATH_MAX];
- ::GetModuleFileName(NULL, buffer, sizeof(buffer));
- m_program_filespec.SetFile(buffer, false);
+ std::call_once(g_once_flag, []() {
+ std::vector<wchar_t> buffer(PATH_MAX);
+ ::GetModuleFileNameW(NULL, buffer.data(), buffer.size());
+ std::string path;
+ llvm::convertWideToUTF8(buffer.data(), path);
+ m_program_filespec.SetFile(path, false);
});
return m_program_filespec;
}
@@ -100,7 +118,9 @@ HostInfoWindows::GetProgramFileSpec()
FileSpec
HostInfoWindows::GetDefaultShell()
{
- return FileSpec(::getenv("ComSpec"), false);
+ std::string shell;
+ GetEnvironmentVar("ComSpec", shell);
+ return FileSpec(shell, false);
}
bool
@@ -116,3 +136,15 @@ HostInfoWindows::ComputePythonDirectory(FileSpec &file_spec)
file_spec.GetDirectory().SetString(path.c_str());
return true;
}
+
+bool
+HostInfoWindows::GetEnvironmentVar(const std::string &var_name, std::string &var)
+{
+ std::wstring wvar_name;
+ if (!llvm::ConvertUTF8toWide(var_name, wvar_name))
+ return false;
+
+ if (const wchar_t *wvar = _wgetenv(wvar_name.c_str()))
+ return llvm::convertWideToUTF8(wvar, var);
+ return false;
+}
diff --git a/source/Host/windows/HostProcessWindows.cpp b/source/Host/windows/HostProcessWindows.cpp
index 0f81c18d34af..2878171cbe77 100644
--- a/source/Host/windows/HostProcessWindows.cpp
+++ b/source/Host/windows/HostProcessWindows.cpp
@@ -14,6 +14,7 @@
#include "lldb/Host/windows/HostProcessWindows.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ConvertUTF.h"
#include <Psapi.h>
@@ -23,8 +24,7 @@ namespace
{
struct MonitorInfo
{
- HostProcess::MonitorCallback callback;
- void *baton;
+ Host::MonitorChildProcessCallback callback;
HANDLE process_handle;
};
}
@@ -70,9 +70,15 @@ Error HostProcessWindows::GetMainModule(FileSpec &file_spec) const
if (m_process == nullptr)
error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);
- char path[MAX_PATH] = { 0 };
- if (::GetProcessImageFileName(m_process, path, llvm::array_lengthof(path)))
- file_spec.SetFile(path, false);
+ std::vector<wchar_t> wpath(PATH_MAX);
+ if (::GetProcessImageFileNameW(m_process, wpath.data(), wpath.size()))
+ {
+ std::string path;
+ if (llvm::convertWideToUTF8(wpath.data(), path))
+ file_spec.SetFile(path, false);
+ else
+ error.SetErrorString("Error converting path to UTF-8");
+ }
else
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
@@ -97,12 +103,11 @@ bool HostProcessWindows::IsRunning() const
}
HostThread
-HostProcessWindows::StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals)
+HostProcessWindows::StartMonitoring(const Host::MonitorChildProcessCallback &callback, bool monitor_signals)
{
HostThread monitor_thread;
MonitorInfo *info = new MonitorInfo;
info->callback = callback;
- info->baton = callback_baton;
// Since the life of this HostProcessWindows instance and the life of the process may be different, duplicate the handle so that
// the monitor thread can have ownership over its own copy of the handle.
@@ -122,7 +127,7 @@ HostProcessWindows::MonitorThread(void *thread_arg)
{
::WaitForSingleObject(info->process_handle, INFINITE);
::GetExitCodeProcess(info->process_handle, &exit_code);
- info->callback(info->baton, ::GetProcessId(info->process_handle), true, 0, exit_code);
+ info->callback(::GetProcessId(info->process_handle), true, 0, exit_code);
::CloseHandle(info->process_handle);
delete (info);
}
diff --git a/source/Host/windows/PipeWindows.cpp b/source/Host/windows/PipeWindows.cpp
index d4afd6e74943..6ed8d0e83f3c 100644
--- a/source/Host/windows/PipeWindows.cpp
+++ b/source/Host/windows/PipeWindows.cpp
@@ -73,8 +73,8 @@ PipeWindows::CreateNew(llvm::StringRef name, bool child_process_inherit)
// Always open for overlapped i/o. We implement blocking manually in Read and Write.
DWORD read_mode = FILE_FLAG_OVERLAPPED;
- m_read =
- ::CreateNamedPipe(pipe_path.c_str(), PIPE_ACCESS_INBOUND | read_mode, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);
+ m_read = ::CreateNamedPipeA(pipe_path.c_str(), PIPE_ACCESS_INBOUND | read_mode, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 1024,
+ 1024, 120 * 1000, NULL);
if (INVALID_HANDLE_VALUE == m_read)
return Error(::GetLastError(), eErrorTypeWin32);
m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
@@ -153,7 +153,8 @@ PipeWindows::OpenNamedPipe(llvm::StringRef name, bool child_process_inherit, boo
if (is_read)
{
- m_read = ::CreateFile(pipe_path.c_str(), GENERIC_READ, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+ m_read =
+ ::CreateFileA(pipe_path.c_str(), GENERIC_READ, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (INVALID_HANDLE_VALUE == m_read)
return Error(::GetLastError(), eErrorTypeWin32);
@@ -164,7 +165,8 @@ PipeWindows::OpenNamedPipe(llvm::StringRef name, bool child_process_inherit, boo
}
else
{
- m_write = ::CreateFile(pipe_path.c_str(), GENERIC_WRITE, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+ m_write =
+ ::CreateFileA(pipe_path.c_str(), GENERIC_WRITE, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (INVALID_HANDLE_VALUE == m_write)
return Error(::GetLastError(), eErrorTypeWin32);
diff --git a/source/Host/windows/ProcessLauncherWindows.cpp b/source/Host/windows/ProcessLauncherWindows.cpp
index 355dd40544f9..caf0fc71e121 100644
--- a/source/Host/windows/ProcessLauncherWindows.cpp
+++ b/source/Host/windows/ProcessLauncherWindows.cpp
@@ -11,12 +11,38 @@
#include "lldb/Host/windows/ProcessLauncherWindows.h"
#include "lldb/Target/ProcessLaunchInfo.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/ConvertUTF.h"
+
#include <string>
#include <vector>
using namespace lldb;
using namespace lldb_private;
+namespace
+{
+void
+CreateEnvironmentBuffer(const Args &env, std::vector<char> &buffer)
+{
+ if (env.GetArgumentCount() == 0)
+ return;
+
+ // Environment buffer is a null terminated list of null terminated strings
+ for (int i = 0; i < env.GetArgumentCount(); ++i)
+ {
+ std::wstring warg;
+ if (llvm::ConvertUTF8toWide(env.GetArgumentAtIndex(i), warg))
+ {
+ buffer.insert(buffer.end(), (char *)warg.c_str(), (char *)(warg.c_str() + warg.size() + 1));
+ }
+ }
+ // One null wchar_t (to end the block) is two null bytes
+ buffer.push_back(0);
+ buffer.push_back(0);
+}
+}
+
HostProcess
ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error)
{
@@ -45,14 +71,27 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info, Erro
startupinfo.wShowWindow = SW_HIDE;
}
- DWORD flags = CREATE_NEW_CONSOLE;
+ DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
if (launch_info.GetFlags().Test(eLaunchFlagDebug))
flags |= DEBUG_ONLY_THIS_PROCESS;
+ auto &env = const_cast<Args &>(launch_info.GetEnvironmentEntries());
+ LPVOID env_block = nullptr;
+ ::CreateEnvironmentBuffer(env, environment);
+ if (!environment.empty())
+ env_block = environment.data();
+
executable = launch_info.GetExecutableFile().GetPath();
launch_info.GetArguments().GetQuotedCommandString(commandLine);
- BOOL result = ::CreateProcessA(executable.c_str(), const_cast<char *>(commandLine.c_str()), NULL, NULL, TRUE, flags, NULL,
- launch_info.GetWorkingDirectory().GetCString(), &startupinfo, &pi);
+
+ std::wstring wexecutable, wcommandLine, wworkingDirectory;
+ llvm::ConvertUTF8toWide(executable, wexecutable);
+ llvm::ConvertUTF8toWide(commandLine, wcommandLine);
+ llvm::ConvertUTF8toWide(launch_info.GetWorkingDirectory().GetCString(), wworkingDirectory);
+
+ wcommandLine.resize(PATH_MAX); // Needs to be over-allocated because CreateProcessW can modify it
+ BOOL result = ::CreateProcessW(wexecutable.c_str(), &wcommandLine[0], NULL, NULL, TRUE, flags, env_block,
+ wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(), &startupinfo, &pi);
if (result)
{
// Do not call CloseHandle on pi.hProcess, since we want to pass that back through the HostProcess.
@@ -100,6 +139,8 @@ ProcessLauncherWindows::GetStdioHandle(const ProcessLaunchInfo &launch_info, int
flags = FILE_FLAG_WRITE_THROUGH;
}
- HANDLE result = ::CreateFile(path, access, share, &secattr, create, flags, NULL);
+ std::wstring wpath;
+ llvm::ConvertUTF8toWide(path, wpath);
+ HANDLE result = ::CreateFileW(wpath.c_str(), access, share, &secattr, create, flags, NULL);
return (result == INVALID_HANDLE_VALUE) ? NULL : result;
}
diff --git a/source/Host/windows/Windows.cpp b/source/Host/windows/Windows.cpp
index 71bff7a9d2e2..2aebb10bcdd9 100644
--- a/source/Host/windows/Windows.cpp
+++ b/source/Host/windows/Windows.cpp
@@ -12,6 +12,9 @@
#include "lldb/Host/windows/windows.h"
#include "lldb/Host/windows/win32.h"
+#include "llvm/Support/ConvertUTF.h"
+
+#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
@@ -27,6 +30,29 @@ extern "C"
int _chdir(const char *path);
}
+namespace
+{
+bool
+utf8ToWide(const char *utf8, wchar_t *buf, size_t bufSize)
+{
+ const UTF8 *sourceStart = reinterpret_cast<const UTF8 *>(utf8);
+ size_t sourceLen = strlen(utf8) + 1 /* convert null too */;
+ UTF16 *target = reinterpret_cast<UTF16 *>(buf);
+ ConversionFlags flags = strictConversion;
+ return ConvertUTF8toUTF16(&sourceStart, sourceStart + sourceLen, &target, target + bufSize, flags) == conversionOK;
+}
+
+bool
+wideToUtf8(const wchar_t *wide, char *buf, size_t bufSize)
+{
+ const UTF16 *sourceStart = reinterpret_cast<const UTF16 *>(wide);
+ size_t sourceLen = wcslen(wide) + 1 /* convert null too */;
+ UTF8 *target = reinterpret_cast<UTF8 *>(buf);
+ ConversionFlags flags = strictConversion;
+ return ConvertUTF16toUTF8(&sourceStart, sourceStart + sourceLen, &target, target + bufSize, flags) == conversionOK;
+}
+}
+
int vasprintf(char **ret, const char *fmt, va_list ap)
{
char *buf;
@@ -75,81 +101,90 @@ char* strcasestr(const char *s, const char* find)
char* realpath(const char * name, char * resolved)
{
- char *retname = NULL; /* we will return this, if we fail */
+ char *retname = NULL;
/* SUSv3 says we must set `errno = EINVAL', and return NULL,
* if `name' is passed as a NULL pointer.
*/
-
if (name == NULL)
+ {
errno = EINVAL;
+ return NULL;
+ }
/* Otherwise, `name' must refer to a readable filesystem object,
* if we are going to resolve its absolute path name.
*/
-
- else if (access(name, 4) == 0)
+ wchar_t wideNameBuffer[PATH_MAX];
+ wchar_t *wideName = wideNameBuffer;
+ if (!utf8ToWide(name, wideName, PATH_MAX))
{
- /* If `name' didn't point to an existing entity,
- * then we don't get to here; we simply fall past this block,
- * returning NULL, with `errno' appropriately set by `access'.
- *
- * When we _do_ get to here, then we can use `_fullpath' to
- * resolve the full path for `name' into `resolved', but first,
- * check that we have a suitable buffer, in which to return it.
- */
+ errno = EINVAL;
+ return NULL;
+ }
- if ((retname = resolved) == NULL)
- {
- /* Caller didn't give us a buffer, so we'll exercise the
- * option granted by SUSv3, and allocate one.
- *
- * `_fullpath' would do this for us, but it uses `malloc', and
- * Microsoft's implementation doesn't set `errno' on failure.
- * If we don't do this explicitly ourselves, then we will not
- * know if `_fullpath' fails on `malloc' failure, or for some
- * other reason, and we want to set `errno = ENOMEM' for the
- * `malloc' failure case.
- */
-
- retname = (char*) malloc(_MAX_PATH);
- }
+ if (_waccess(wideName, 4) != 0)
+ return NULL;
+
+ /* If `name' didn't point to an existing entity,
+ * then we don't get to here; we simply fall past this block,
+ * returning NULL, with `errno' appropriately set by `access'.
+ *
+ * When we _do_ get to here, then we can use `_fullpath' to
+ * resolve the full path for `name' into `resolved', but first,
+ * check that we have a suitable buffer, in which to return it.
+ */
- /* By now, we should have a valid buffer.
- * If we don't, then we know that `malloc' failed,
- * so we can set `errno = ENOMEM' appropriately.
+ if ((retname = resolved) == NULL)
+ {
+ /* Caller didn't give us a buffer, so we'll exercise the
+ * option granted by SUSv3, and allocate one.
+ *
+ * `_fullpath' would do this for us, but it uses `malloc', and
+ * Microsoft's implementation doesn't set `errno' on failure.
+ * If we don't do this explicitly ourselves, then we will not
+ * know if `_fullpath' fails on `malloc' failure, or for some
+ * other reason, and we want to set `errno = ENOMEM' for the
+ * `malloc' failure case.
*/
+ retname = (char *)malloc(PATH_MAX);
if (retname == NULL)
+ {
errno = ENOMEM;
+ return NULL;
+ }
+ }
- /* Otherwise, when we do have a valid buffer,
- * `_fullpath' should only fail if the path name is too long.
- */
+ /* Otherwise, when we do have a valid buffer,
+ * `_fullpath' should only fail if the path name is too long.
+ */
- else if ((retname = _fullpath(retname, name, _MAX_PATH)) == NULL)
- errno = ENAMETOOLONG;
+ wchar_t wideFullPathBuffer[PATH_MAX];
+ wchar_t *wideFullPath;
+ if ((wideFullPath = _wfullpath(wideFullPathBuffer, wideName, PATH_MAX)) == NULL)
+ {
+ errno = ENAMETOOLONG;
+ return NULL;
}
- /* By the time we get to here,
- * `retname' either points to the required resolved path name,
- * or it is NULL, with `errno' set appropriately, either of which
- * is our required return condition.
- */
+ // Do a LongPath<->ShortPath roundtrip so that case is resolved by OS
+ // FIXME: Check for failure
+ size_t initialLength = wcslen(wideFullPath);
+ GetShortPathNameW(wideFullPath, wideNameBuffer, PATH_MAX);
+ GetLongPathNameW(wideNameBuffer, wideFullPathBuffer, initialLength + 1);
- if (retname != NULL)
+ // Convert back to UTF-8
+ if (!wideToUtf8(wideFullPathBuffer, retname, PATH_MAX))
{
- // Do a LongPath<->ShortPath roundtrip so that case is resolved by OS
- int initialLength = strlen(retname);
- TCHAR buffer[MAX_PATH];
- GetShortPathName(retname, buffer, MAX_PATH);
- GetLongPathName(buffer, retname, initialLength + 1);
-
- // Force drive to be upper case
- if (retname[1] == ':')
- retname[0] = toupper(retname[0]);
+ errno = EINVAL;
+ return NULL;
}
+ // Force drive to be upper case
+ if (retname[1] == ':')
+ retname[0] = toupper(retname[0]);
+
return retname;
}
@@ -167,7 +202,27 @@ char* basename(char *path)
// use _getcwd() instead of GetCurrentDirectory() because it updates errno
char* getcwd(char* path, int max)
{
- return _getcwd(path, max);
+ assert(path == NULL || max <= PATH_MAX);
+ wchar_t wpath[PATH_MAX];
+ if (wchar_t *wresult = _wgetcwd(wpath, PATH_MAX))
+ {
+ // Caller is allowed to pass in NULL for `path`.
+ // In that case, we're supposed to allocate a
+ // buffer on the caller's behalf.
+ if (path == NULL)
+ {
+ max = UNI_MAX_UTF8_BYTES_PER_CODE_POINT * wcslen(wresult) + 1;
+ path = (char *)malloc(max);
+ if (path == NULL)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
+ if (wideToUtf8(wresult, path, max))
+ return path;
+ }
+ return NULL;
}
// use _chdir() instead of SetCurrentDirectory() because it updates errno
diff --git a/source/Initialization/Makefile b/source/Initialization/Makefile
deleted file mode 100644
index a63f4733bb6e..000000000000
--- a/source/Initialization/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Initialize/Makefile -------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LIBRARYNAME := lldbInitialization
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Initialization/SystemInitializerCommon.cpp b/source/Initialization/SystemInitializerCommon.cpp
index 6cbc0b707df4..258f9c8872e2 100644
--- a/source/Initialization/SystemInitializerCommon.cpp
+++ b/source/Initialization/SystemInitializerCommon.cpp
@@ -13,11 +13,6 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Timer.h"
-#include "lldb/Symbol/GoASTContext.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
-#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
-#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
#include "Plugins/Instruction/MIPS/EmulateInstructionMIPS.h"
#include "Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h"
@@ -25,23 +20,10 @@
#include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h"
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
-#include "Plugins/OperatingSystem/Python/OperatingSystemPython.h"
-#include "Plugins/OperatingSystem/Go/OperatingSystemGo.h"
-#include "Plugins/Platform/Android/PlatformAndroid.h"
-#include "Plugins/Platform/FreeBSD/PlatformFreeBSD.h"
-#include "Plugins/Platform/Kalimba/PlatformKalimba.h"
-#include "Plugins/Platform/Linux/PlatformLinux.h"
-#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
-#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
-#include "Plugins/Platform/NetBSD/PlatformNetBSD.h"
-#include "Plugins/Platform/Windows/PlatformWindows.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
#if defined(__APPLE__)
-#include "Plugins/Platform/MacOSX/PlatformiOSSimulator.h"
-#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
-#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
#endif
#if defined(__linux__)
@@ -49,8 +31,8 @@
#endif
#if defined(_MSC_VER)
-#include "lldb/Host/windows/windows.h"
#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
+#include "lldb/Host/windows/windows.h"
#endif
#include "llvm/Support/TargetSelect.h"
@@ -97,7 +79,6 @@ SystemInitializerCommon::Initialize()
Log::Initialize();
HostInfo::Initialize();
- Timer::Initialize();
Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
llvm::install_fatal_error_handler(fatal_error_handler, 0);
@@ -105,20 +86,9 @@ SystemInitializerCommon::Initialize()
process_gdb_remote::ProcessGDBRemoteLog::Initialize();
// Initialize plug-ins
- ClangASTContext::Initialize();
- GoASTContext::Initialize();
-
ObjectContainerBSDArchive::Initialize();
ObjectFileELF::Initialize();
ObjectFilePECOFF::Initialize();
- DynamicLoaderPOSIXDYLD::Initialize();
- DynamicLoaderWindowsDYLD::Initialize();
- platform_freebsd::PlatformFreeBSD::Initialize();
- platform_linux::PlatformLinux::Initialize();
- platform_netbsd::PlatformNetBSD::Initialize();
- PlatformWindows::Initialize();
- PlatformKalimba::Initialize();
- platform_android::PlatformAndroid::Initialize();
EmulateInstructionARM::Initialize();
EmulateInstructionMIPS::Initialize();
@@ -127,16 +97,10 @@ SystemInitializerCommon::Initialize()
//----------------------------------------------------------------------
// Apple/Darwin hosted plugins
//----------------------------------------------------------------------
- DynamicLoaderMacOSXDYLD::Initialize();
ObjectContainerUniversalMachO::Initialize();
- PlatformRemoteiOS::Initialize();
- PlatformMacOSX::Initialize();
#if defined(__APPLE__)
- PlatformiOSSimulator::Initialize();
- DynamicLoaderDarwinKernel::Initialize();
- PlatformDarwinKernel::Initialize();
ObjectFileMachO::Initialize();
#endif
#if defined(__linux__)
@@ -146,10 +110,6 @@ SystemInitializerCommon::Initialize()
#if defined(_MSC_VER)
ProcessWindowsLog::Initialize();
#endif
-#ifndef LLDB_DISABLE_PYTHON
- OperatingSystemPython::Initialize();
-#endif
- OperatingSystemGo::Initialize();
}
void
@@ -159,41 +119,20 @@ SystemInitializerCommon::Terminate()
ObjectContainerBSDArchive::Terminate();
ObjectFileELF::Terminate();
ObjectFilePECOFF::Terminate();
- DynamicLoaderPOSIXDYLD::Terminate();
- DynamicLoaderWindowsDYLD::Terminate();
- platform_freebsd::PlatformFreeBSD::Terminate();
- platform_linux::PlatformLinux::Terminate();
- platform_netbsd::PlatformNetBSD::Terminate();
- PlatformWindows::Terminate();
- PlatformKalimba::Terminate();
- platform_android::PlatformAndroid::Terminate();
- DynamicLoaderMacOSXDYLD::Terminate();
- ObjectContainerUniversalMachO::Terminate();
- PlatformMacOSX::Terminate();
- PlatformRemoteiOS::Terminate();
-
- ClangASTContext::Terminate();
- GoASTContext::Terminate();
EmulateInstructionARM::Terminate();
EmulateInstructionMIPS::Terminate();
EmulateInstructionMIPS64::Terminate();
+ ObjectContainerUniversalMachO::Terminate();
#if defined(__APPLE__)
- PlatformiOSSimulator::Terminate();
- DynamicLoaderDarwinKernel::Terminate();
ObjectFileMachO::Terminate();
- PlatformDarwinKernel::Terminate();
#endif
#if defined(_MSC_VER)
ProcessWindowsLog::Terminate();
#endif
-#ifndef LLDB_DISABLE_PYTHON
- OperatingSystemPython::Terminate();
-#endif
- OperatingSystemGo::Terminate();
-
+ HostInfo::Terminate();
Log::Terminate();
}
diff --git a/source/Initialization/SystemLifetimeManager.cpp b/source/Initialization/SystemLifetimeManager.cpp
index eafbe68c9984..0f61622b31b0 100644
--- a/source/Initialization/SystemLifetimeManager.cpp
+++ b/source/Initialization/SystemLifetimeManager.cpp
@@ -10,16 +10,13 @@
#include "lldb/Initialization/SystemLifetimeManager.h"
#include "lldb/Core/Debugger.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Initialization/SystemInitializer.h"
#include <utility>
using namespace lldb_private;
-SystemLifetimeManager::SystemLifetimeManager()
- : m_mutex(Mutex::eMutexTypeRecursive)
- , m_initialized(false)
+SystemLifetimeManager::SystemLifetimeManager() : m_mutex(), m_initialized(false)
{
}
@@ -32,7 +29,7 @@ void
SystemLifetimeManager::Initialize(std::unique_ptr<SystemInitializer> initializer,
LoadPluginCallbackType plugin_callback)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_initialized)
{
assert(!m_initializer &&
@@ -48,7 +45,7 @@ SystemLifetimeManager::Initialize(std::unique_ptr<SystemInitializer> initializer
void
SystemLifetimeManager::Terminate()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_initialized)
{
diff --git a/source/Interpreter/Args.cpp b/source/Interpreter/Args.cpp
index 81e6b0aa1dbc..d90ef1d256a4 100644
--- a/source/Interpreter/Args.cpp
+++ b/source/Interpreter/Args.cpp
@@ -83,19 +83,22 @@ Args::~Args ()
}
void
-Args::Dump (Stream *s)
+Args::Dump (Stream &s, const char *label_name) const
{
+ if (!label_name)
+ return;
+
const size_t argc = m_argv.size();
for (size_t i=0; i<argc; ++i)
{
- s->Indent();
+ s.Indent();
const char *arg_cstr = m_argv[i];
if (arg_cstr)
- s->Printf("argv[%zi]=\"%s\"\n", i, arg_cstr);
+ s.Printf("%s[%zi]=\"%s\"\n", label_name, i, arg_cstr);
else
- s->Printf("argv[%zi]=NULL\n", i);
+ s.Printf("%s[%zi]=NULL\n", label_name, i);
}
- s->EOL();
+ s.EOL();
}
bool
@@ -575,8 +578,8 @@ Args::ParseOptions (Options &options)
}
}
}
- Mutex::Locker options_locker(NULL);
- OptionParser::Prepare(options_locker);
+ std::unique_lock<std::mutex> lock;
+ OptionParser::Prepare(lock);
int val;
while (1)
{
@@ -887,14 +890,43 @@ Args::StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t
}
const char *
-Args::GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg)
+Args::GetShellSafeArgument (const FileSpec& shell,
+ const char *unsafe_arg,
+ std::string &safe_arg)
{
+ struct ShellDescriptor
+ {
+ ConstString m_basename;
+ const char* m_escapables;
+ };
+
+ static ShellDescriptor g_Shells[] = {
+ {ConstString("bash")," '\"<>()&"},
+ {ConstString("tcsh")," '\"<>()&$"},
+ {ConstString("sh")," '\"<>()&"}
+ };
+
+ // safe minimal set
+ const char* escapables = " '\"";
+
+ if (auto basename = shell.GetFilename())
+ {
+ for (const auto& Shell : g_Shells)
+ {
+ if (Shell.m_basename == basename)
+ {
+ escapables = Shell.m_escapables;
+ break;
+ }
+ }
+ }
+
safe_arg.assign (unsafe_arg);
size_t prev_pos = 0;
while (prev_pos < safe_arg.size())
{
// Escape spaces and quotes
- size_t pos = safe_arg.find_first_of(" '\"", prev_pos);
+ size_t pos = safe_arg.find_first_of(escapables, prev_pos);
if (pos != std::string::npos)
{
safe_arg.insert (pos, 1, '\\');
@@ -906,7 +938,6 @@ Args::GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg)
return safe_arg.c_str();
}
-
int64_t
Args::StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error)
{
@@ -1108,6 +1139,47 @@ Args::LongestCommonPrefix (std::string &common_prefix)
}
}
+bool
+Args::ContainsEnvironmentVariable(const char *env_var_name) const
+{
+ // Validate args.
+ if (!env_var_name)
+ return false;
+
+ // Check each arg to see if it matches the env var name.
+ for (size_t i = 0; i < GetArgumentCount(); ++i)
+ {
+ // Get the arg value.
+ const char *argument_value = GetArgumentAtIndex(i);
+ if (!argument_value)
+ continue;
+
+ // Check if we are the "{env_var_name}={env_var_value}" style.
+ const char *equal_p = strchr(argument_value, '=');
+ if (equal_p)
+ {
+ if (strncmp(env_var_name, argument_value,
+ equal_p - argument_value) == 0)
+ {
+ // We matched.
+ return true;
+ }
+ }
+ else
+ {
+ // We're a simple {env_var_name}-style entry.
+ if (strcmp(argument_value, env_var_name) == 0)
+ {
+ // We matched.
+ return true;
+ }
+ }
+ }
+
+ // We didn't find a match.
+ return false;
+}
+
size_t
Args::FindArgumentIndexForOption (Option *long_options, int long_options_index)
{
@@ -1190,8 +1262,8 @@ Args::ParseAliasOptions (Options &options,
}
}
- Mutex::Locker options_locker(NULL);
- OptionParser::Prepare(options_locker);
+ std::unique_lock<std::mutex> lock;
+ OptionParser::Prepare(lock);
int val;
while (1)
{
@@ -1368,8 +1440,8 @@ Args::ParseArgsForCompletion
}
}
- Mutex::Locker options_locker(NULL);
- OptionParser::Prepare(options_locker);
+ std::unique_lock<std::mutex> lock;
+ OptionParser::Prepare(lock);
OptionParser::EnableError(false);
int val;
diff --git a/source/Interpreter/CMakeLists.txt b/source/Interpreter/CMakeLists.txt
index b92128cd3011..76d046f7d802 100644
--- a/source/Interpreter/CMakeLists.txt
+++ b/source/Interpreter/CMakeLists.txt
@@ -1,5 +1,6 @@
add_lldb_library(lldbInterpreter
Args.cpp
+ CommandAlias.cpp
CommandHistory.cpp
CommandInterpreter.cpp
CommandObject.cpp
diff --git a/source/Interpreter/CommandAlias.cpp b/source/Interpreter/CommandAlias.cpp
new file mode 100644
index 000000000000..a915d63e6541
--- /dev/null
+++ b/source/Interpreter/CommandAlias.cpp
@@ -0,0 +1,307 @@
+//===-- CommandAlias.cpp ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/CommandAlias.h"
+
+#include "llvm/Support/ErrorHandling.h"
+
+#include "lldb/Core/StreamString.h"
+#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static bool
+ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp,
+ const char *options_args,
+ OptionArgVectorSP &option_arg_vector_sp)
+{
+ bool success = true;
+ OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
+
+ if (!options_args || (strlen (options_args) < 1))
+ return true;
+
+ std::string options_string (options_args);
+ Args args (options_args);
+ CommandReturnObject result;
+ // Check to see if the command being aliased can take any command options.
+ Options *options = cmd_obj_sp->GetOptions ();
+ if (options)
+ {
+ // See if any options were specified as part of the alias; if so, handle them appropriately.
+ options->NotifyOptionParsingStarting ();
+ args.Unshift ("dummy_arg");
+ args.ParseAliasOptions (*options, result, option_arg_vector, options_string);
+ args.Shift ();
+ if (result.Succeeded())
+ options->VerifyPartialOptions (result);
+ if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted)
+ {
+ result.AppendError ("Unable to create requested alias.\n");
+ return false;
+ }
+ }
+
+ if (!options_string.empty())
+ {
+ if (cmd_obj_sp->WantsRawCommandString ())
+ option_arg_vector->push_back (OptionArgPair ("<argument>",
+ OptionArgValue (-1,
+ options_string)));
+ else
+ {
+ const size_t argc = args.GetArgumentCount();
+ for (size_t i = 0; i < argc; ++i)
+ if (strcmp (args.GetArgumentAtIndex (i), "") != 0)
+ option_arg_vector->push_back
+ (OptionArgPair ("<argument>",
+ OptionArgValue (-1,
+ std::string (args.GetArgumentAtIndex (i)))));
+ }
+ }
+
+ return success;
+}
+
+CommandAlias::CommandAlias (CommandInterpreter &interpreter,
+ lldb::CommandObjectSP cmd_sp,
+ const char *options_args,
+ const char *name,
+ const char *help,
+ const char *syntax,
+ uint32_t flags) :
+ CommandObject(interpreter,
+ name,
+ help,
+ syntax,
+ flags),
+m_underlying_command_sp(),
+m_option_string(options_args ? options_args : ""),
+m_option_args_sp(new OptionArgVector),
+m_is_dashdash_alias(eLazyBoolCalculate),
+m_did_set_help(false),
+m_did_set_help_long(false)
+{
+ if (ProcessAliasOptionsArgs(cmd_sp, options_args, m_option_args_sp))
+ {
+ m_underlying_command_sp = cmd_sp;
+ for (int i = 0;
+ auto cmd_entry = m_underlying_command_sp->GetArgumentEntryAtIndex(i);
+ i++)
+ {
+ m_arguments.push_back(*cmd_entry);
+ }
+ if (!help || !help[0])
+ {
+ StreamString sstr;
+ StreamString translation_and_help;
+ GetAliasExpansion(sstr);
+
+ translation_and_help.Printf ("(%s) %s", sstr.GetData(), GetUnderlyingCommand()->GetHelp());
+ SetHelp(translation_and_help.GetData());
+ }
+ }
+}
+
+bool
+CommandAlias::WantsRawCommandString()
+{
+ if (IsValid())
+ return m_underlying_command_sp->WantsRawCommandString();
+ return false;
+}
+
+bool
+CommandAlias::WantsCompletion()
+{
+ if (IsValid())
+ return m_underlying_command_sp->WantsCompletion();
+ return false;
+}
+
+int
+CommandAlias::HandleCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches)
+{
+ if (IsValid())
+ return m_underlying_command_sp->HandleCompletion(input,
+ cursor_index,
+ cursor_char_position,
+ match_start_point,
+ max_return_elements,
+ word_complete,
+ matches);
+ return -1;
+}
+
+int
+CommandAlias::HandleArgumentCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches)
+{
+ if (IsValid())
+ return m_underlying_command_sp->HandleArgumentCompletion(input,
+ cursor_index,
+ cursor_char_position,
+ opt_element_vector,
+ match_start_point,
+ max_return_elements,
+ word_complete,
+ matches);
+ return -1;
+}
+
+Options*
+CommandAlias::GetOptions()
+{
+ if (IsValid())
+ return m_underlying_command_sp->GetOptions();
+ return nullptr;
+}
+
+bool
+CommandAlias::Execute(const char *args_string, CommandReturnObject &result)
+{
+ llvm_unreachable("CommandAlias::Execute is not to be called");
+}
+
+void
+CommandAlias::GetAliasExpansion (StreamString &help_string)
+{
+ const char* command_name = m_underlying_command_sp->GetCommandName();
+ help_string.Printf ("'%s", command_name);
+
+ if (m_option_args_sp)
+ {
+ OptionArgVector *options = m_option_args_sp.get();
+ for (size_t i = 0; i < options->size(); ++i)
+ {
+ OptionArgPair cur_option = (*options)[i];
+ std::string opt = cur_option.first;
+ OptionArgValue value_pair = cur_option.second;
+ std::string value = value_pair.second;
+ if (opt.compare("<argument>") == 0)
+ {
+ help_string.Printf (" %s", value.c_str());
+ }
+ else
+ {
+ help_string.Printf (" %s", opt.c_str());
+ if ((value.compare ("<no-argument>") != 0)
+ && (value.compare ("<need-argument") != 0))
+ {
+ help_string.Printf (" %s", value.c_str());
+ }
+ }
+ }
+ }
+
+ help_string.Printf ("'");
+}
+
+bool
+CommandAlias::IsDashDashCommand ()
+{
+ if (m_is_dashdash_alias == eLazyBoolCalculate)
+ {
+ m_is_dashdash_alias = eLazyBoolNo;
+ if (IsValid())
+ {
+ for (const OptionArgPair& opt_arg : *GetOptionArguments())
+ {
+ if (opt_arg.first == "<argument>" &&
+ !opt_arg.second.second.empty() &&
+ llvm::StringRef(opt_arg.second.second).endswith("--"))
+ {
+ m_is_dashdash_alias = eLazyBoolYes;
+ break;
+ }
+ }
+ // if this is a nested alias, it may be adding arguments on top of an already dash-dash alias
+ if ((m_is_dashdash_alias == eLazyBoolNo) && IsNestedAlias())
+ m_is_dashdash_alias = (GetUnderlyingCommand()->IsDashDashCommand() ? eLazyBoolYes : eLazyBoolNo);
+ }
+ }
+ return (m_is_dashdash_alias == eLazyBoolYes);
+}
+
+bool
+CommandAlias::IsNestedAlias ()
+{
+ if (GetUnderlyingCommand())
+ return GetUnderlyingCommand()->IsAlias();
+ return false;
+}
+
+std::pair<lldb::CommandObjectSP, OptionArgVectorSP>
+CommandAlias::Desugar ()
+{
+ auto underlying = GetUnderlyingCommand();
+ if (!underlying)
+ return {nullptr,nullptr};
+
+ if (underlying->IsAlias())
+ {
+ auto desugared = ((CommandAlias*)underlying.get())->Desugar();
+ auto options = GetOptionArguments();
+ options->insert(options->begin(), desugared.second->begin(), desugared.second->end());
+ return {desugared.first,options};
+ }
+
+ return {underlying,GetOptionArguments()};
+}
+
+// allow CommandAlias objects to provide their own help, but fallback to the info
+// for the underlying command if no customization has been provided
+void
+CommandAlias::SetHelp (const char * str)
+{
+ this->CommandObject::SetHelp(str);
+ m_did_set_help = true;
+}
+
+void
+CommandAlias::SetHelpLong (const char * str)
+{
+ this->CommandObject::SetHelpLong(str);
+ m_did_set_help_long = true;
+}
+
+const char*
+CommandAlias::GetHelp ()
+{
+ if (!m_cmd_help_short.empty() || m_did_set_help)
+ return m_cmd_help_short.c_str();
+ if (IsValid())
+ return m_underlying_command_sp->GetHelp();
+ return nullptr;
+}
+
+const char*
+CommandAlias::GetHelpLong ()
+{
+ if (!m_cmd_help_long.empty() || m_did_set_help_long)
+ return m_cmd_help_long.c_str();
+ if (IsValid())
+ return m_underlying_command_sp->GetHelpLong();
+ return nullptr;
+}
diff --git a/source/Interpreter/CommandHistory.cpp b/source/Interpreter/CommandHistory.cpp
index 9d3c814697b0..ff87e528d36f 100644
--- a/source/Interpreter/CommandHistory.cpp
+++ b/source/Interpreter/CommandHistory.cpp
@@ -15,10 +15,7 @@
using namespace lldb;
using namespace lldb_private;
-
-CommandHistory::CommandHistory () :
- m_mutex(Mutex::eMutexTypeRecursive),
- m_history()
+CommandHistory::CommandHistory() : m_mutex(), m_history()
{}
CommandHistory::~CommandHistory ()
@@ -27,21 +24,21 @@ CommandHistory::~CommandHistory ()
size_t
CommandHistory::GetSize () const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_history.size();
}
bool
CommandHistory::IsEmpty () const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_history.empty();
}
const char*
CommandHistory::FindString (const char* input_str) const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!input_str)
return nullptr;
if (input_str[0] != g_repeat_char)
@@ -80,7 +77,7 @@ CommandHistory::FindString (const char* input_str) const
const char*
CommandHistory::GetStringAtIndex (size_t idx) const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (idx < m_history.size())
return m_history[idx].c_str();
return nullptr;
@@ -95,7 +92,7 @@ CommandHistory::operator [] (size_t idx) const
const char*
CommandHistory::GetRecentmostString () const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_history.empty())
return nullptr;
return m_history.back().c_str();
@@ -105,7 +102,7 @@ void
CommandHistory::AppendString (const std::string& str,
bool reject_if_dupe)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (reject_if_dupe)
{
if (!m_history.empty())
@@ -120,7 +117,7 @@ CommandHistory::AppendString (const std::string& str,
void
CommandHistory::Clear ()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_history.clear();
}
@@ -129,7 +126,7 @@ CommandHistory::Dump (Stream& stream,
size_t start_idx,
size_t stop_idx) const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
stop_idx = std::min(stop_idx + 1, m_history.size());
for (size_t counter = start_idx;
counter < stop_idx;
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index fd88f0d6b4be..5d5669f73cbc 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -105,7 +105,7 @@ CommandInterpreter::GetStaticBroadcasterClass ()
}
CommandInterpreter::CommandInterpreter(Debugger &debugger, ScriptLanguage script_language, bool synchronous_execution)
- : Broadcaster(&debugger, CommandInterpreter::GetStaticBroadcasterClass().AsCString()),
+ : Broadcaster(debugger.GetBroadcasterManager(), CommandInterpreter::GetStaticBroadcasterClass().AsCString()),
Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))),
IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand),
m_debugger(debugger),
@@ -185,6 +185,9 @@ CommandInterpreter::Initialize ()
LoadCommandDictionary ();
+ // An alias arguments vector to reuse - reset it before use...
+ OptionArgVectorSP alias_arguments_vector_sp (new OptionArgVector);
+
// Set up some initial aliases.
CommandObjectSP cmd_obj_sp = GetCommandSPExact ("quit", false);
if (cmd_obj_sp)
@@ -195,9 +198,7 @@ CommandInterpreter::Initialize ()
cmd_obj_sp = GetCommandSPExact ("_regexp-attach",false);
if (cmd_obj_sp)
- {
- AddAlias ("attach", cmd_obj_sp);
- }
+ AddAlias ("attach", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
cmd_obj_sp = GetCommandSPExact ("process detach",false);
if (cmd_obj_sp)
@@ -214,11 +215,11 @@ CommandInterpreter::Initialize ()
cmd_obj_sp = GetCommandSPExact ("_regexp-break",false);
if (cmd_obj_sp)
- AddAlias ("b", cmd_obj_sp);
+ AddAlias ("b", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
cmd_obj_sp = GetCommandSPExact ("_regexp-tbreak",false);
if (cmd_obj_sp)
- AddAlias ("tbreak", cmd_obj_sp);
+ AddAlias ("tbreak", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
cmd_obj_sp = GetCommandSPExact ("thread step-inst", false);
if (cmd_obj_sp)
@@ -239,6 +240,13 @@ CommandInterpreter::Initialize ()
{
AddAlias ("s", cmd_obj_sp);
AddAlias ("step", cmd_obj_sp);
+ CommandAlias *sif_alias = AddAlias ("sif", cmd_obj_sp, "--end-linenumber block --step-in-target %1");
+ if (sif_alias)
+ {
+ sif_alias->SetHelp("Step through the current block, stopping if you step "
+ "directly into a function whose name matches the TargetFunctionName.");
+ sif_alias->SetSyntax("sif <TargetFunctionName>");
+ }
}
cmd_obj_sp = GetCommandSPExact ("thread step-over", false);
@@ -269,22 +277,20 @@ CommandInterpreter::Initialize ()
cmd_obj_sp = GetCommandSPExact ("_regexp-jump",false);
if (cmd_obj_sp)
{
- AddAlias ("j", cmd_obj_sp);
- AddAlias ("jump", cmd_obj_sp);
+ AddAlias ("j", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
+ AddAlias ("jump", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
}
cmd_obj_sp = GetCommandSPExact ("_regexp-list", false);
if (cmd_obj_sp)
{
- AddAlias ("l", cmd_obj_sp);
- AddAlias ("list", cmd_obj_sp);
+ AddAlias ("l", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
+ AddAlias ("list", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
}
cmd_obj_sp = GetCommandSPExact ("_regexp-env", false);
if (cmd_obj_sp)
- {
- AddAlias ("env", cmd_obj_sp);
- }
+ AddAlias ("env", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
cmd_obj_sp = GetCommandSPExact ("memory read", false);
if (cmd_obj_sp)
@@ -292,15 +298,15 @@ CommandInterpreter::Initialize ()
cmd_obj_sp = GetCommandSPExact ("_regexp-up", false);
if (cmd_obj_sp)
- AddAlias ("up", cmd_obj_sp);
+ AddAlias ("up", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
cmd_obj_sp = GetCommandSPExact ("_regexp-down", false);
if (cmd_obj_sp)
- AddAlias ("down", cmd_obj_sp);
+ AddAlias ("down", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
cmd_obj_sp = GetCommandSPExact ("_regexp-display", false);
if (cmd_obj_sp)
- AddAlias ("display", cmd_obj_sp);
+ AddAlias ("display", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
cmd_obj_sp = GetCommandSPExact ("disassemble", false);
if (cmd_obj_sp)
@@ -314,11 +320,11 @@ CommandInterpreter::Initialize ()
cmd_obj_sp = GetCommandSPExact ("_regexp-undisplay", false);
if (cmd_obj_sp)
- AddAlias ("undisplay", cmd_obj_sp);
+ AddAlias ("undisplay", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
cmd_obj_sp = GetCommandSPExact ("_regexp-bt", false);
if (cmd_obj_sp)
- AddAlias ("bt", cmd_obj_sp);
+ AddAlias ("bt", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
cmd_obj_sp = GetCommandSPExact ("target create", false);
if (cmd_obj_sp)
@@ -329,23 +335,22 @@ CommandInterpreter::Initialize ()
AddAlias ("image", cmd_obj_sp);
- OptionArgVectorSP alias_arguments_vector_sp (new OptionArgVector);
-
+ alias_arguments_vector_sp.reset(new OptionArgVector);
+
cmd_obj_sp = GetCommandSPExact ("expression", false);
if (cmd_obj_sp)
{
- ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
- AddAlias ("p", cmd_obj_sp);
- AddAlias ("print", cmd_obj_sp);
- AddAlias ("call", cmd_obj_sp);
- AddOrReplaceAliasOptions ("p", alias_arguments_vector_sp);
- AddOrReplaceAliasOptions ("print", alias_arguments_vector_sp);
- AddOrReplaceAliasOptions ("call", alias_arguments_vector_sp);
-
- alias_arguments_vector_sp.reset (new OptionArgVector);
- ProcessAliasOptionsArgs (cmd_obj_sp, "-O -- ", alias_arguments_vector_sp);
- AddAlias ("po", cmd_obj_sp);
- AddOrReplaceAliasOptions ("po", alias_arguments_vector_sp);
+ AddAlias ("p", cmd_obj_sp, "--")->SetHelpLong("");
+ AddAlias ("print", cmd_obj_sp, "--")->SetHelpLong("");
+ AddAlias ("call", cmd_obj_sp, "--")->SetHelpLong("");
+ if (auto po = AddAlias ("po", cmd_obj_sp, "-O --"))
+ {
+ po->SetHelp("Evaluate an expression on the current thread. Displays any returned value with formatting "
+ "controlled by the type's author.");
+ po->SetHelpLong("");
+ }
+ AddAlias("parray", cmd_obj_sp, "--element-count %1 --")->SetHelpLong("");
+ AddAlias("poarray", cmd_obj_sp, "--object-description --element-count %1 --")->SetHelpLong("");
}
cmd_obj_sp = GetCommandSPExact ("process kill", false);
@@ -359,26 +364,23 @@ CommandInterpreter::Initialize ()
{
alias_arguments_vector_sp.reset (new OptionArgVector);
#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
- ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
+ AddAlias ("r", cmd_obj_sp, "--");
+ AddAlias ("run", cmd_obj_sp, "--");
#else
#if defined(__APPLE__)
std::string shell_option;
shell_option.append("--shell-expand-args");
shell_option.append(" true");
shell_option.append(" --");
- ProcessAliasOptionsArgs (cmd_obj_sp, shell_option.c_str(), alias_arguments_vector_sp);
+ AddAlias ("r", cmd_obj_sp, "--shell-expand-args true --");
+ AddAlias ("run", cmd_obj_sp, "--shell-expand-args true --");
#else
- std::string shell_option;
- shell_option.append("--shell=");
- shell_option.append(HostInfo::GetDefaultShell().GetPath());
- shell_option.append(" --");
- ProcessAliasOptionsArgs (cmd_obj_sp, shell_option.c_str(), alias_arguments_vector_sp);
+ StreamString defaultshell;
+ defaultshell.Printf("--shell=%s --", HostInfo::GetDefaultShell().GetPath().c_str());
+ AddAlias ("r", cmd_obj_sp, defaultshell.GetData());
+ AddAlias ("run", cmd_obj_sp, defaultshell.GetData());
#endif
#endif
- AddAlias ("r", cmd_obj_sp);
- AddAlias ("run", cmd_obj_sp);
- AddOrReplaceAliasOptions ("r", alias_arguments_vector_sp);
- AddOrReplaceAliasOptions ("run", alias_arguments_vector_sp);
}
cmd_obj_sp = GetCommandSPExact ("target symbols add", false);
@@ -390,10 +392,7 @@ CommandInterpreter::Initialize ()
cmd_obj_sp = GetCommandSPExact ("breakpoint set", false);
if (cmd_obj_sp)
{
- alias_arguments_vector_sp.reset (new OptionArgVector);
- ProcessAliasOptionsArgs (cmd_obj_sp, "--func-regex %1", alias_arguments_vector_sp);
- AddAlias ("rbreak", cmd_obj_sp);
- AddOrReplaceAliasOptions("rbreak", alias_arguments_vector_sp);
+ AddAlias ("rbreak", cmd_obj_sp, "--func-regex %1");
}
}
@@ -466,22 +465,26 @@ CommandInterpreter::LoadCommandDictionary ()
{"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"}};
size_t num_regexes = llvm::array_lengthof(break_regexes);
-
- std::unique_ptr<CommandObjectRegexCommand>
- break_regex_cmd_ap(new CommandObjectRegexCommand (*this,
- "_regexp-break",
- "Set a breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.\n",
- "\n_regexp-break <filename>:<linenum> # _regexp-break main.c:12 // Break on line 12 of main.c\n"
- "_regexp-break <linenum> # _regexp-break 12 // Break on line 12 of current file\n"
- "_regexp-break <address> # _regexp-break 0x1234000 // Break on address 0x1234000\n"
- "_regexp-break <name> # _regexp-break main // Break in 'main' after the prologue\n"
- "_regexp-break &<name> # _regexp-break &main // Break on the first instruction in 'main'\n"
- "_regexp-break <module>`<name> # _regexp-break libc.so`malloc // Break in 'malloc' only in the 'libc.so' shared library\n"
- "_regexp-break /<source-regex>/ # _regexp-break /break here/ // Break on all lines that match the regular expression 'break here' in the current file.\n",
- 2,
- CommandCompletions::eSymbolCompletion |
- CommandCompletions::eSourceFileCompletion,
- false));
+
+ std::unique_ptr<CommandObjectRegexCommand> break_regex_cmd_ap(new CommandObjectRegexCommand(
+ *this, "_regexp-break", "Set a breakpoint using one of several shorthand formats.\n",
+ "\n"
+ "_regexp-break <filename>:<linenum>\n"
+ " main.c:12 // Break at line 12 of main.c\n\n"
+ "_regexp-break <linenum>\n"
+ " 12 // Break at line 12 of current file\n\n"
+ "_regexp-break 0x<address>\n"
+ " 0x1234000 // Break at address 0x1234000\n\n"
+ "_regexp-break <name>\n"
+ " main // Break in 'main' after the prologue\n\n"
+ "_regexp-break &<name>\n"
+ " &main // Break at first instruction in 'main'\n\n"
+ "_regexp-break <module>`<name>\n"
+ " libc.so`malloc // Break in 'malloc' from 'libc.so'\n\n"
+ "_regexp-break /<source-regex>/\n"
+ " /break here/ // Break on source lines in current file\n"
+ " // containing text 'break here'.\n",
+ 2, CommandCompletions::eSymbolCompletion | CommandCompletions::eSourceFileCompletion, false));
if (break_regex_cmd_ap.get())
{
@@ -501,15 +504,25 @@ CommandInterpreter::LoadCommandDictionary ()
}
}
- std::unique_ptr<CommandObjectRegexCommand>
- tbreak_regex_cmd_ap(new CommandObjectRegexCommand (*this,
- "_regexp-tbreak",
- "Set a one shot breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.",
- "_regexp-tbreak [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>",
- 2,
- CommandCompletions::eSymbolCompletion |
- CommandCompletions::eSourceFileCompletion,
- false));
+ std::unique_ptr<CommandObjectRegexCommand> tbreak_regex_cmd_ap(new CommandObjectRegexCommand(
+ *this, "_regexp-tbreak", "Set a one-shot breakpoint using one of several shorthand formats.\n",
+ "\n"
+ "_regexp-break <filename>:<linenum>\n"
+ " main.c:12 // Break at line 12 of main.c\n\n"
+ "_regexp-break <linenum>\n"
+ " 12 // Break at line 12 of current file\n\n"
+ "_regexp-break 0x<address>\n"
+ " 0x1234000 // Break at address 0x1234000\n\n"
+ "_regexp-break <name>\n"
+ " main // Break in 'main' after the prologue\n\n"
+ "_regexp-break &<name>\n"
+ " &main // Break at first instruction in 'main'\n\n"
+ "_regexp-break <module>`<name>\n"
+ " libc.so`malloc // Break in 'malloc' from 'libc.so'\n\n"
+ "_regexp-break /<source-regex>/\n"
+ " /break here/ // Break on source lines in current file\n"
+ " // containing text 'break here'.\n",
+ 2, CommandCompletions::eSymbolCompletion | CommandCompletions::eSourceFileCompletion, false));
if (tbreak_regex_cmd_ap.get())
{
@@ -534,14 +547,9 @@ CommandInterpreter::LoadCommandDictionary ()
}
}
- std::unique_ptr<CommandObjectRegexCommand>
- attach_regex_cmd_ap(new CommandObjectRegexCommand (*this,
- "_regexp-attach",
- "Attach to a process id if in decimal, otherwise treat the argument as a process name to attach to.",
- "_regexp-attach [<pid>]\n_regexp-attach [<process-name>]",
- 2,
- 0,
- false));
+ std::unique_ptr<CommandObjectRegexCommand> attach_regex_cmd_ap(
+ new CommandObjectRegexCommand(*this, "_regexp-attach", "Attach to process by ID or name.",
+ "_regexp-attach <pid> | <process-name>", 2, 0, false));
if (attach_regex_cmd_ap.get())
{
if (attach_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "process attach --pid %1") &&
@@ -553,15 +561,11 @@ CommandInterpreter::LoadCommandDictionary ()
m_command_dict[attach_regex_cmd_sp->GetCommandName ()] = attach_regex_cmd_sp;
}
}
-
- std::unique_ptr<CommandObjectRegexCommand>
- down_regex_cmd_ap(new CommandObjectRegexCommand (*this,
- "_regexp-down",
- "Go down \"n\" frames in the stack (1 frame by default).",
- "_regexp-down [n]",
- 2,
- 0,
- false));
+
+ std::unique_ptr<CommandObjectRegexCommand> down_regex_cmd_ap(new CommandObjectRegexCommand(
+ *this, "_regexp-down", "Select a newer stack frame. Defaults to moving one frame, a numeric argument can "
+ "specify an arbitrary number.",
+ "_regexp-down [<count>]", 2, 0, false));
if (down_regex_cmd_ap.get())
{
if (down_regex_cmd_ap->AddRegexCommand("^$", "frame select -r -1") &&
@@ -571,15 +575,11 @@ CommandInterpreter::LoadCommandDictionary ()
m_command_dict[down_regex_cmd_sp->GetCommandName ()] = down_regex_cmd_sp;
}
}
-
- std::unique_ptr<CommandObjectRegexCommand>
- up_regex_cmd_ap(new CommandObjectRegexCommand (*this,
- "_regexp-up",
- "Go up \"n\" frames in the stack (1 frame by default).",
- "_regexp-up [n]",
- 2,
- 0,
- false));
+
+ std::unique_ptr<CommandObjectRegexCommand> up_regex_cmd_ap(
+ new CommandObjectRegexCommand(*this, "_regexp-up", "Select an older stack frame. Defaults to moving one "
+ "frame, a numeric argument can specify an arbitrary number.",
+ "_regexp-up [<count>]", 2, 0, false));
if (up_regex_cmd_ap.get())
{
if (up_regex_cmd_ap->AddRegexCommand("^$", "frame select -r 1") &&
@@ -590,14 +590,9 @@ CommandInterpreter::LoadCommandDictionary ()
}
}
- std::unique_ptr<CommandObjectRegexCommand>
- display_regex_cmd_ap(new CommandObjectRegexCommand (*this,
- "_regexp-display",
- "Add an expression evaluation stop-hook.",
- "_regexp-display expression",
- 2,
- 0,
- false));
+ std::unique_ptr<CommandObjectRegexCommand> display_regex_cmd_ap(new CommandObjectRegexCommand(
+ *this, "_regexp-display", "Evaluate an expression at every stop (see 'help target stop-hook'.)",
+ "_regexp-display expression", 2, 0, false));
if (display_regex_cmd_ap.get())
{
if (display_regex_cmd_ap->AddRegexCommand("^(.+)$", "target stop-hook add -o \"expr -- %1\""))
@@ -607,14 +602,9 @@ CommandInterpreter::LoadCommandDictionary ()
}
}
- std::unique_ptr<CommandObjectRegexCommand>
- undisplay_regex_cmd_ap(new CommandObjectRegexCommand (*this,
- "_regexp-undisplay",
- "Remove an expression evaluation stop-hook.",
- "_regexp-undisplay stop-hook-number",
- 2,
- 0,
- false));
+ std::unique_ptr<CommandObjectRegexCommand> undisplay_regex_cmd_ap(new CommandObjectRegexCommand(
+ *this, "_regexp-undisplay", "Stop displaying expression at every stop (specified by stop-hook index.)",
+ "_regexp-undisplay stop-hook-number", 2, 0, false));
if (undisplay_regex_cmd_ap.get())
{
if (undisplay_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "target stop-hook delete %1"))
@@ -624,14 +614,10 @@ CommandInterpreter::LoadCommandDictionary ()
}
}
- std::unique_ptr<CommandObjectRegexCommand>
- connect_gdb_remote_cmd_ap(new CommandObjectRegexCommand (*this,
- "gdb-remote",
- "Connect to a remote GDB server. If no hostname is provided, localhost is assumed.",
- "gdb-remote [<hostname>:]<portnum>",
- 2,
- 0,
- false));
+ std::unique_ptr<CommandObjectRegexCommand> connect_gdb_remote_cmd_ap(new CommandObjectRegexCommand(
+ *this, "gdb-remote",
+ "Connect to a process via remote GDB server. If no host is specifed, localhost is assumed.",
+ "gdb-remote [<hostname>:]<portnum>", 2, 0, false));
if (connect_gdb_remote_cmd_ap.get())
{
if (connect_gdb_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin gdb-remote connect://%1") &&
@@ -642,14 +628,10 @@ CommandInterpreter::LoadCommandDictionary ()
}
}
- std::unique_ptr<CommandObjectRegexCommand>
- connect_kdp_remote_cmd_ap(new CommandObjectRegexCommand (*this,
- "kdp-remote",
- "Connect to a remote KDP server. udp port 41139 is the default port number.",
- "kdp-remote <hostname>[:<portnum>]",
- 2,
- 0,
- false));
+ std::unique_ptr<CommandObjectRegexCommand> connect_kdp_remote_cmd_ap(new CommandObjectRegexCommand(
+ *this, "kdp-remote",
+ "Connect to a process via remote KDP server. If no UDP port is specified, port 41139 is assumed.",
+ "kdp-remote <hostname>[:<portnum>]", 2, 0, false));
if (connect_kdp_remote_cmd_ap.get())
{
if (connect_kdp_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin kdp-remote udp://%1") &&
@@ -660,14 +642,10 @@ CommandInterpreter::LoadCommandDictionary ()
}
}
- std::unique_ptr<CommandObjectRegexCommand>
- bt_regex_cmd_ap(new CommandObjectRegexCommand (*this,
- "_regexp-bt",
- "Show a backtrace. An optional argument is accepted; if that argument is a number, it specifies the number of frames to display. If that argument is 'all', full backtraces of all threads are displayed.",
- "bt [<digit>|all]",
- 2,
- 0,
- false));
+ std::unique_ptr<CommandObjectRegexCommand> bt_regex_cmd_ap(new CommandObjectRegexCommand(
+ *this, "_regexp-bt", "Show the current thread's call stack. Any numeric argument displays at most that many "
+ "frames. The argument 'all' displays all threads.",
+ "bt [<digit> | all]", 2, 0, false));
if (bt_regex_cmd_ap.get())
{
// accept but don't document "bt -c <number>" -- before bt was a regex command if you wanted to backtrace
@@ -683,14 +661,16 @@ CommandInterpreter::LoadCommandDictionary ()
}
}
- std::unique_ptr<CommandObjectRegexCommand>
- list_regex_cmd_ap(new CommandObjectRegexCommand (*this,
- "_regexp-list",
- "Implements the GDB 'list' command in all of its forms except FILE:FUNCTION and maps them to the appropriate 'source list' commands.",
- "_regexp-list [<line>]\n_regexp-list [<file>:<line>]\n_regexp-list [<file>:<line>]",
- 2,
- CommandCompletions::eSourceFileCompletion,
- false));
+ std::unique_ptr<CommandObjectRegexCommand> list_regex_cmd_ap(new CommandObjectRegexCommand(
+ *this, "_regexp-list", "List relevant source code using one of several shorthand formats.",
+ "\n"
+ "_regexp-list <file>:<line> // List around specific file/line\n"
+ "_regexp-list <line> // List current file around specified line\n"
+ "_regexp-list <function-name> // List specified function\n"
+ "_regexp-list 0x<address> // List around specified address\n"
+ "_regexp-list -[<count>] // List previous <count> lines\n"
+ "_regexp-list // List subsequent lines",
+ 2, CommandCompletions::eSourceFileCompletion, false));
if (list_regex_cmd_ap.get())
{
if (list_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "source list --line %1") &&
@@ -706,14 +686,12 @@ CommandInterpreter::LoadCommandDictionary ()
}
}
- std::unique_ptr<CommandObjectRegexCommand>
- env_regex_cmd_ap(new CommandObjectRegexCommand (*this,
- "_regexp-env",
- "Implements a shortcut to viewing and setting environment variables.",
- "_regexp-env\n_regexp-env FOO=BAR",
- 2,
- 0,
- false));
+ std::unique_ptr<CommandObjectRegexCommand> env_regex_cmd_ap(
+ new CommandObjectRegexCommand(*this, "_regexp-env", "Shorthand for viewing and setting environment variables.",
+ "\n"
+ "_regexp-env // Show enrivonment\n"
+ "_regexp-env <name>=<value> // Set an environment variable",
+ 2, 0, false));
if (env_regex_cmd_ap.get())
{
if (env_regex_cmd_ap->AddRegexCommand("^$", "settings show target.env-vars") &&
@@ -724,17 +702,14 @@ CommandInterpreter::LoadCommandDictionary ()
}
}
- std::unique_ptr<CommandObjectRegexCommand>
- jump_regex_cmd_ap(new CommandObjectRegexCommand (*this,
- "_regexp-jump",
- "Sets the program counter to a new address.",
- "_regexp-jump [<line>]\n"
- "_regexp-jump [<+-lineoffset>]\n"
- "_regexp-jump [<file>:<line>]\n"
- "_regexp-jump [*<addr>]\n",
- 2,
- 0,
- false));
+ std::unique_ptr<CommandObjectRegexCommand> jump_regex_cmd_ap(
+ new CommandObjectRegexCommand(*this, "_regexp-jump", "Set the program counter to a new address.",
+ "\n"
+ "_regexp-jump <line>\n"
+ "_regexp-jump +<line-offset> | -<line-offset>\n"
+ "_regexp-jump <file>:<line>\n"
+ "_regexp-jump *<addr>\n",
+ 2, 0, false));
if (jump_regex_cmd_ap.get())
{
if (jump_regex_cmd_ap->AddRegexCommand("^\\*(.*)$", "thread jump --addr %1") &&
@@ -753,11 +728,11 @@ int
CommandInterpreter::GetCommandNamesMatchingPartialString (const char *cmd_str, bool include_aliases,
StringList &matches)
{
- CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_str, matches);
+ AddNamesMatchingPartialString (m_command_dict, cmd_str, matches);
if (include_aliases)
{
- CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_str, matches);
+ AddNamesMatchingPartialString (m_alias_dict, cmd_str, matches);
}
return matches.GetSize();
@@ -780,9 +755,9 @@ CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bo
if (include_aliases && HasAliases())
{
- pos = m_alias_dict.find(cmd);
- if (pos != m_alias_dict.end())
- command_sp = pos->second;
+ auto alias_pos = m_alias_dict.find(cmd);
+ if (alias_pos != m_alias_dict.end())
+ command_sp = alias_pos->second;
}
if (HasUserCommands())
@@ -811,7 +786,7 @@ CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bo
if (HasCommands())
{
- num_cmd_matches = CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_cstr, *matches);
+ num_cmd_matches = AddNamesMatchingPartialString (m_command_dict, cmd_cstr, *matches);
}
if (num_cmd_matches == 1)
@@ -824,21 +799,21 @@ CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bo
if (include_aliases && HasAliases())
{
- num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_cstr, *matches);
+ num_alias_matches = AddNamesMatchingPartialString (m_alias_dict, cmd_cstr, *matches);
}
if (num_alias_matches == 1)
{
cmd.assign(matches->GetStringAtIndex (num_cmd_matches));
- pos = m_alias_dict.find(cmd);
- if (pos != m_alias_dict.end())
- alias_match_sp = pos->second;
+ auto alias_pos = m_alias_dict.find(cmd);
+ if (alias_pos != m_alias_dict.end())
+ alias_match_sp = alias_pos->second;
}
if (HasUserCommands())
{
- num_user_matches = CommandObject::AddNamesMatchingPartialString (m_user_dict, cmd_cstr, *matches);
+ num_user_matches = AddNamesMatchingPartialString (m_user_dict, cmd_cstr, *matches);
}
if (num_user_matches == 1)
@@ -874,6 +849,9 @@ CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bo
bool
CommandInterpreter::AddCommand (const char *name, const lldb::CommandObjectSP &cmd_sp, bool can_replace)
{
+ if (cmd_sp.get())
+ assert((this == &cmd_sp->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter");
+
if (name && name[0])
{
std::string name_sstr(name);
@@ -893,9 +871,11 @@ CommandInterpreter::AddUserCommand (std::string name,
const lldb::CommandObjectSP &cmd_sp,
bool can_replace)
{
+ if (cmd_sp.get())
+ assert((this == &cmd_sp->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter");
+
if (!name.empty())
{
-
const char* name_cstr = name.c_str();
// do not allow replacement of internal commands
@@ -1009,59 +989,6 @@ CommandInterpreter::CommandExists (const char *cmd)
}
bool
-CommandInterpreter::ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp,
- const char *options_args,
- OptionArgVectorSP &option_arg_vector_sp)
-{
- bool success = true;
- OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
-
- if (!options_args || (strlen (options_args) < 1))
- return true;
-
- std::string options_string (options_args);
- Args args (options_args);
- CommandReturnObject result;
- // Check to see if the command being aliased can take any command options.
- Options *options = cmd_obj_sp->GetOptions ();
- if (options)
- {
- // See if any options were specified as part of the alias; if so, handle them appropriately.
- options->NotifyOptionParsingStarting ();
- args.Unshift ("dummy_arg");
- args.ParseAliasOptions (*options, result, option_arg_vector, options_string);
- args.Shift ();
- if (result.Succeeded())
- options->VerifyPartialOptions (result);
- if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted)
- {
- result.AppendError ("Unable to create requested alias.\n");
- return false;
- }
- }
-
- if (!options_string.empty())
- {
- if (cmd_obj_sp->WantsRawCommandString ())
- option_arg_vector->push_back (OptionArgPair ("<argument>",
- OptionArgValue (-1,
- options_string)));
- else
- {
- const size_t argc = args.GetArgumentCount();
- for (size_t i = 0; i < argc; ++i)
- if (strcmp (args.GetArgumentAtIndex (i), "") != 0)
- option_arg_vector->push_back
- (OptionArgPair ("<argument>",
- OptionArgValue (-1,
- std::string (args.GetArgumentAtIndex (i)))));
- }
- }
-
- return success;
-}
-
-bool
CommandInterpreter::GetAliasFullName (const char *cmd, std::string &full_name)
{
bool exact_match = (m_alias_dict.find(cmd) != m_alias_dict.end());
@@ -1074,7 +1001,7 @@ CommandInterpreter::GetAliasFullName (const char *cmd, std::string &full_name)
{
StringList matches;
size_t num_alias_matches;
- num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd, matches);
+ num_alias_matches = AddNamesMatchingPartialString (m_alias_dict, cmd, matches);
if (num_alias_matches == 1)
{
// Make sure this isn't shadowing a command in the regular command space:
@@ -1107,17 +1034,32 @@ CommandInterpreter::UserCommandExists (const char *cmd)
return m_user_dict.find(cmd) != m_user_dict.end();
}
-void
-CommandInterpreter::AddAlias (const char *alias_name, CommandObjectSP& command_obj_sp)
+CommandAlias*
+CommandInterpreter::AddAlias (const char *alias_name,
+ lldb::CommandObjectSP& command_obj_sp,
+ const char *args_string)
{
- command_obj_sp->SetIsAlias (true);
- m_alias_dict[alias_name] = command_obj_sp;
+ if (command_obj_sp.get())
+ assert((this == &command_obj_sp->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter");
+
+ std::unique_ptr<CommandAlias> command_alias_up(new CommandAlias(*this,
+ command_obj_sp,
+ args_string,
+ alias_name));
+
+ if (command_alias_up && command_alias_up->IsValid())
+ {
+ m_alias_dict[alias_name] = CommandObjectSP(command_alias_up.get());
+ return command_alias_up.release();
+ }
+
+ return nullptr;
}
bool
CommandInterpreter::RemoveAlias (const char *alias_name)
{
- CommandObject::CommandMap::iterator pos = m_alias_dict.find(alias_name);
+ auto pos = m_alias_dict.find(alias_name);
if (pos != m_alias_dict.end())
{
m_alias_dict.erase(pos);
@@ -1154,56 +1096,6 @@ CommandInterpreter::RemoveUser (const char *alias_name)
}
void
-CommandInterpreter::GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string)
-{
- help_string.Printf ("'%s", command_name);
- OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
-
- if (option_arg_vector_sp)
- {
- OptionArgVector *options = option_arg_vector_sp.get();
- for (size_t i = 0; i < options->size(); ++i)
- {
- OptionArgPair cur_option = (*options)[i];
- std::string opt = cur_option.first;
- OptionArgValue value_pair = cur_option.second;
- std::string value = value_pair.second;
- if (opt.compare("<argument>") == 0)
- {
- help_string.Printf (" %s", value.c_str());
- }
- else
- {
- help_string.Printf (" %s", opt.c_str());
- if ((value.compare ("<no-argument>") != 0)
- && (value.compare ("<need-argument") != 0))
- {
- help_string.Printf (" %s", value.c_str());
- }
- }
- }
- }
-
- help_string.Printf ("'");
-}
-
-size_t
-CommandInterpreter::FindLongestCommandWord (CommandObject::CommandMap &dict)
-{
- CommandObject::CommandMap::const_iterator pos;
- CommandObject::CommandMap::const_iterator end = dict.end();
- size_t max_len = 0;
-
- for (pos = dict.begin(); pos != end; ++pos)
- {
- size_t len = pos->first.size();
- if (max_len < len)
- max_len = len;
- }
- return max_len;
-}
-
-void
CommandInterpreter::GetHelp (CommandReturnObject &result,
uint32_t cmd_types)
{
@@ -1241,17 +1133,10 @@ CommandInterpreter::GetHelp (CommandReturnObject &result,
result.AppendMessage("");
max_len = FindLongestCommandWord (m_alias_dict);
- for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos)
+ for (auto alias_pos = m_alias_dict.begin(); alias_pos != m_alias_dict.end(); ++alias_pos)
{
- StreamString sstr;
- StreamString translation_and_help;
- std::string entry_name = pos->first;
- std::string second_entry = pos->second.get()->GetCommandName();
- GetAliasHelp (pos->first.c_str(), pos->second->GetCommandName(), sstr);
-
- translation_and_help.Printf ("(%s) %s", sstr.GetData(), pos->second->GetHelp());
- OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--",
- translation_and_help.GetData(), max_len);
+ OutputFormattedHelpText (result.GetOutputStream(), alias_pos->first.c_str(), "--", alias_pos->second->GetHelp(),
+ max_len);
}
result.AppendMessage("");
}
@@ -1451,15 +1336,17 @@ CommandInterpreter::BuildAliasResult (const char *alias_name,
alias_cmd_obj = GetCommandObject (alias_name);
StreamString result_str;
- if (alias_cmd_obj)
+ if (alias_cmd_obj && alias_cmd_obj->IsAlias())
{
+ std::pair<CommandObjectSP, OptionArgVectorSP> desugared = ((CommandAlias*)alias_cmd_obj)->Desugar();
+ OptionArgVectorSP option_arg_vector_sp = desugared.second;
+ alias_cmd_obj = desugared.first.get();
std::string alias_name_str = alias_name;
if ((cmd_args.GetArgumentCount() == 0)
|| (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0))
cmd_args.Unshift (alias_name);
result_str.Printf ("%s", alias_cmd_obj->GetCommandName ());
- OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
if (option_arg_vector_sp.get())
{
@@ -1617,6 +1504,7 @@ CommandInterpreter::PreprocessCommand (std::string &command)
break;
case eExpressionResultUnavailable:
error.SetErrorStringWithFormat ("expression error fetching result for the expression '%s'", expr_str.c_str());
+ break;
case eExpressionCompleted:
break;
case eExpressionDiscarded:
@@ -2085,38 +1973,18 @@ CommandInterpreter::Confirm (const char *message, bool default_answer)
return confirm->GetResponse();
}
-OptionArgVectorSP
-CommandInterpreter::GetAliasOptions (const char *alias_name)
+CommandAlias*
+CommandInterpreter::GetAlias (const char *alias_name)
{
- OptionArgMap::iterator pos;
OptionArgVectorSP ret_val;
std::string alias (alias_name);
- if (HasAliasOptions())
- {
- pos = m_alias_options.find (alias);
- if (pos != m_alias_options.end())
- ret_val = pos->second;
- }
-
- return ret_val;
-}
-
-void
-CommandInterpreter::RemoveAliasOptions (const char *alias_name)
-{
- OptionArgMap::iterator pos = m_alias_options.find(alias_name);
- if (pos != m_alias_options.end())
- {
- m_alias_options.erase (pos);
- }
-}
-
-void
-CommandInterpreter::AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp)
-{
- m_alias_options[alias_name] = option_arg_vector_sp;
+ auto pos = m_alias_dict.find(alias);
+ if (pos != m_alias_dict.end())
+ return (CommandAlias*)pos->second.get();
+
+ return nullptr;
}
bool
@@ -2140,7 +2008,7 @@ CommandInterpreter::HasUserCommands ()
bool
CommandInterpreter::HasAliasOptions ()
{
- return (!m_alias_options.empty());
+ return HasAliases();
}
void
@@ -2150,7 +2018,7 @@ CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj,
std::string &raw_input_string,
CommandReturnObject &result)
{
- OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
+ OptionArgVectorSP option_arg_vector_sp = GetAlias(alias_name)->GetOptionArguments();
bool wants_raw_input = alias_cmd_obj->WantsRawCommandString();
@@ -2311,12 +2179,44 @@ CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result)
FileSpec init_file;
if (in_cwd)
{
- // In the current working directory we don't load any program specific
- // .lldbinit files, we only look for a "./.lldbinit" file.
- if (m_skip_lldbinit_files)
- return;
+ ExecutionContext exe_ctx(GetExecutionContext());
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target)
+ {
+ // In the current working directory we don't load any program specific
+ // .lldbinit files, we only look for a ".lldbinit" file.
+ if (m_skip_lldbinit_files)
+ return;
- init_file.SetFile ("./.lldbinit", true);
+ LoadCWDlldbinitFile should_load = target->TargetProperties::GetLoadCWDlldbinitFile ();
+ if (should_load == eLoadCWDlldbinitWarn)
+ {
+ FileSpec dot_lldb (".lldbinit", true);
+ llvm::SmallString<64> home_dir_path;
+ llvm::sys::path::home_directory (home_dir_path);
+ FileSpec homedir_dot_lldb (home_dir_path.c_str(), false);
+ homedir_dot_lldb.AppendPathComponent (".lldbinit");
+ homedir_dot_lldb.ResolvePath ();
+ if (dot_lldb.Exists ()
+ && dot_lldb.GetDirectory() != homedir_dot_lldb.GetDirectory())
+ {
+ result.AppendErrorWithFormat (
+ "There is a .lldbinit file in the current directory which is not being read.\n"
+ "To silence this warning without sourcing in the local .lldbinit,\n"
+ "add the following to the lldbinit file in your home directory:\n"
+ " settings set target.load-cwd-lldbinit false\n"
+ "To allow lldb to source .lldbinit files in the current working directory,\n"
+ "set the value of this variable to true. Only do so if you understand and\n"
+ "accept the security risk.");
+ result.SetStatus (eReturnStatusFailed);
+ return;
+ }
+ }
+ else if (should_load == eLoadCWDlldbinitTrue)
+ {
+ init_file.SetFile ("./.lldbinit", true);
+ }
+ }
}
else
{
@@ -2856,54 +2756,63 @@ CommandInterpreter::OutputHelpText (Stream &strm,
}
void
-CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found,
- StringList &commands_help, bool search_builtin_commands, bool search_user_commands)
+CommandInterpreter::FindCommandsForApropos (const char *search_word,
+ StringList &commands_found,
+ StringList &commands_help,
+ CommandObject::CommandMap &command_map)
{
CommandObject::CommandMap::const_iterator pos;
-
- if (search_builtin_commands)
+
+ for (pos = command_map.begin(); pos != command_map.end(); ++pos)
{
- for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
+ const char *command_name = pos->first.c_str();
+ CommandObject *cmd_obj = pos->second.get();
+
+ const bool search_short_help = true;
+ const bool search_long_help = false;
+ const bool search_syntax = false;
+ const bool search_options = false;
+ if (strcasestr(command_name, search_word) ||
+ cmd_obj->HelpTextContainsWord (search_word,
+ search_short_help,
+ search_long_help,
+ search_syntax,
+ search_options))
+ {
+ commands_found.AppendString (cmd_obj->GetCommandName());
+ commands_help.AppendString (cmd_obj->GetHelp());
+ }
+
+ if (cmd_obj->IsMultiwordObject())
{
- const char *command_name = pos->first.c_str();
- CommandObject *cmd_obj = pos->second.get();
-
- if (cmd_obj->HelpTextContainsWord (search_word))
- {
- commands_found.AppendString (command_name);
- commands_help.AppendString (cmd_obj->GetHelp());
- }
-
- if (cmd_obj->IsMultiwordObject())
- cmd_obj->AproposAllSubCommands (command_name,
- search_word,
- commands_found,
- commands_help);
-
+ CommandObjectMultiword *cmd_multiword = cmd_obj->GetAsMultiwordCommand();
+ FindCommandsForApropos(search_word,
+ commands_found,
+ commands_help,
+ cmd_multiword->GetSubcommandDictionary());
}
}
+}
+
+
+void
+CommandInterpreter::FindCommandsForApropos (const char *search_word,
+ StringList &commands_found,
+ StringList &commands_help,
+ bool search_builtin_commands,
+ bool search_user_commands,
+ bool search_alias_commands)
+{
+ CommandObject::CommandMap::const_iterator pos;
+
+ if (search_builtin_commands)
+ FindCommandsForApropos(search_word, commands_found, commands_help, m_command_dict);
if (search_user_commands)
- {
- for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
- {
- const char *command_name = pos->first.c_str();
- CommandObject *cmd_obj = pos->second.get();
-
- if (cmd_obj->HelpTextContainsWord (search_word))
- {
- commands_found.AppendString (command_name);
- commands_help.AppendString (cmd_obj->GetHelp());
- }
+ FindCommandsForApropos(search_word, commands_found, commands_help, m_user_dict);
- if (cmd_obj->IsMultiwordObject())
- cmd_obj->AproposAllSubCommands (command_name,
- search_word,
- commands_found,
- commands_help);
-
- }
- }
+ if (search_alias_commands)
+ FindCommandsForApropos(search_word, commands_found, commands_help, m_alias_dict);
}
void
@@ -3240,8 +3149,12 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, CommandReturnO
if (cmd_obj == nullptr)
{
std::string full_name;
- if (GetAliasFullName(next_word.c_str(), full_name))
+ bool is_alias = GetAliasFullName(next_word.c_str(), full_name);
+ cmd_obj = GetCommandObject(next_word.c_str(), &matches);
+ bool is_real_command = (is_alias == false) || (cmd_obj != nullptr && cmd_obj->IsAlias() == false);
+ if (!is_real_command)
{
+ matches.Clear();
std::string alias_result;
cmd_obj = BuildAliasResult(full_name.c_str(), scratch_command, alias_result, result);
revised_command_line.Printf("%s", alias_result.c_str());
@@ -3253,7 +3166,8 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, CommandReturnO
}
else
{
- cmd_obj = GetCommandObject(next_word.c_str(), &matches);
+ if (!cmd_obj)
+ cmd_obj = GetCommandObject(next_word.c_str(), &matches);
if (cmd_obj)
{
actual_cmd_name_len += strlen(cmd_obj->GetCommandName());
diff --git a/source/Interpreter/CommandObject.cpp b/source/Interpreter/CommandObject.cpp
index 616d3e38acbb..75e42925406b 100644
--- a/source/Interpreter/CommandObject.cpp
+++ b/source/Interpreter/CommandObject.cpp
@@ -53,7 +53,6 @@ CommandObject::CommandObject
m_cmd_help_short (),
m_cmd_help_long (),
m_cmd_syntax (),
- m_is_alias (false),
m_flags (flags),
m_arguments(),
m_deprecated_command_override_callback (nullptr),
@@ -89,12 +88,12 @@ CommandObject::GetSyntax ()
{
StreamString syntax_str;
syntax_str.Printf ("%s", GetCommandName());
- if (GetOptions() != nullptr)
+ if (!IsDashDashCommand() && GetOptions() != nullptr)
syntax_str.Printf (" <cmd-options>");
if (m_arguments.size() > 0)
{
syntax_str.Printf (" ");
- if (WantsRawCommandString() && GetOptions() && GetOptions()->NumCommandOptions())
+ if (!IsDashDashCommand() && WantsRawCommandString() && GetOptions() && GetOptions()->NumCommandOptions())
syntax_str.Printf("-- ");
GetFormattedCommandArguments (syntax_str);
}
@@ -119,25 +118,19 @@ CommandObject::SetCommandName (const char *name)
void
CommandObject::SetHelp (const char *cstr)
{
- m_cmd_help_short = cstr;
-}
-
-void
-CommandObject::SetHelp (std::string str)
-{
- m_cmd_help_short = str;
+ if (cstr)
+ m_cmd_help_short = cstr;
+ else
+ m_cmd_help_short.assign("");
}
void
CommandObject::SetHelpLong (const char *cstr)
{
- m_cmd_help_long = cstr;
-}
-
-void
-CommandObject::SetHelpLong (std::string str)
-{
- m_cmd_help_long = str;
+ if (cstr)
+ m_cmd_help_long = cstr;
+ else
+ m_cmd_help_long.assign("");
}
void
@@ -283,7 +276,7 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
{
Target *target = m_exe_ctx.GetTargetPtr();
if (target)
- m_api_locker.Lock (target->GetAPIMutex());
+ m_api_locker = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex());
}
}
@@ -343,46 +336,8 @@ void
CommandObject::Cleanup ()
{
m_exe_ctx.Clear();
- m_api_locker.Unlock();
-}
-
-
-class CommandDictCommandPartialMatch
-{
- public:
- CommandDictCommandPartialMatch (const char *match_str)
- {
- m_match_str = match_str;
- }
- bool operator() (const std::pair<std::string, lldb::CommandObjectSP> map_element) const
- {
- // A NULL or empty string matches everything.
- if (m_match_str == nullptr || *m_match_str == '\0')
- return true;
-
- return map_element.first.find (m_match_str, 0) == 0;
- }
-
- private:
- const char *m_match_str;
-};
-
-int
-CommandObject::AddNamesMatchingPartialString (CommandObject::CommandMap &in_map, const char *cmd_str,
- StringList &matches)
-{
- int number_added = 0;
- CommandDictCommandPartialMatch matcher(cmd_str);
-
- CommandObject::CommandMap::iterator matching_cmds = std::find_if (in_map.begin(), in_map.end(), matcher);
-
- while (matching_cmds != in_map.end())
- {
- ++number_added;
- matches.AppendString((*matching_cmds).first.c_str());
- matching_cmds = std::find_if (++matching_cmds, in_map.end(), matcher);;
- }
- return number_added;
+ if (m_api_locker.owns_lock())
+ m_api_locker.unlock();
}
int
@@ -457,7 +412,11 @@ CommandObject::HandleCompletion
}
bool
-CommandObject::HelpTextContainsWord (const char *search_word)
+CommandObject::HelpTextContainsWord (const char *search_word,
+ bool search_short_help,
+ bool search_long_help,
+ bool search_syntax,
+ bool search_options)
{
std::string options_usage_help;
@@ -467,14 +426,15 @@ CommandObject::HelpTextContainsWord (const char *search_word)
const char *long_help = GetHelpLong();
const char *syntax_help = GetSyntax();
- if (short_help && strcasestr (short_help, search_word))
+ if (search_short_help && short_help && strcasestr (short_help, search_word))
found_word = true;
- else if (long_help && strcasestr (long_help, search_word))
+ else if (search_long_help && long_help && strcasestr (long_help, search_word))
found_word = true;
- else if (syntax_help && strcasestr (syntax_help, search_word))
+ else if (search_syntax && syntax_help && strcasestr (syntax_help, search_word))
found_word = true;
if (!found_word
+ && search_options
&& GetOptions() != nullptr)
{
StreamString usage_help;
@@ -727,46 +687,47 @@ RegisterNameHelpTextCallback ()
static const char *
BreakpointIDHelpTextCallback ()
{
- return "Breakpoint ID's consist major and minor numbers; the major number "
- "corresponds to the single entity that was created with a 'breakpoint set' "
- "command; the minor numbers correspond to all the locations that were actually "
- "found/set based on the major breakpoint. A full breakpoint ID might look like "
- "3.14, meaning the 14th location set for the 3rd breakpoint. You can specify "
- "all the locations of a breakpoint by just indicating the major breakpoint "
- "number. A valid breakpoint id consists either of just the major id number, "
- "or the major number, a dot, and the location number (e.g. 3 or 3.2 could "
- "both be valid breakpoint ids).";
+ return "Breakpoints are identified using major and minor numbers; the major "
+ "number corresponds to the single entity that was created with a 'breakpoint "
+ "set' command; the minor numbers correspond to all the locations that were "
+ "actually found/set based on the major breakpoint. A full breakpoint ID might "
+ "look like 3.14, meaning the 14th location set for the 3rd breakpoint. You "
+ "can specify all the locations of a breakpoint by just indicating the major "
+ "breakpoint number. A valid breakpoint ID consists either of just the major "
+ "number, or the major number followed by a dot and the location number (e.g. "
+ "3 or 3.2 could both be valid breakpoint IDs.)";
}
static const char *
BreakpointIDRangeHelpTextCallback ()
{
- return "A 'breakpoint id list' is a manner of specifying multiple breakpoints. "
- "This can be done through several mechanisms. The easiest way is to just "
- "enter a space-separated list of breakpoint ids. To specify all the "
- "breakpoint locations under a major breakpoint, you can use the major "
- "breakpoint number followed by '.*', eg. '5.*' means all the locations under "
- "breakpoint 5. You can also indicate a range of breakpoints by using "
- "<start-bp-id> - <end-bp-id>. The start-bp-id and end-bp-id for a range can "
- "be any valid breakpoint ids. It is not legal, however, to specify a range "
- "using specific locations that cross major breakpoint numbers. I.e. 3.2 - 3.7"
- " is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal.";
+ return "A 'breakpoint ID list' is a manner of specifying multiple breakpoints. "
+ "This can be done through several mechanisms. The easiest way is to just "
+ "enter a space-separated list of breakpoint IDs. To specify all the "
+ "breakpoint locations under a major breakpoint, you can use the major "
+ "breakpoint number followed by '.*', eg. '5.*' means all the locations under "
+ "breakpoint 5. You can also indicate a range of breakpoints by using "
+ "<start-bp-id> - <end-bp-id>. The start-bp-id and end-bp-id for a range can "
+ "be any valid breakpoint IDs. It is not legal, however, to specify a range "
+ "using specific locations that cross major breakpoint numbers. I.e. 3.2 - 3.7"
+ " is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal.";
}
static const char *
BreakpointNameHelpTextCallback ()
{
return "A name that can be added to a breakpoint when it is created, or later "
- "on with the \"breakpoint name add\" command. "
- "Breakpoint names can be used to specify breakpoints in all the places breakpoint ID's "
- "and breakpoint ID ranges can be used. As such they provide a convenient way to group breakpoints, "
- "and to operate on breakpoints you create without having to track the breakpoint number. "
- "Note, the attributes you set when using a breakpoint name in a breakpoint command don't "
- "adhere to the name, but instead are set individually on all the breakpoints currently tagged with that name. Future breakpoints "
- "tagged with that name will not pick up the attributes previously given using that name. "
- "In order to distinguish breakpoint names from breakpoint ID's and ranges, "
- "names must start with a letter from a-z or A-Z and cannot contain spaces, \".\" or \"-\". "
- "Also, breakpoint names can only be applied to breakpoints, not to breakpoint locations.";
+ "on with the \"breakpoint name add\" command. "
+ "Breakpoint names can be used to specify breakpoints in all the places breakpoint IDs "
+ "and breakpoint ID ranges can be used. As such they provide a convenient way to group breakpoints, "
+ "and to operate on breakpoints you create without having to track the breakpoint number. "
+ "Note, the attributes you set when using a breakpoint name in a breakpoint command don't "
+ "adhere to the name, but instead are set individually on all the breakpoints currently tagged with that "
+ "name. Future breakpoints "
+ "tagged with that name will not pick up the attributes previously given using that name. "
+ "In order to distinguish breakpoint names from breakpoint IDs and ranges, "
+ "names must start with a letter from a-z or A-Z and cannot contain spaces, \".\" or \"-\". "
+ "Also, breakpoint names can only be applied to breakpoints, not to breakpoint locations.";
}
static const char *
@@ -956,68 +917,46 @@ void
CommandObject::GenerateHelpText (Stream &output_strm)
{
CommandInterpreter& interpreter = GetCommandInterpreter();
- if (GetOptions() != nullptr)
+ if (WantsRawCommandString())
+ {
+ std::string help_text(GetHelp());
+ help_text.append(" Expects 'raw' input (see 'help raw-input'.)");
+ interpreter.OutputFormattedHelpText(output_strm, "", "", help_text.c_str(), 1);
+ }
+ else
+ interpreter.OutputFormattedHelpText(output_strm, "", "", GetHelp(), 1);
+ output_strm.Printf("\nSyntax: %s\n", GetSyntax());
+ Options *options = GetOptions();
+ if (options != nullptr)
+ {
+ options->GenerateOptionUsage(output_strm, this);
+ }
+ const char *long_help = GetHelpLong();
+ if ((long_help != nullptr) && (strlen(long_help) > 0))
+ {
+ FormatLongHelpText(output_strm, long_help);
+ }
+ if (!IsDashDashCommand() && options && options->NumCommandOptions() > 0)
{
- if (WantsRawCommandString())
- {
- std::string help_text (GetHelp());
- help_text.append (" This command takes 'raw' input (no need to quote stuff).");
- interpreter.OutputFormattedHelpText (output_strm, "", "", help_text.c_str(), 1);
- }
- else
- interpreter.OutputFormattedHelpText (output_strm, "", "", GetHelp(), 1);
- output_strm.Printf ("\nSyntax: %s\n", GetSyntax());
- GetOptions()->GenerateOptionUsage (output_strm, this);
- const char *long_help = GetHelpLong();
- if ((long_help != nullptr)
- && (strlen (long_help) > 0))
- FormatLongHelpText (output_strm, long_help);
if (WantsRawCommandString() && !WantsCompletion())
{
// Emit the message about using ' -- ' between the end of the command options and the raw input
// conditionally, i.e., only if the command object does not want completion.
- interpreter.OutputFormattedHelpText (output_strm, "", "",
- "\nIMPORTANT NOTE: Because this command takes 'raw' input, if you use any command options"
- " you must use ' -- ' between the end of the command options and the beginning of the raw input.", 1);
+ interpreter.OutputFormattedHelpText(
+ output_strm, "", "",
+ "\nImportant Note: Because this command takes 'raw' input, if you use any command options"
+ " you must use ' -- ' between the end of the command options and the beginning of the raw input.",
+ 1);
}
- else if (GetNumArgumentEntries() > 0
- && GetOptions()
- && GetOptions()->NumCommandOptions() > 0)
+ else if (GetNumArgumentEntries() > 0)
{
// Also emit a warning about using "--" in case you are using a command that takes options and arguments.
- interpreter.OutputFormattedHelpText (output_strm, "", "",
- "\nThis command takes options and free-form arguments. If your arguments resemble"
- " option specifiers (i.e., they start with a - or --), you must use ' -- ' between"
- " the end of the command options and the beginning of the arguments.", 1);
- }
- }
- else if (IsMultiwordObject())
- {
- if (WantsRawCommandString())
- {
- std::string help_text (GetHelp());
- help_text.append (" This command takes 'raw' input (no need to quote stuff).");
- interpreter.OutputFormattedHelpText (output_strm, "", "", help_text.c_str(), 1);
- }
- else
- interpreter.OutputFormattedHelpText (output_strm, "", "", GetHelp(), 1);
- GenerateHelpText (output_strm);
- }
- else
- {
- const char *long_help = GetHelpLong();
- if ((long_help != nullptr)
- && (strlen (long_help) > 0))
- FormatLongHelpText (output_strm, long_help);
- else if (WantsRawCommandString())
- {
- std::string help_text (GetHelp());
- help_text.append (" This command takes 'raw' input (no need to quote stuff).");
- interpreter.OutputFormattedHelpText (output_strm, "", "", help_text.c_str(), 1);
+ interpreter.OutputFormattedHelpText(
+ output_strm, "", "", "\nThis command takes options and free-form arguments. If your arguments resemble"
+ " option specifiers (i.e., they start with a - or --), you must use ' -- ' between"
+ " the end of the command options and the beginning of the arguments.",
+ 1);
}
- else
- interpreter.OutputFormattedHelpText (output_strm, "", "", GetHelp(), 1);
- output_strm.Printf ("\nSyntax: %s\n", GetSyntax());
}
}
@@ -1067,6 +1006,31 @@ CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy)
return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
}
+Thread *
+CommandObject::GetDefaultThread()
+{
+ Thread *thread_to_use = m_exe_ctx.GetThreadPtr();
+ if (thread_to_use)
+ return thread_to_use;
+
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (!process)
+ {
+ Target *target = m_exe_ctx.GetTargetPtr();
+ if (!target)
+ {
+ target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ }
+ if (target)
+ process = target->GetProcessSP().get();
+ }
+
+ if (process)
+ return process->GetThreadList().GetSelectedThread().get();
+ else
+ return nullptr;
+}
+
bool
CommandObjectParsed::Execute (const char *args_string, CommandReturnObject &result)
{
@@ -1138,9 +1102,8 @@ const char *arch_helper()
return g_archs_help.GetData();
}
-CommandObject::ArgumentTableEntry
-CommandObject::g_arguments_data[] =
-{
+CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
+ // clang-format off
{ eArgTypeAddress, "address", CommandCompletions::eNoCompletion, { nullptr, false }, "A valid address in the target program's execution space." },
{ eArgTypeAddressOrExpression, "address-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "An expression that resolves to an address." },
{ eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of an abbreviation (alias) for a debugger command." },
@@ -1170,7 +1133,7 @@ CommandObject::g_arguments_data[] =
{ eArgTypeGDBFormat, "gdb-format", CommandCompletions::eNoCompletion, { GDBFormatHelpTextCallback, true }, nullptr },
{ eArgTypeHelpText, "help-text", CommandCompletions::eNoCompletion, { nullptr, false }, "Text to be used as help for some other entity in LLDB" },
{ eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a list." },
- { eArgTypeLanguage, "language", CommandCompletions::eNoCompletion, { LanguageTypeHelpTextCallback, true }, nullptr },
+ { eArgTypeLanguage, "source-language", CommandCompletions::eNoCompletion, { LanguageTypeHelpTextCallback, true }, nullptr },
{ eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { nullptr, false }, "Line number in a source file." },
{ eArgTypeLogCategory, "log-category", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a category within a log channel, e.g. all (try \"log list\" to see a list of all channels and their categories." },
{ eArgTypeLogChannel, "log-channel", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a log channel, e.g. process.gdb-remote (try \"log list\" to see a list of all channels and their categories)." },
@@ -1198,7 +1161,7 @@ CommandObject::g_arguments_data[] =
{ eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
{ eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", CommandCompletions::eNoCompletion, { nullptr, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." },
{ eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, { nullptr, false }, "The scripting language to be used for script-based commands. Currently only Python is valid." },
- { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, { nullptr, false }, "The word for which you wish to search for information about." },
+ { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, { nullptr, false }, "Any word of interest for search purposes." },
{ eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, { nullptr, false }, "An Objective-C selector name." },
{ eArgTypeSettingIndex, "setting-index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a settings variable that is an array (try 'settings list' to see all the possible settings variables and their types)." },
{ eArgTypeSettingKey, "setting-key", CommandCompletions::eNoCompletion, { nullptr, false }, "A key into a settings variables that is a dictionary (try 'settings list' to see all the possible settings variables and their types)." },
@@ -1223,7 +1186,9 @@ CommandObject::g_arguments_data[] =
{ eArgTypePlatform, "platform-name", CommandCompletions::ePlatformPluginCompletion, { nullptr, false }, "The name of an installed platform plug-in . Type 'platform list' to see a complete list of installed platforms." },
{ eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Watchpoint IDs are positive integers." },
{ eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." },
- { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." }
+ { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." },
+ { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." }
+ // clang-format on
};
const CommandObject::ArgumentTableEntry*
diff --git a/source/Interpreter/CommandObjectScript.cpp b/source/Interpreter/CommandObjectScript.cpp
index 31e5311ab441..e7de490878fd 100644
--- a/source/Interpreter/CommandObjectScript.cpp
+++ b/source/Interpreter/CommandObjectScript.cpp
@@ -30,11 +30,10 @@ using namespace lldb_private;
// CommandObjectScript
//-------------------------------------------------------------------------
-CommandObjectScript::CommandObjectScript (CommandInterpreter &interpreter, ScriptLanguage script_lang) :
- CommandObjectRaw (interpreter,
- "script",
- "Pass an expression to the script interpreter for evaluation and return the results. Drop into the interactive interpreter if no expression is given.",
- "script [<script-expression-for-evaluation>]")
+CommandObjectScript::CommandObjectScript(CommandInterpreter &interpreter, ScriptLanguage script_lang)
+ : CommandObjectRaw(interpreter, "script", "Invoke the script interpreter with provided code and display any "
+ "results. Start the interactive interpreter if no code is supplied.",
+ "script [<script-code>]")
{
}
diff --git a/source/Interpreter/Makefile b/source/Interpreter/Makefile
deleted file mode 100644
index 2f25e6796604..000000000000
--- a/source/Interpreter/Makefile
+++ /dev/null
@@ -1,51 +0,0 @@
-##===- source/Interpreter/Makefile ------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LIBRARYNAME := lldbInterpreter
-BUILD_ARCHIVE = 1
-include $(LLDB_LEVEL)/../../Makefile.config
-
-ifneq ($(HOST_OS),MingW)
-ifeq (,$(findstring -DLLDB_DISABLE_PYTHON,$(CXXFLAGS)))
-DO_BUILD_LLDBWrapPython = 1
-BUILT_SOURCES := LLDBWrapPython.cpp
-endif
-endif
-
-include $(LLDB_LEVEL)/Makefile
--include $(PROJ_OBJ_DIR)/LLDBWrapPython.cpp.d
-
-ifeq ($(DO_BUILD_LLDBWrapPython),1)
-# Drop -Wfour-char-constants, which we are not currently clean with.
-EXTRA_OPTIONS += -Wno-four-char-constants
-
-# Drop -Wself-assign, -Wmissing-field-initializers, -Wsometimes-uninitialized,
-# -Wcast-qual, and -Wdeprecated-register which we are not clean with due to SWIG
-# generated cpp source.
-EXTRA_OPTIONS += -Wno-missing-field-initializers -Wno-self-assign -Wno-sometimes-uninitialized -Wno-cast-qual -Wno-deprecated-register
-
-PYTHON_DIR := $(PROJ_OBJ_ROOT)/$(BuildMode)
-
-SWIG_SOURCES := $(shell find $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts -type f -name '*.swig' -print)
-
-LLDBWrapPython.cpp lldb.py: $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/Python/modify-python-lldb.py \
- $(wildcard $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/interface/*.i) \
- ${SWIG_SOURCES}
- $(Echo) Generating LLDBWrapPython.cpp
- $(Verb) "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/prepare_bindings.py" "--src-root=$(PROJ_SRC_DIR)/$(LLDB_LEVEL)" "--target-dir=$(PROJ_OBJ_DIR)" "--config-build-dir=$(PROJ_OBJ_DIR)" "--prefix=$(PYTHON_DIR)" $(if $(DISABLE_AUTO_DEPENDENCIES),,-M) --find-swig
- $(Verb) "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/finish-swig-wrapper-classes.sh" "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)" "$(PROJ_OBJ_DIR)" "$(PROJ_OBJ_DIR)" "$(PYTHON_DIR)" -m
-
-install-local:: lldb.py
- $(Echo) Installing $(BuildMode) LLDB python modules
- $(Verb) "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/prepare_bindings.py" "--src-root=$(PROJ_SRC_DIR)/$(LLDB_LEVEL)" "--target-dir=$(PROJ_OBJ_DIR)" "--config-build-dir=$(PROJ_OBJ_DIR)" "--prefix=$(DESTDIR)$(prefix)" --find-swig
-
-clean-local::
- $(Verb) $(RM) -f LLDBWrapPython.cpp lldb.py
-endif
diff --git a/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
index bbd966859c34..c30a978d9577 100644
--- a/source/Interpreter/OptionGroupValueObjectDisplay.cpp
+++ b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
@@ -44,7 +44,8 @@ g_option_table[] =
{ LLDB_OPT_SET_1, false, "no-summary-depth", 'Y', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the depth at which omitting summary information stops (default is 1)."},
{ LLDB_OPT_SET_1, false, "raw-output", 'R', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use formatting options."},
{ LLDB_OPT_SET_1, false, "show-all-children", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Ignore the upper bound on the number of children to show."},
- { LLDB_OPT_SET_1, false, "validate", 'V', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Show results of type validators."},
+ { LLDB_OPT_SET_1, false, "validate", 'V', OptionParser::eRequiredArgument, nullptr, nullptr,0, eArgTypeBoolean, "Show results of type validators."},
+ { LLDB_OPT_SET_1, false, "element-count", 'Z', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Treat the result of the expression as if its type is an array of this many values."},
{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
@@ -92,6 +93,12 @@ OptionGroupValueObjectDisplay::SetOptionValue (CommandInterpreter &interpreter,
if (!success)
error.SetErrorStringWithFormat("invalid max depth '%s'", option_arg);
break;
+
+ case 'Z':
+ elem_count = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success);
+ if (!success)
+ error.SetErrorStringWithFormat("invalid element count '%s'", option_arg);
+ break;
case 'P':
ptr_depth = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
@@ -141,6 +148,7 @@ OptionGroupValueObjectDisplay::OptionParsingStarting (CommandInterpreter &interp
use_objc = false;
max_depth = UINT32_MAX;
ptr_depth = 0;
+ elem_count = 0;
use_synth = true;
be_raw = false;
ignore_cap = false;
@@ -187,6 +195,8 @@ OptionGroupValueObjectDisplay::GetAsDumpOptions (LanguageRuntimeDescriptionDispl
options.SetRawDisplay();
options.SetRunValidator(run_validator);
+
+ options.SetElementCount(elem_count);
return options;
}
diff --git a/source/Interpreter/OptionValueArray.cpp b/source/Interpreter/OptionValueArray.cpp
index aabe457534d6..348414f432c9 100644
--- a/source/Interpreter/OptionValueArray.cpp
+++ b/source/Interpreter/OptionValueArray.cpp
@@ -316,6 +316,7 @@ OptionValueArray::SetArgs (const Args &args, VarSetOperationType op)
case eVarSetOperationAssign:
m_values.clear();
// Fall through to append case
+ LLVM_FALLTHROUGH;
case eVarSetOperationAppend:
for (size_t i=0; i<argc; ++i)
{
diff --git a/source/Interpreter/OptionValueFileSpecLIst.cpp b/source/Interpreter/OptionValueFileSpecLIst.cpp
index 669d3ee33acc..6a0ba11b676c 100644
--- a/source/Interpreter/OptionValueFileSpecLIst.cpp
+++ b/source/Interpreter/OptionValueFileSpecLIst.cpp
@@ -88,6 +88,7 @@ OptionValueFileSpecList::SetValueFromString (llvm::StringRef value, VarSetOperat
case eVarSetOperationAssign:
m_current_value.Clear();
// Fall through to append case
+ LLVM_FALLTHROUGH;
case eVarSetOperationAppend:
if (argc > 0)
{
diff --git a/source/Interpreter/OptionValuePathMappings.cpp b/source/Interpreter/OptionValuePathMappings.cpp
index 722d6a144279..f3f146f1f8c6 100644
--- a/source/Interpreter/OptionValuePathMappings.cpp
+++ b/source/Interpreter/OptionValuePathMappings.cpp
@@ -14,11 +14,24 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Stream.h"
+#include "lldb/Host/FileSpec.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Args.h"
using namespace lldb;
using namespace lldb_private;
+namespace
+{
+ static bool
+ VerifyPathExists(const char *path)
+ {
+ if (path && path[0])
+ return FileSpec(path, false).Exists();
+ else
+ return false;
+ }
+}
+
void
OptionValuePathMappings::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
@@ -59,14 +72,27 @@ OptionValuePathMappings::SetValueFromString (llvm::StringRef value, VarSetOperat
}
else
{
+ bool changed = false;
for (size_t i=1; i<argc; i += 2, ++idx)
{
- ConstString a(args.GetArgumentAtIndex(i));
- ConstString b(args.GetArgumentAtIndex(i+1));
- if (!m_path_mappings.Replace (a, b, idx, m_notify_changes))
- m_path_mappings.Append(a, b, m_notify_changes);
+ const char *orginal_path = args.GetArgumentAtIndex(i);
+ const char *replace_path = args.GetArgumentAtIndex(i+1);
+ if (VerifyPathExists(replace_path))
+ {
+ ConstString a(orginal_path);
+ ConstString b(replace_path);
+ if (!m_path_mappings.Replace (a, b, idx, m_notify_changes))
+ m_path_mappings.Append(a, b, m_notify_changes);
+ changed = true;
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("the replacement path doesn't exist: \"%s\"", replace_path);
+ break;
+ }
}
- NotifyValueChanged();
+ if (changed)
+ NotifyValueChanged();
}
}
else
@@ -85,6 +111,7 @@ OptionValuePathMappings::SetValueFromString (llvm::StringRef value, VarSetOperat
}
m_path_mappings.Clear(m_notify_changes);
// Fall through to append case
+ LLVM_FALLTHROUGH;
case eVarSetOperationAppend:
if (argc < 2 || (argc & 1))
{
@@ -93,14 +120,27 @@ OptionValuePathMappings::SetValueFromString (llvm::StringRef value, VarSetOperat
}
else
{
+ bool changed = false;
for (size_t i=0; i<argc; i += 2)
{
- ConstString a(args.GetArgumentAtIndex(i));
- ConstString b(args.GetArgumentAtIndex(i+1));
- m_path_mappings.Append(a, b, m_notify_changes);
- m_value_was_set = true;
+ const char *orginal_path = args.GetArgumentAtIndex(i);
+ const char *replace_path = args.GetArgumentAtIndex(i+1);
+ if (VerifyPathExists(replace_path))
+ {
+ ConstString a(orginal_path);
+ ConstString b(replace_path);
+ m_path_mappings.Append(a, b, m_notify_changes);
+ m_value_was_set = true;
+ changed = true;
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("the replacement path doesn't exist: \"%s\"", replace_path);
+ break;
+ }
}
- NotifyValueChanged();
+ if (changed)
+ NotifyValueChanged();
}
break;
@@ -117,15 +157,28 @@ OptionValuePathMappings::SetValueFromString (llvm::StringRef value, VarSetOperat
}
else
{
+ bool changed = false;
if (op == eVarSetOperationInsertAfter)
++idx;
for (size_t i=1; i<argc; i += 2, ++idx)
{
- ConstString a(args.GetArgumentAtIndex(i));
- ConstString b(args.GetArgumentAtIndex(i+1));
- m_path_mappings.Insert (a, b, idx, m_notify_changes);
+ const char *orginal_path = args.GetArgumentAtIndex(i);
+ const char *replace_path = args.GetArgumentAtIndex(i+1);
+ if (VerifyPathExists(replace_path))
+ {
+ ConstString a(orginal_path);
+ ConstString b(replace_path);
+ m_path_mappings.Insert (a, b, idx, m_notify_changes);
+ changed = true;
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("the replacement path doesn't exist: \"%s\"", replace_path);
+ break;
+ }
}
- NotifyValueChanged();
+ if (changed)
+ NotifyValueChanged();
}
}
else
diff --git a/source/Interpreter/OptionValueProperties.cpp b/source/Interpreter/OptionValueProperties.cpp
index a3c28f70270f..7024c3601d9f 100644
--- a/source/Interpreter/OptionValueProperties.cpp
+++ b/source/Interpreter/OptionValueProperties.cpp
@@ -164,8 +164,23 @@ OptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx,
switch (sub_name[0])
{
case '.':
- return value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error);
-
+ {
+ lldb::OptionValueSP return_val_sp;
+ return_val_sp = value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error);
+ if (!return_val_sp)
+ {
+ if (Properties::IsSettingExperimental(sub_name + 1))
+ {
+ size_t experimental_len = strlen(Properties::GetExperimentalSettingsName());
+ if (*(sub_name + experimental_len + 1) == '.')
+ return_val_sp = value_sp->GetSubValue(exe_ctx, sub_name + experimental_len + 2, will_modify, error);
+ // It isn't an error if an experimental setting is not present.
+ if (!return_val_sp)
+ error.Clear();
+ }
+ }
+ return return_val_sp;
+ }
case '{':
// Predicate matching for predicates like
// "<setting-name>{<predicate>}"
diff --git a/source/Interpreter/Options.cpp b/source/Interpreter/Options.cpp
index 7f0e0abc03ea..70f532ed75de 100644
--- a/source/Interpreter/Options.cpp
+++ b/source/Interpreter/Options.cpp
@@ -14,6 +14,7 @@
#include <algorithm>
#include <bitset>
#include <map>
+#include <set>
// Other libraries and framework includes
// Project includes
@@ -477,6 +478,7 @@ Options::GenerateOptionUsage
CommandObject *cmd
)
{
+ const bool only_print_args = cmd->IsDashDashCommand();
const uint32_t screen_width = m_interpreter.GetDebugger().GetTerminalWidth();
const OptionDefinition *opt_defs = GetDefinitions();
@@ -509,203 +511,211 @@ Options::GenerateOptionUsage
uint32_t i;
- for (uint32_t opt_set = 0; opt_set < num_option_sets; ++opt_set)
+ if (!only_print_args)
{
- uint32_t opt_set_mask;
-
- opt_set_mask = 1 << opt_set;
- if (opt_set > 0)
- strm.Printf ("\n");
- strm.Indent (name);
-
- // Different option sets may require different args.
- StreamString args_str;
- if (cmd)
- cmd->GetFormattedCommandArguments(args_str, opt_set_mask);
-
- // First go through and print all options that take no arguments as
- // a single string. If a command has "-a" "-b" and "-c", this will show
- // up as [-abc]
-
- std::set<int> options;
- std::set<int>::const_iterator options_pos, options_end;
- for (i = 0; i < num_options; ++i)
+ for (uint32_t opt_set = 0; opt_set < num_option_sets; ++opt_set)
{
- if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
+ uint32_t opt_set_mask;
+
+ opt_set_mask = 1 << opt_set;
+ if (opt_set > 0)
+ strm.Printf ("\n");
+ strm.Indent (name);
+
+ // Different option sets may require different args.
+ StreamString args_str;
+ if (cmd)
+ cmd->GetFormattedCommandArguments(args_str, opt_set_mask);
+
+ // First go through and print all options that take no arguments as
+ // a single string. If a command has "-a" "-b" and "-c", this will show
+ // up as [-abc]
+
+ std::set<int> options;
+ std::set<int>::const_iterator options_pos, options_end;
+ for (i = 0; i < num_options; ++i)
{
- // Add current option to the end of out_stream.
-
- if (opt_defs[i].required == true &&
- opt_defs[i].option_has_arg == OptionParser::eNoArgument)
+ if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
{
- options.insert (opt_defs[i].short_option);
- }
- }
- }
+ // Add current option to the end of out_stream.
- if (options.empty() == false)
- {
- // We have some required options with no arguments
- strm.PutCString(" -");
- for (i=0; i<2; ++i)
- for (options_pos = options.begin(), options_end = options.end();
- options_pos != options_end;
- ++options_pos)
- {
- if (i==0 && ::islower (*options_pos))
- continue;
- if (i==1 && ::isupper (*options_pos))
- continue;
- strm << (char)*options_pos;
+ if (opt_defs[i].required == true &&
+ opt_defs[i].option_has_arg == OptionParser::eNoArgument)
+ {
+ options.insert (opt_defs[i].short_option);
+ }
}
- }
+ }
- for (i = 0, options.clear(); i < num_options; ++i)
- {
- if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
+ if (options.empty() == false)
{
- // Add current option to the end of out_stream.
+ // We have some required options with no arguments
+ strm.PutCString(" -");
+ for (i=0; i<2; ++i)
+ for (options_pos = options.begin(), options_end = options.end();
+ options_pos != options_end;
+ ++options_pos)
+ {
+ if (i==0 && ::islower (*options_pos))
+ continue;
+ if (i==1 && ::isupper (*options_pos))
+ continue;
+ strm << (char)*options_pos;
+ }
+ }
- if (opt_defs[i].required == false &&
- opt_defs[i].option_has_arg == OptionParser::eNoArgument)
+ for (i = 0, options.clear(); i < num_options; ++i)
+ {
+ if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
{
- options.insert (opt_defs[i].short_option);
+ // Add current option to the end of out_stream.
+
+ if (opt_defs[i].required == false &&
+ opt_defs[i].option_has_arg == OptionParser::eNoArgument)
+ {
+ options.insert (opt_defs[i].short_option);
+ }
}
}
- }
- if (options.empty() == false)
- {
- // We have some required options with no arguments
- strm.PutCString(" [-");
- for (i=0; i<2; ++i)
- for (options_pos = options.begin(), options_end = options.end();
- options_pos != options_end;
- ++options_pos)
- {
- if (i==0 && ::islower (*options_pos))
- continue;
- if (i==1 && ::isupper (*options_pos))
- continue;
- strm << (char)*options_pos;
- }
- strm.PutChar(']');
- }
+ if (options.empty() == false)
+ {
+ // We have some required options with no arguments
+ strm.PutCString(" [-");
+ for (i=0; i<2; ++i)
+ for (options_pos = options.begin(), options_end = options.end();
+ options_pos != options_end;
+ ++options_pos)
+ {
+ if (i==0 && ::islower (*options_pos))
+ continue;
+ if (i==1 && ::isupper (*options_pos))
+ continue;
+ strm << (char)*options_pos;
+ }
+ strm.PutChar(']');
+ }
- // First go through and print the required options (list them up front).
-
- for (i = 0; i < num_options; ++i)
- {
- if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
+ // First go through and print the required options (list them up front).
+
+ for (i = 0; i < num_options; ++i)
{
- if (opt_defs[i].required && opt_defs[i].option_has_arg != OptionParser::eNoArgument)
- PrintOption (opt_defs[i], eDisplayBestOption, " ", nullptr, true, strm);
+ if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
+ {
+ if (opt_defs[i].required && opt_defs[i].option_has_arg != OptionParser::eNoArgument)
+ PrintOption (opt_defs[i], eDisplayBestOption, " ", nullptr, true, strm);
+ }
}
- }
- // Now go through again, and this time only print the optional options.
+ // Now go through again, and this time only print the optional options.
- for (i = 0; i < num_options; ++i)
- {
- if (opt_defs[i].usage_mask & opt_set_mask)
+ for (i = 0; i < num_options; ++i)
{
- // Add current option to the end of out_stream.
+ if (opt_defs[i].usage_mask & opt_set_mask)
+ {
+ // Add current option to the end of out_stream.
- if (!opt_defs[i].required && opt_defs[i].option_has_arg != OptionParser::eNoArgument)
- PrintOption (opt_defs[i], eDisplayBestOption, " ", nullptr, true, strm);
+ if (!opt_defs[i].required && opt_defs[i].option_has_arg != OptionParser::eNoArgument)
+ PrintOption (opt_defs[i], eDisplayBestOption, " ", nullptr, true, strm);
+ }
}
- }
-
- if (args_str.GetSize() > 0)
- {
- if (cmd->WantsRawCommandString())
- strm.Printf(" --");
- strm.Printf (" %s", args_str.GetData());
+ if (args_str.GetSize() > 0)
+ {
+ if (cmd->WantsRawCommandString() && !only_print_args)
+ strm.Printf(" --");
+
+ strm.Printf (" %s", args_str.GetData());
+ if (only_print_args)
+ break;
+ }
}
}
if (cmd &&
- cmd->WantsRawCommandString() &&
+ (only_print_args || cmd->WantsRawCommandString()) &&
arguments_str.GetSize() > 0)
{
- strm.PutChar('\n');
+ if (!only_print_args) strm.PutChar('\n');
strm.Indent(name);
strm.Printf(" %s", arguments_str.GetData());
}
strm.Printf ("\n\n");
- // Now print out all the detailed information about the various options: long form, short form and help text:
- // -short <argument> ( --long_name <argument> )
- // help text
+ if (!only_print_args)
+ {
+ // Now print out all the detailed information about the various options: long form, short form and help text:
+ // -short <argument> ( --long_name <argument> )
+ // help text
- // This variable is used to keep track of which options' info we've printed out, because some options can be in
- // more than one usage level, but we only want to print the long form of its information once.
+ // This variable is used to keep track of which options' info we've printed out, because some options can be in
+ // more than one usage level, but we only want to print the long form of its information once.
- std::multimap<int, uint32_t> options_seen;
- strm.IndentMore (5);
+ std::multimap<int, uint32_t> options_seen;
+ strm.IndentMore (5);
- // Put the unique command options in a vector & sort it, so we can output them alphabetically (by short_option)
- // when writing out detailed help for each option.
+ // Put the unique command options in a vector & sort it, so we can output them alphabetically (by short_option)
+ // when writing out detailed help for each option.
- for (i = 0; i < num_options; ++i)
- options_seen.insert(std::make_pair(opt_defs[i].short_option, i));
+ for (i = 0; i < num_options; ++i)
+ options_seen.insert(std::make_pair(opt_defs[i].short_option, i));
- // Go through the unique'd and alphabetically sorted vector of options, find the table entry for each option
- // and write out the detailed help information for that option.
+ // Go through the unique'd and alphabetically sorted vector of options, find the table entry for each option
+ // and write out the detailed help information for that option.
- bool first_option_printed = false;;
+ bool first_option_printed = false;;
- for (auto pos : options_seen)
- {
- i = pos.second;
- //Print out the help information for this option.
+ for (auto pos : options_seen)
+ {
+ i = pos.second;
+ //Print out the help information for this option.
- // Put a newline separation between arguments
- if (first_option_printed)
- strm.EOL();
- else
- first_option_printed = true;
-
- CommandArgumentType arg_type = opt_defs[i].argument_type;
-
- StreamString arg_name_str;
- arg_name_str.Printf ("<%s>", CommandObject::GetArgumentName (arg_type));
+ // Put a newline separation between arguments
+ if (first_option_printed)
+ strm.EOL();
+ else
+ first_option_printed = true;
+
+ CommandArgumentType arg_type = opt_defs[i].argument_type;
+
+ StreamString arg_name_str;
+ arg_name_str.Printf ("<%s>", CommandObject::GetArgumentName (arg_type));
- strm.Indent ();
- if (opt_defs[i].short_option && isprint8(opt_defs[i].short_option))
- {
- PrintOption (opt_defs[i], eDisplayShortOption, nullptr, nullptr, false, strm);
- PrintOption (opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm);
- }
- else
- {
- // Short option is not printable, just print long option
- PrintOption (opt_defs[i], eDisplayLongOption, nullptr, nullptr, false, strm);
- }
- strm.EOL();
-
- strm.IndentMore (5);
-
- if (opt_defs[i].usage_text)
- OutputFormattedUsageText (strm,
- opt_defs[i],
- screen_width);
- if (opt_defs[i].enum_values != nullptr)
- {
strm.Indent ();
- strm.Printf("Values: ");
- for (int k = 0; opt_defs[i].enum_values[k].string_value != nullptr; k++)
+ if (opt_defs[i].short_option && isprint8(opt_defs[i].short_option))
{
- if (k == 0)
- strm.Printf("%s", opt_defs[i].enum_values[k].string_value);
- else
- strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value);
+ PrintOption (opt_defs[i], eDisplayShortOption, nullptr, nullptr, false, strm);
+ PrintOption (opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm);
+ }
+ else
+ {
+ // Short option is not printable, just print long option
+ PrintOption (opt_defs[i], eDisplayLongOption, nullptr, nullptr, false, strm);
}
strm.EOL();
+
+ strm.IndentMore (5);
+
+ if (opt_defs[i].usage_text)
+ OutputFormattedUsageText (strm,
+ opt_defs[i],
+ screen_width);
+ if (opt_defs[i].enum_values != nullptr)
+ {
+ strm.Indent ();
+ strm.Printf("Values: ");
+ for (int k = 0; opt_defs[i].enum_values[k].string_value != nullptr; k++)
+ {
+ if (k == 0)
+ strm.Printf("%s", opt_defs[i].enum_values[k].string_value);
+ else
+ strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value);
+ }
+ strm.EOL();
+ }
+ strm.IndentLess (5);
}
- strm.IndentLess (5);
}
// Restore the indent level
@@ -954,6 +964,13 @@ Options::HandleOptionArgumentCompletion
for (size_t i = 0; i < opt_element_vector.size(); i++)
{
int cur_defs_index = opt_element_vector[i].opt_defs_index;
+
+ // trying to use <0 indices will definitely cause problems
+ if (cur_defs_index == OptionArgElement::eUnrecognizedArg ||
+ cur_defs_index == OptionArgElement::eBareDash ||
+ cur_defs_index == OptionArgElement::eBareDoubleDash)
+ continue;
+
int cur_arg_pos = opt_element_vector[i].opt_arg_pos;
const char *cur_opt_name = opt_defs[cur_defs_index].long_option;
diff --git a/source/Makefile b/source/Makefile
deleted file mode 100644
index 0ad56ffa5e0c..000000000000
--- a/source/Makefile
+++ /dev/null
@@ -1,37 +0,0 @@
-##===- source/Makefile -------------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ..
-PARALLEL_DIRS := API Initialization Breakpoint Commands Core DataFormatters Expression Host Interpreter Plugins Symbol Target Utility
-LIBRARYNAME := lldbBase
-BUILD_ARCHIVE = 1
-
-# Although LLVM makefiles provide $(HOST_OS), we cannot use that here because it is defined by including the $(LLDB_LEVEL)/Makefile
-# below. Instead, we use uname -s to detect the HOST_OS and generate LLDB_vers.c only on Mac. On Linux, the version number is
-# calculated in the same way as Clang's version.
-ifeq (Darwin,$(shell uname -s))
-BUILT_SOURCES = LLDB_vers.c
-endif
-
-SOURCES := lldb.cpp
-
-include $(LLDB_LEVEL)/Makefile
-
-ifeq ($(HOST_OS),Darwin)
-LLDB_vers.c: $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/lldb.xcodeproj/project.pbxproj
- "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl" "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/lldb.xcodeproj/project.pbxproj" liblldb_core > LLDB_vers.c
-else
-LLDB_REVISION := $(strip \
- $(shell $(LLVM_SRC_ROOT)/utils/GetSourceVersion $(LLVM_SRC_ROOT)/tools/lldb))
-
-LLDB_REPOSITORY := $(strip \
- $(shell $(LLVM_SRC_ROOT)/utils/GetRepositoryPath $(LLVM_SRC_ROOT)/tools/lldb))
-
-CPP.Defines += -DLLDB_REVISION='"$(LLDB_REVISION)"' -DLLDB_REPOSITORY='"$(LLDB_REPOSITORY)"'
-endif
diff --git a/source/Plugins/ABI/CMakeLists.txt b/source/Plugins/ABI/CMakeLists.txt
index 08452c5dad62..9d7a79308d7b 100644
--- a/source/Plugins/ABI/CMakeLists.txt
+++ b/source/Plugins/ABI/CMakeLists.txt
@@ -5,6 +5,7 @@ add_subdirectory(SysV-ppc)
add_subdirectory(SysV-ppc64)
add_subdirectory(SysV-mips)
add_subdirectory(SysV-mips64)
+add_subdirectory(SysV-s390x)
add_subdirectory(SysV-i386)
add_subdirectory(SysV-x86_64)
add_subdirectory(MacOSX-i386)
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index 3b9b0f346072..ea906f613890 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -1,4 +1,4 @@
-//===-- ABIMacOSX_arm.cpp --------------------------------------*- C++ -*-===//
+//===-- ABIMacOSX_arm.cpp ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,6 +9,15 @@
#include "ABIMacOSX_arm.h"
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Module.h"
@@ -23,15 +32,10 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
#include "Utility/ARM_DWARF_Registers.h"
#include "Utility/ARM_ehframe_Registers.h"
#include "Plugins/Process/Utility/ARMDefines.h"
-#include <vector>
-
using namespace lldb;
using namespace lldb_private;
@@ -39,111 +43,112 @@ static RegisterInfo g_register_infos[] =
{
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
// ========== ======= == === ============= ============ ======================= =================== =========================== ======================= ====================== ========== ===============
- { "r0", "arg1", 4, 0, eEncodingUint , eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r1", "arg2", 4, 0, eEncodingUint , eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r2", "arg3", 4, 0, eEncodingUint , eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r3", "arg4", 4, 0, eEncodingUint , eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r4", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r5", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r6", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r7", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r8", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r9", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r10", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r11", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r12", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "sp", "r13", 4, 0, eEncodingUint , eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "lr", "r14", 4, 0, eEncodingUint , eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "pc", "r15", 4, 0, eEncodingUint , eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "cpsr", "psr", 4, 0, eEncodingUint , eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s0", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s1", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s2", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s3", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s4", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s5", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s6", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s7", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s8", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s9", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s10", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s11", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s12", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s13", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s14", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s15", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s16", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s17", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s18", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s19", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s20", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s21", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s22", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s23", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s24", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s25", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s26", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s27", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s28", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s29", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s30", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s31", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fpscr", NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d0", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d1", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d2", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d3", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d4", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d5", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d6", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d7", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d8", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d9", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d10", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d11", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d12", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d13", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d14", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d15", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d16", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d17", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d18", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d19", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d20", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d21", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d22", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d23", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d24", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d25", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d26", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d27", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d28", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d29", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d30", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d31", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r8_usr", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r9_usr", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r10_usr", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r11_usr", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r12_usr", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13_usr", "sp_usr", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14_usr", "lr_usr", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r8_fiq", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r9_fiq", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r10_fiq", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r11_fiq", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r12_fiq", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13_fiq", "sp_fiq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14_fiq", "lr_fiq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13_irq", "sp_irq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14_irq", "lr_irq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13_abt", "sp_abt", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14_abt", "lr_abt", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13_und", "sp_und", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14_und", "lr_und", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13_svc", "sp_svc", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14_svc", "lr_svc", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL}
+ { "r0", "arg1", 4, 0, eEncodingUint , eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r1", "arg2", 4, 0, eEncodingUint , eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r2", "arg3", 4, 0, eEncodingUint , eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r3", "arg4", 4, 0, eEncodingUint , eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r4", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r5", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r6", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r7", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r8", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r9", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r10", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r11", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r12", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "sp", "r13", 4, 0, eEncodingUint , eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "lr", "r14", 4, 0, eEncodingUint , eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "pc", "r15", 4, 0, eEncodingUint , eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "cpsr", "psr", 4, 0, eEncodingUint , eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s0", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s1", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s2", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s3", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s4", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s5", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s6", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s7", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s8", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s9", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s10", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s11", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s12", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s13", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s14", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s15", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s16", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s17", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s18", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s19", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s20", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s21", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s22", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s23", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s24", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s25", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s26", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s27", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s28", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s29", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s30", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s31", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fpscr", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d0", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d1", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d2", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d3", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d4", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d5", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d6", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d7", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d8", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d9", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d10", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d11", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d12", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d13", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d14", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d15", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d16", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d17", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d18", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d19", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d20", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d21", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d22", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d23", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d24", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d25", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d26", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d27", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d28", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d29", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d30", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d31", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r8_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r9_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r10_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r11_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r12_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13_usr", "sp_usr", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14_usr", "lr_usr", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r8_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r9_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r10_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r11_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r12_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13_fiq", "sp_fiq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14_fiq", "lr_fiq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13_irq", "sp_irq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14_irq", "lr_irq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13_abt", "sp_abt", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14_abt", "lr_abt", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13_und", "sp_und", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14_und", "lr_und", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13_svc", "sp_svc", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14_svc", "lr_svc", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr }
};
+
static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
static bool g_register_info_names_constified = false;
@@ -156,7 +161,7 @@ ABIMacOSX_arm::GetRegisterInfoArray (uint32_t &count)
if (!g_register_info_names_constified)
{
g_register_info_names_constified = true;
- for (uint32_t i=0; i<k_num_register_infos; ++i)
+ for (uint32_t i = 0; i < k_num_register_infos; ++i)
{
if (g_register_infos[i].name)
g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
@@ -168,7 +173,6 @@ ABIMacOSX_arm::GetRegisterInfoArray (uint32_t &count)
return g_register_infos;
}
-
size_t
ABIMacOSX_arm::GetRedZoneSize () const
{
@@ -178,6 +182,7 @@ ABIMacOSX_arm::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
ABISP
ABIMacOSX_arm::CreateInstance (const ArchSpec &arch)
{
@@ -308,8 +313,7 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread,
ValueList &values) const
{
uint32_t num_values = values.GetSize();
-
-
+
ExecutionContext exe_ctx (thread.shared_from_this());
// For now, assume that the types in the AST values come from the Target's
// scratch AST.
@@ -337,7 +341,7 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread,
{
bool is_signed = false;
size_t bit_width = 0;
- if (compiler_type.IsIntegerType (is_signed))
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed))
{
bit_width = compiler_type.GetBitSize(&thread);
}
@@ -356,7 +360,7 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread,
if (value_idx < 4)
{
// Arguments 1-4 are in r0-r3...
- const RegisterInfo *arg_reg_info = NULL;
+ const RegisterInfo *arg_reg_info = nullptr;
// Search by generic ID first, then fall back to by name
uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
if (arg_reg_num != LLDB_INVALID_REGNUM)
@@ -455,7 +459,7 @@ ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread,
// when reading data
const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
- if (compiler_type.IsIntegerType (is_signed))
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed))
{
size_t bit_width = compiler_type.GetBitSize(&thread);
@@ -594,7 +598,7 @@ ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObj
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
bool set_it_simple = false;
- if (compiler_type.IsIntegerType (is_signed) || compiler_type.IsPointerType())
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
{
DataExtractor data;
Error data_error;
@@ -843,6 +847,7 @@ ABIMacOSX_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
default:
break;
}
+ break;
case '4':
case '5':
case '6':
@@ -878,30 +883,14 @@ ABIMacOSX_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
break;
case '2':
- switch (name[2])
- {
- case '\0':
- return true; // s2 is volatile
- default:
- break;
- }
- break;
-
case '3':
- switch (name[2])
- {
- case '\0':
- return true; // s3 is volatile
- default:
- break;
- }
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
- return name[2] == '\0'; // s4 - s9 are volatile
+ return name[2] == '\0'; // s2 - s9 are volatile
default:
break;
@@ -926,7 +915,8 @@ ABIMacOSX_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
default:
break;
};
- case '0':
+ break;
+ case '0':
case '2':
case '3':
return name[2] == '\0'; // q0-q3 are volatile
@@ -967,6 +957,7 @@ ABIMacOSX_arm::GetPluginNameStatic()
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
lldb_private::ConstString
ABIMacOSX_arm::GetPluginName()
{
@@ -978,4 +969,3 @@ ABIMacOSX_arm::GetPluginVersion()
{
return 1;
}
-
diff --git a/source/Plugins/ABI/MacOSX-arm/Makefile b/source/Plugins/ABI/MacOSX-arm/Makefile
deleted file mode 100644
index 18073266d34d..000000000000
--- a/source/Plugins/ABI/MacOSX-arm/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ABI/MacOSX-arm/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===--------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginABIMacOSX_arm
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
index 0e6f9d663ae8..ad3d8cb03b86 100644
--- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
+++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
@@ -9,6 +9,14 @@
#include "ABIMacOSX_arm64.h"
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
@@ -25,159 +33,153 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
#include "Utility/ARM64_DWARF_Registers.h"
-#include <vector>
-
using namespace lldb;
using namespace lldb_private;
static const char *pluginDesc = "Mac OS X ABI for arm64 targets";
-
static RegisterInfo g_register_infos[] =
{
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE
// ========== ======= == === ============= =================== =================== ====================== =========================== ======================= ======================
- { "x0", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x1", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x2", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x3", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x4", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x5", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x6", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x7", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x8", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x9", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x10", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x11", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x12", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x13", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x14", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x15", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x16", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x17", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x18", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x19", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x20", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x21", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x22", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x23", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x24", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x25", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x26", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x27", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x28", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "fp", "x29", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "lr", "x30", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "sp", "x31", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "pc", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "cpsr", "psr", 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
-
- { "v0", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v1", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v2", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v3", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v4", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v5", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v6", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v7", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v8", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v9", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v10", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v11", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v12", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v13", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v14", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v15", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v16", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v17", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v18", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v19", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v20", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v21", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v22", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v23", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v24", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v25", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v26", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v27", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v28", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v29", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v30", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v31", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
-
- { "fpsr", NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "fpcr", NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
-
- { "s0", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s1", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s2", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s3", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s4", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s5", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s6", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s7", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s8", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s9", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s10", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s11", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s12", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s13", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s14", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s15", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s16", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s17", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s18", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s19", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s20", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s21", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s22", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s23", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s24", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s25", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s26", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s27", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s28", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s29", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s30", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s31", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
-
- { "d0", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d1", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d2", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d3", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d4", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d5", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d6", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d7", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d8", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d9", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d10", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d11", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d12", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d13", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d14", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d15", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d16", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d17", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d18", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d19", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d20", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d21", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d22", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d23", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d24", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d25", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d26", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d27", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d28", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d29", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d30", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d31", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL }
+ { "x0", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x1", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x2", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x3", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x4", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x5", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x6", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x7", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x8", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x9", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x10", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x11", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x12", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x13", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x14", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x15", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x16", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x17", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x18", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x19", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x20", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x21", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x22", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x23", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x24", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x25", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x26", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x27", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x28", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fp", "x29", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "lr", "x30", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "sp", "x31", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "pc", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "cpsr", "psr", 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+
+ { "v0", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v1", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v2", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v3", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v4", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v5", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v6", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v7", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v8", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v9", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v10", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v11", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v12", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v13", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v14", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v15", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v16", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v17", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v18", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v19", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v20", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v21", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v22", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v23", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v24", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v25", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v26", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v27", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v28", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v29", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v30", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v31", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+
+ { "fpsr", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fpcr", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+
+ { "s0", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s1", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s2", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s3", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s4", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s5", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s6", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s7", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s8", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s9", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s10", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s11", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s12", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s13", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s14", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s15", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s16", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s17", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s18", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s19", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s20", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s21", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s22", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s23", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s24", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s25", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s26", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s27", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s28", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s29", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s30", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s31", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+
+ { "d0", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d1", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d2", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d3", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d4", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d5", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d6", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d7", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d8", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d9", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d10", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d11", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d12", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d13", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d14", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d15", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d16", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d17", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d18", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d19", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d20", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d21", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d22", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d23", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d24", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d25", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d26", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d27", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d28", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d29", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d30", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d31", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr }
};
static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
@@ -192,7 +194,7 @@ ABIMacOSX_arm64::GetRegisterInfoArray (uint32_t &count)
if (!g_register_info_names_constified)
{
g_register_info_names_constified = true;
- for (uint32_t i=0; i<k_num_register_infos; ++i)
+ for (uint32_t i = 0; i < k_num_register_infos; ++i)
{
if (g_register_infos[i].name)
g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
@@ -213,6 +215,7 @@ ABIMacOSX_arm64::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
ABISP
ABIMacOSX_arm64::CreateInstance (const ArchSpec &arch)
{
@@ -294,7 +297,6 @@ ABIMacOSX_arm64::PrepareTrivialCall (Thread &thread,
return true;
}
-
bool
ABIMacOSX_arm64::GetArgumentValues (Thread &thread, ValueList &values) const
{
@@ -325,7 +327,7 @@ ABIMacOSX_arm64::GetArgumentValues (Thread &thread, ValueList &values) const
{
bool is_signed = false;
size_t bit_width = 0;
- if (value_type.IsIntegerType (is_signed))
+ if (value_type.IsIntegerOrEnumerationType (is_signed))
{
bit_width = value_type.GetBitSize(&thread);
}
@@ -344,7 +346,7 @@ ABIMacOSX_arm64::GetArgumentValues (Thread &thread, ValueList &values) const
if (value_idx < 8)
{
// Arguments 1-6 are in x0-x5...
- const RegisterInfo *reg_info = NULL;
+ const RegisterInfo *reg_info = nullptr;
// Search by generic ID first, then fall back to by name
uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
if (arg_reg_num != LLDB_INVALID_REGNUM)
@@ -444,7 +446,7 @@ ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueO
return error;
}
- const uint32_t type_flags = return_value_type.GetTypeInfo (NULL);
+ const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr);
if (type_flags & eTypeIsScalar ||
type_flags & eTypeIsPointer)
{
@@ -670,6 +672,7 @@ ABIMacOSX_arm64::RegisterIsVolatile (const RegisterInfo *reg_info)
case '3': // x30 aka lr treat as non-volatile
if (name[2] == '0')
return false;
+ break;
default:
return true;
}
@@ -734,12 +737,12 @@ LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
const size_t base_byte_size = base_type.GetByteSize(nullptr);
uint32_t data_offset = 0;
- for (uint32_t i=0; i<homogeneous_count; ++i)
+ for (uint32_t i = 0; i < homogeneous_count; ++i)
{
char v_name[8];
::snprintf (v_name, sizeof(v_name), "v%u", NSRN);
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(v_name, 0);
- if (reg_info == NULL)
+ if (reg_info == nullptr)
return false;
if (base_byte_size > reg_info->byte_size)
@@ -788,7 +791,7 @@ LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
return false;
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
- if (reg_info == NULL)
+ if (reg_info == nullptr)
return false;
RegisterValue reg_value;
@@ -809,7 +812,7 @@ LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
}
else
{
- const RegisterInfo *reg_info = NULL;
+ const RegisterInfo *reg_info = nullptr;
if (is_return_value)
{
// We are assuming we are decoding this immediately after returning
@@ -828,12 +831,12 @@ LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
if (reg_num == LLDB_INVALID_REGNUM)
return false;
reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
- if (reg_info == NULL)
+ if (reg_info == nullptr)
return false;
++NGRN;
}
- if (reg_info == NULL)
+ if (reg_info == nullptr)
return false;
const lldb::addr_t value_addr = reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
@@ -863,7 +866,7 @@ ABIMacOSX_arm64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_
Value value;
ExecutionContext exe_ctx (thread.shared_from_this());
- if (exe_ctx.GetTargetPtr() == NULL || exe_ctx.GetProcessPtr() == NULL)
+ if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
return return_valobj_sp;
//value.SetContext (Value::eContextTypeClangType, return_compiler_type);
@@ -875,7 +878,7 @@ ABIMacOSX_arm64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_
const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- const uint32_t type_flags = return_compiler_type.GetTypeInfo (NULL);
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
if (type_flags & eTypeIsScalar ||
type_flags & eTypeIsPointer)
{
@@ -1010,7 +1013,6 @@ ABIMacOSX_arm64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_
return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
value,
ConstString(""));
-
}
else if (type_flags & eTypeIsVector)
{
@@ -1084,6 +1086,7 @@ ABIMacOSX_arm64::Terminate()
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
ConstString
ABIMacOSX_arm64::GetPluginNameStatic()
{
@@ -1096,4 +1099,3 @@ ABIMacOSX_arm64::GetPluginVersion()
{
return 1;
}
-
diff --git a/source/Plugins/ABI/MacOSX-arm64/Makefile b/source/Plugins/ABI/MacOSX-arm64/Makefile
deleted file mode 100644
index 7fc6909e43cc..000000000000
--- a/source/Plugins/ABI/MacOSX-arm64/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ABI/MacOSX-arm64/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginABIMacOSX_arm64
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index 75e5fb1558e6..70c7adb8e5b5 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -9,6 +9,15 @@
#include "ABIMacOSX_i386.h"
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Module.h"
@@ -22,11 +31,6 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
-#include <vector>
-
using namespace lldb;
using namespace lldb_private;
@@ -82,60 +86,59 @@ enum
dwarf_ymm7 = dwarf_xmm7
};
-
static RegisterInfo g_register_infos[] =
{
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
// ====== ======= == === ============= ============ ===================== ===================== ============================ ==================== ====================== ========== ===============
- { "eax", NULL, 4, 0, eEncodingUint , eFormatHex , { ehframe_eax , dwarf_eax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ebx" , NULL, 4, 0, eEncodingUint , eFormatHex , { ehframe_ebx , dwarf_ebx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ecx" , NULL, 4, 0, eEncodingUint , eFormatHex , { ehframe_ecx , dwarf_ecx , LLDB_REGNUM_GENERIC_ARG4 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "edx" , NULL, 4, 0, eEncodingUint , eFormatHex , { ehframe_edx , dwarf_edx , LLDB_REGNUM_GENERIC_ARG3 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "esi" , NULL, 4, 0, eEncodingUint , eFormatHex , { ehframe_esi , dwarf_esi , LLDB_REGNUM_GENERIC_ARG2 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "edi" , NULL, 4, 0, eEncodingUint , eFormatHex , { ehframe_edi , dwarf_edi , LLDB_REGNUM_GENERIC_ARG1 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ebp" , "fp", 4, 0, eEncodingUint , eFormatHex , { ehframe_ebp , dwarf_ebp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "esp" , "sp", 4, 0, eEncodingUint , eFormatHex , { ehframe_esp , dwarf_esp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "eip" , "pc", 4, 0, eEncodingUint , eFormatHex , { ehframe_eip , dwarf_eip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "eflags", NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_REGNUM_GENERIC_FLAGS , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "cs" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ss" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ds" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "es" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fs" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "gs" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm0" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm1" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm2" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm3" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm4" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm5" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm6" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm7" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fctrl" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fstat" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ftag" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fiseg" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fioff" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "foseg" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fooff" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fop" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm0" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm1" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm2" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm3" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm4" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm5" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm6" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm7" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "mxcsr" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm0" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm1" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm2" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm3" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm4" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm5" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm6" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm7" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL}
+ { "eax", nullptr, 4, 0, eEncodingUint , eFormatHex , { ehframe_eax , dwarf_eax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ebx" , nullptr, 4, 0, eEncodingUint , eFormatHex , { ehframe_ebx , dwarf_ebx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ecx" , nullptr, 4, 0, eEncodingUint , eFormatHex , { ehframe_ecx , dwarf_ecx , LLDB_REGNUM_GENERIC_ARG4 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "edx" , nullptr, 4, 0, eEncodingUint , eFormatHex , { ehframe_edx , dwarf_edx , LLDB_REGNUM_GENERIC_ARG3 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "esi" , nullptr, 4, 0, eEncodingUint , eFormatHex , { ehframe_esi , dwarf_esi , LLDB_REGNUM_GENERIC_ARG2 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "edi" , nullptr, 4, 0, eEncodingUint , eFormatHex , { ehframe_edi , dwarf_edi , LLDB_REGNUM_GENERIC_ARG1 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ebp" , "fp", 4, 0, eEncodingUint , eFormatHex , { ehframe_ebp , dwarf_ebp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "esp" , "sp", 4, 0, eEncodingUint , eFormatHex , { ehframe_esp , dwarf_esp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "eip" , "pc", 4, 0, eEncodingUint , eFormatHex , { ehframe_eip , dwarf_eip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "eflags", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_REGNUM_GENERIC_FLAGS , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "cs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ss" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ds" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "es" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "gs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm0" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm1" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm2" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm3" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm4" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm5" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm6" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm7" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fctrl" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fstat" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ftag" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fiseg" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fioff" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "foseg" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fooff" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fop" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm0" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm1" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm2" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm3" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm4" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm5" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm6" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm7" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "mxcsr" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm0" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm1" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm2" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm3" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm4" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm5" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm6" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm7" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr }
};
static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
@@ -150,7 +153,7 @@ ABIMacOSX_i386::GetRegisterInfoArray (uint32_t &count)
if (!g_register_info_names_constified)
{
g_register_info_names_constified = true;
- for (uint32_t i=0; i<k_num_register_infos; ++i)
+ for (uint32_t i = 0; i < k_num_register_infos; ++i)
{
if (g_register_infos[i].name)
g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
@@ -171,6 +174,7 @@ ABIMacOSX_i386::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
ABISP
ABIMacOSX_i386::CreateInstance (const ArchSpec &arch)
{
@@ -311,7 +315,7 @@ ABIMacOSX_i386::GetArgumentValues (Thread &thread,
{
bool is_signed;
- if (compiler_type.IsIntegerType (is_signed))
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
compiler_type.GetBitSize(&thread),
@@ -359,7 +363,7 @@ ABIMacOSX_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
bool set_it_simple = false;
- if (compiler_type.IsIntegerType (is_signed) || compiler_type.IsPointerType())
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
{
DataExtractor data;
Error data_error;
@@ -432,7 +436,7 @@ ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread,
bool is_signed;
- if (compiler_type.IsIntegerType (is_signed))
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed))
{
size_t bit_width = compiler_type.GetBitSize(&thread);
@@ -626,6 +630,7 @@ ABIMacOSX_i386::GetPluginNameStatic ()
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
lldb_private::ConstString
ABIMacOSX_i386::GetPluginName()
{
@@ -637,4 +642,3 @@ ABIMacOSX_i386::GetPluginVersion()
{
return 1;
}
-
diff --git a/source/Plugins/ABI/MacOSX-i386/Makefile b/source/Plugins/ABI/MacOSX-i386/Makefile
deleted file mode 100644
index d9bc73922563..000000000000
--- a/source/Plugins/ABI/MacOSX-i386/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ABI/MacOSX-i386/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginABIMacOSX_i386
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
index ef625dece265..c23b41c11ccb 100644
--- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
+++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_arm.cpp --------------------------------------*- C++ -*-===//
+//===-- ABISysV_arm.cpp -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,6 +9,15 @@
#include "ABISysV_arm.h"
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Module.h"
@@ -23,15 +32,10 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
#include "Utility/ARM_DWARF_Registers.h"
#include "Utility/ARM_ehframe_Registers.h"
#include "Plugins/Process/Utility/ARMDefines.h"
-#include <vector>
-
using namespace lldb;
using namespace lldb_private;
@@ -39,111 +43,112 @@ static RegisterInfo g_register_infos[] =
{
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
// ========== ======= == === ============= ============ ======================= =================== =========================== ======================= ====================== ========== ===============
- { "r0", "arg1", 4, 0, eEncodingUint , eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r1", "arg2", 4, 0, eEncodingUint , eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r2", "arg3", 4, 0, eEncodingUint , eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r3", "arg4", 4, 0, eEncodingUint , eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r4", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r5", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r6", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r7", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r8", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r9", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r10", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r11", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r12", NULL, 4, 0, eEncodingUint , eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "sp", "r13", 4, 0, eEncodingUint , eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "lr", "r14", 4, 0, eEncodingUint , eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "pc", "r15", 4, 0, eEncodingUint , eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "cpsr", "psr", 4, 0, eEncodingUint , eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s0", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s1", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s2", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s3", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s4", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s5", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s6", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s7", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s8", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s9", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s10", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s11", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s12", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s13", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s14", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s15", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s16", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s17", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s18", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s19", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s20", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s21", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s22", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s23", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s24", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s25", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s26", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s27", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s28", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s29", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s30", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "s31", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fpscr", NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d0", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d1", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d2", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d3", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d4", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d5", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d6", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d7", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d8", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d9", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d10", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d11", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d12", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d13", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d14", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d15", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d16", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d17", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d18", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d19", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d20", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d21", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d22", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d23", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d24", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d25", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d26", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d27", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d28", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d29", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d30", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "d31", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r8_usr", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r9_usr", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r10_usr", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r11_usr", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r12_usr", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13_usr", "sp_usr", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14_usr", "lr_usr", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r8_fiq", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r9_fiq", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r10_fiq", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r11_fiq", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r12_fiq", NULL, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13_fiq", "sp_fiq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14_fiq", "lr_fiq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13_irq", "sp_irq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14_irq", "lr_irq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13_abt", "sp_abt", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14_abt", "lr_abt", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13_und", "sp_und", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14_und", "lr_und", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13_svc", "sp_svc", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14_svc", "lr_svc", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL}
+ { "r0", "arg1", 4, 0, eEncodingUint , eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r1", "arg2", 4, 0, eEncodingUint , eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r2", "arg3", 4, 0, eEncodingUint , eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r3", "arg4", 4, 0, eEncodingUint , eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r4", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r5", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r6", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r7", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r8", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r9", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r10", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r11", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r12", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "sp", "r13", 4, 0, eEncodingUint , eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "lr", "r14", 4, 0, eEncodingUint , eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "pc", "r15", 4, 0, eEncodingUint , eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "cpsr", "psr", 4, 0, eEncodingUint , eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s0", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s1", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s2", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s3", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s4", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s5", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s6", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s7", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s8", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s9", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s10", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s11", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s12", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s13", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s14", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s15", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s16", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s17", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s18", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s19", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s20", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s21", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s22", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s23", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s24", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s25", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s26", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s27", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s28", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s29", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s30", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s31", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fpscr", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d0", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d1", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d2", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d3", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d4", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d5", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d6", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d7", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d8", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d9", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d10", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d11", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d12", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d13", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d14", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d15", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d16", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d17", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d18", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d19", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d20", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d21", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d22", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d23", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d24", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d25", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d26", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d27", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d28", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d29", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d30", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d31", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r8_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r9_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r10_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r11_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r12_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13_usr", "sp_usr", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14_usr", "lr_usr", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r8_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r9_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r10_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r11_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r12_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13_fiq", "sp_fiq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14_fiq", "lr_fiq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13_irq", "sp_irq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14_irq", "lr_irq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13_abt", "sp_abt", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14_abt", "lr_abt", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13_und", "sp_und", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14_und", "lr_und", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13_svc", "sp_svc", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14_svc", "lr_svc", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr }
};
+
static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
static bool g_register_info_names_constified = false;
@@ -156,7 +161,7 @@ ABISysV_arm::GetRegisterInfoArray (uint32_t &count)
if (!g_register_info_names_constified)
{
g_register_info_names_constified = true;
- for (uint32_t i=0; i<k_num_register_infos; ++i)
+ for (uint32_t i = 0; i < k_num_register_infos; ++i)
{
if (g_register_infos[i].name)
g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
@@ -168,7 +173,6 @@ ABISysV_arm::GetRegisterInfoArray (uint32_t &count)
return g_register_infos;
}
-
size_t
ABISysV_arm::GetRedZoneSize () const
{
@@ -178,6 +182,7 @@ ABISysV_arm::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
ABISP
ABISysV_arm::CreateInstance (const ArchSpec &arch)
{
@@ -308,8 +313,7 @@ ABISysV_arm::GetArgumentValues (Thread &thread,
ValueList &values) const
{
uint32_t num_values = values.GetSize();
-
-
+
ExecutionContext exe_ctx (thread.shared_from_this());
// For now, assume that the types in the AST values come from the Target's
// scratch AST.
@@ -337,7 +341,7 @@ ABISysV_arm::GetArgumentValues (Thread &thread,
{
bool is_signed = false;
size_t bit_width = 0;
- if (compiler_type.IsIntegerType (is_signed))
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed))
{
bit_width = compiler_type.GetBitSize(&thread);
}
@@ -356,7 +360,7 @@ ABISysV_arm::GetArgumentValues (Thread &thread,
if (value_idx < 4)
{
// Arguments 1-4 are in r0-r3...
- const RegisterInfo *arg_reg_info = NULL;
+ const RegisterInfo *arg_reg_info = nullptr;
arg_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
if (arg_reg_info)
{
@@ -414,6 +418,20 @@ GetReturnValuePassedInMemory(Thread &thread, RegisterContext* reg_ctx, size_t by
return true;
}
+bool
+ABISysV_arm::IsArmHardFloat (Thread &thread) const
+{
+ ProcessSP process_sp (thread.GetProcess());
+ if (process_sp)
+ {
+ const ArchSpec &arch (process_sp->GetTarget().GetArchitecture());
+
+ return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0;
+ }
+
+ return false;
+}
+
ValueObjectSP
ABISysV_arm::GetReturnValueObjectImpl (Thread &thread,
lldb_private::CompilerType &compiler_type) const
@@ -434,14 +452,18 @@ ABISysV_arm::GetReturnValueObjectImpl (Thread &thread,
bool is_signed;
bool is_complex;
uint32_t float_count;
+ bool is_vfp_candidate = false;
+ uint8_t vfp_count = 0;
+ uint8_t vfp_byte_size = 0;
// Get the pointer to the first stack argument so we have a place to start
// when reading data
const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
size_t bit_width = compiler_type.GetBitSize(&thread);
+ size_t byte_size = compiler_type.GetByteSize(&thread);
- if (compiler_type.IsIntegerType (is_signed))
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed))
{
switch (bit_width)
{
@@ -486,8 +508,13 @@ ABISysV_arm::GetReturnValueObjectImpl (Thread &thread,
}
else if (compiler_type.IsVectorType(nullptr, nullptr))
{
- size_t byte_size = compiler_type.GetByteSize(&thread);
- if (byte_size <= 16)
+ if (IsArmHardFloat(thread) && (byte_size == 8 || byte_size == 16))
+ {
+ is_vfp_candidate = true;
+ vfp_byte_size = 8;
+ vfp_count = (byte_size == 8?1:2);
+ }
+ else if (byte_size <= 16)
{
DataBufferHeap buffer(16, 0);
uint32_t* buffer_ptr = (uint32_t*)buffer.GetBytes();
@@ -516,39 +543,135 @@ ABISysV_arm::GetReturnValueObjectImpl (Thread &thread,
case 64:
{
static_assert(sizeof(double) == sizeof(uint64_t), "");
- const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
- uint64_t raw_value;
- raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
- raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & UINT32_MAX)) << 32;
- value.GetScalar() = *reinterpret_cast<double*>(&raw_value);
+
+ if (IsArmHardFloat(thread))
+ {
+ RegisterValue reg_value;
+ const RegisterInfo *d0_reg_info = reg_ctx->GetRegisterInfoByName("d0", 0);
+ reg_ctx->ReadRegister(d0_reg_info, reg_value);
+ value.GetScalar() = reg_value.GetAsDouble();
+ }
+ else
+ {
+ uint64_t raw_value;
+ const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
+ raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
+ raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & UINT32_MAX)) << 32;
+ value.GetScalar() = *reinterpret_cast<double*>(&raw_value);
+ }
break;
}
case 16: // Half precision returned after a conversion to single precision
case 32:
{
static_assert(sizeof(float) == sizeof(uint32_t), "");
- uint32_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
- value.GetScalar() = *reinterpret_cast<float*>(&raw_value);
+
+ if (IsArmHardFloat(thread))
+ {
+ RegisterValue reg_value;
+ const RegisterInfo *s0_reg_info = reg_ctx->GetRegisterInfoByName("s0", 0);
+ reg_ctx->ReadRegister(s0_reg_info, reg_value);
+ value.GetScalar() = reg_value.GetAsFloat();
+ }
+ else
+ {
+ uint32_t raw_value;
+ raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
+ value.GetScalar() = *reinterpret_cast<float*>(&raw_value);
+ }
break;
}
}
}
- else
+ else if (is_complex && float_count == 2)
{
+ if (IsArmHardFloat(thread))
+ {
+ is_vfp_candidate = true;
+ vfp_byte_size = byte_size / 2;
+ vfp_count = 2;
+ }
+ else if (!GetReturnValuePassedInMemory(thread, reg_ctx, bit_width / 8, value))
+ return return_valobj_sp;
+ }
+ else
// not handled yet
return return_valobj_sp;
- }
}
else if (compiler_type.IsAggregateType())
{
- size_t byte_size = compiler_type.GetByteSize(&thread);
+ if (IsArmHardFloat(thread))
+ {
+ CompilerType base_type;
+ const uint32_t homogeneous_count = compiler_type.IsHomogeneousAggregate (&base_type);
+
+ if (homogeneous_count > 0 && homogeneous_count <= 4)
+ {
+ if (base_type.IsVectorType(nullptr, nullptr))
+ {
+ uint64_t base_byte_size = base_type.GetByteSize(nullptr);
+ if (base_byte_size == 8 || base_byte_size == 16)
+ {
+ is_vfp_candidate = true;
+ vfp_byte_size = 8;
+ vfp_count = (base_type.GetByteSize(nullptr) == 8 ? homogeneous_count : homogeneous_count * 2);
+ }
+ }
+ else if (base_type.IsFloatingPointType(float_count, is_complex))
+ {
+ if (float_count == 1 && !is_complex)
+ {
+ is_vfp_candidate = true;
+ vfp_byte_size = base_type.GetByteSize(nullptr);
+ vfp_count = homogeneous_count;
+ }
+ }
+ }
+ else if (homogeneous_count == 0)
+ {
+ const uint32_t num_children = compiler_type.GetNumFields ();
+
+ if (num_children > 0 && num_children <=2)
+ {
+ uint32_t index = 0;
+ for (index = 0; index < num_children; index++)
+ {
+ std::string name;
+ base_type = compiler_type.GetFieldAtIndex (index, name, NULL, NULL, NULL);
+
+ if (base_type.IsFloatingPointType(float_count, is_complex))
+ {
+ if (float_count == 2 && is_complex)
+ {
+ if (index != 0 && vfp_byte_size != base_type.GetByteSize(nullptr))
+ break;
+ else
+ vfp_byte_size = base_type.GetByteSize(nullptr);
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ if (index == num_children)
+ {
+ is_vfp_candidate = true;
+ vfp_byte_size = (vfp_byte_size >> 1);
+ vfp_count = (num_children << 1);
+ }
+ }
+ }
+ }
+
if (byte_size <= 4)
{
RegisterValue r0_reg_value;
uint32_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
value.SetBytes(&raw_value, byte_size);
}
- else
+ else if (!is_vfp_candidate)
{
if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value))
return return_valobj_sp;
@@ -560,6 +683,64 @@ ABISysV_arm::GetReturnValueObjectImpl (Thread &thread,
return return_valobj_sp;
}
+ if (is_vfp_candidate)
+ {
+ ProcessSP process_sp (thread.GetProcess());
+ ByteOrder byte_order = process_sp->GetByteOrder();
+
+ DataBufferSP data_sp (new DataBufferHeap(byte_size, 0));
+ uint32_t data_offset = 0;
+
+ for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++)
+ {
+ uint32_t regnum = 0;
+
+ if (vfp_byte_size == 4)
+ regnum = dwarf_s0 + reg_index;
+ else if (vfp_byte_size == 8)
+ regnum = dwarf_d0 + reg_index;
+ else
+ break;
+
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo (eRegisterKindDWARF, regnum);
+ if (reg_info == NULL)
+ break;
+
+ RegisterValue reg_value;
+ if (!reg_ctx->ReadRegister(reg_info, reg_value))
+ break;
+
+ // Make sure we have enough room in "data_sp"
+ if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize())
+ {
+ Error error;
+ const size_t bytes_copied = reg_value.GetAsMemoryData (reg_info,
+ data_sp->GetBytes() + data_offset,
+ vfp_byte_size,
+ byte_order,
+ error);
+ if (bytes_copied != vfp_byte_size)
+ break;
+
+ data_offset += bytes_copied;
+ }
+ }
+
+ if (data_offset == byte_size)
+ {
+ DataExtractor data;
+ data.SetByteOrder(byte_order);
+ data.SetAddressByteSize(process_sp->GetAddressByteSize());
+ data.SetData(data_sp);
+
+ return ValueObjectConstResult::Create (&thread, compiler_type, ConstString(""), data);
+ }
+ else
+ { // Some error occurred while getting values from registers
+ return return_valobj_sp;
+ }
+ }
+
// If we get here, we have a valid Value, so make our ValueObject out of it:
return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
@@ -594,7 +775,7 @@ ABISysV_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjec
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
bool set_it_simple = false;
- if (compiler_type.IsIntegerType (is_signed) || compiler_type.IsPointerType())
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
{
DataExtractor data;
Error data_error;
@@ -802,6 +983,7 @@ ABISysV_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
default:
break;
}
+ break;
case '4':
case '5':
case '6':
@@ -837,30 +1019,14 @@ ABISysV_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
break;
case '2':
- switch (name[2])
- {
- case '\0':
- return true; // s2 is volatile
- default:
- break;
- }
- break;
-
case '3':
- switch (name[2])
- {
- case '\0':
- return true; // s3 is volatile
- default:
- break;
- }
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
- return name[2] == '\0'; // s4 - s9 are volatile
+ return name[2] == '\0'; // s2 - s9 are volatile
default:
break;
@@ -883,9 +1049,11 @@ ABISysV_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
case '5':
return true; // q10-q15 are volatile
default:
- break;
- };
- case '0':
+ return false;
+ }
+ break;
+
+ case '0':
case '2':
case '3':
return name[2] == '\0'; // q0-q3 are volatile
@@ -926,6 +1094,7 @@ ABISysV_arm::GetPluginNameStatic()
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
lldb_private::ConstString
ABISysV_arm::GetPluginName()
{
@@ -937,4 +1106,3 @@ ABISysV_arm::GetPluginVersion()
{
return 1;
}
-
diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.h b/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
index e3b280296a64..11a2601501e4 100644
--- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
+++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
@@ -79,6 +79,9 @@ public:
const lldb_private::RegisterInfo *
GetRegisterInfoArray (uint32_t &count) override;
+ bool
+ IsArmHardFloat (lldb_private::Thread &thread) const;
+
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
diff --git a/source/Plugins/ABI/SysV-arm/Makefile b/source/Plugins/ABI/SysV-arm/Makefile
deleted file mode 100644
index a1d95dc17320..000000000000
--- a/source/Plugins/ABI/SysV-arm/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ABI/SysV-arm/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===--------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginABISysV_arm
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
index bc6df235cb1e..e4ed523b9d0a 100644
--- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
+++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_arm64.cpp -------------------------------------*- C++ -*-===//
+//===-- ABISysV_arm64.cpp ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,6 +9,15 @@
#include "ABISysV_arm64.h"
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
@@ -24,13 +33,8 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
#include "Utility/ARM64_DWARF_Registers.h"
-#include <vector>
-
using namespace lldb;
using namespace lldb_private;
@@ -38,142 +42,142 @@ static RegisterInfo g_register_infos[] =
{
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE
// ========== ======= == === ============= =================== =================== ====================== =========================== ======================= ======================
- { "x0", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x1", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x2", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x3", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x4", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x5", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x6", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x7", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x8", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x9", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x10", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x11", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x12", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x13", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x14", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x15", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x16", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x17", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x18", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x19", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x20", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x21", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x22", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x23", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x24", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x25", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x26", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x27", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "x28", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "fp", "x29", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "lr", "x30", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "sp", "x31", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "pc", NULL, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "cpsr", "psr", 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
-
- { "v0", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v1", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v2", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v3", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v4", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v5", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v6", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v7", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v8", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v9", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v10", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v11", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v12", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v13", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v14", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v15", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v16", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v17", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v18", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v19", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v20", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v21", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v22", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v23", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v24", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v25", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v26", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v27", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v28", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v29", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v30", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "v31", NULL, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
-
- { "fpsr", NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "fpcr", NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
-
- { "s0", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s1", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s2", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s3", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s4", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s5", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s6", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s7", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s8", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s9", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s10", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s11", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s12", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s13", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s14", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s15", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s16", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s17", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s18", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s19", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s20", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s21", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s22", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s23", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s24", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s25", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s26", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s27", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s28", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s29", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s30", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "s31", NULL, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
-
- { "d0", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d1", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d2", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d3", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d4", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d5", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d6", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d7", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d8", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d9", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d10", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d11", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d12", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d13", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d14", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d15", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d16", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d17", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d18", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d19", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d20", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d21", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d22", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d23", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d24", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d25", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d26", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d27", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d28", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d29", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d30", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL },
- { "d31", NULL, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL }
+ { "x0", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x1", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x2", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x3", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x4", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x5", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x6", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x7", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x8", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x9", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x10", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x11", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x12", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x13", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x14", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x15", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x16", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x17", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x18", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x19", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x20", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x21", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x22", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x23", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x24", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x25", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x26", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x27", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "x28", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fp", "x29", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "lr", "x30", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "sp", "x31", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "pc", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "cpsr", "psr", 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+
+ { "v0", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v1", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v2", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v3", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v4", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v5", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v6", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v7", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v8", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v9", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v10", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v11", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v12", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v13", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v14", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v15", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v16", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v17", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v18", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v19", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v20", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v21", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v22", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v23", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v24", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v25", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v26", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v27", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v28", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v29", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v30", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "v31", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+
+ { "fpsr", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fpcr", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+
+ { "s0", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s1", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s2", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s3", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s4", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s5", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s6", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s7", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s8", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s9", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s10", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s11", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s12", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s13", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s14", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s15", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s16", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s17", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s18", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s19", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s20", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s21", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s22", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s23", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s24", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s25", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s26", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s27", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s28", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s29", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s30", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "s31", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+
+ { "d0", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d1", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d2", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d3", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d4", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d5", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d6", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d7", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d8", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d9", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d10", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d11", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d12", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d13", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d14", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d15", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d16", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d17", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d18", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d19", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d20", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d21", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d22", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d23", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d24", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d25", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d26", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d27", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d28", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d29", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d30", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "d31", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr }
};
static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
@@ -209,6 +213,7 @@ ABISysV_arm64::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
ABISP
ABISysV_arm64::CreateInstance (const ArchSpec &arch)
{
@@ -317,7 +322,7 @@ ABISysV_arm64::GetArgumentValues (Thread &thread, ValueList &values) const
{
bool is_signed = false;
size_t bit_width = 0;
- if (value_type.IsIntegerType (is_signed))
+ if (value_type.IsIntegerOrEnumerationType (is_signed))
{
bit_width = value_type.GetBitSize(&thread);
}
@@ -336,7 +341,7 @@ ABISysV_arm64::GetArgumentValues (Thread &thread, ValueList &values) const
if (value_idx < 8)
{
// Arguments 1-8 are in x0-x7...
- const RegisterInfo *reg_info = NULL;
+ const RegisterInfo *reg_info = nullptr;
reg_info= reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
if (reg_info)
@@ -418,7 +423,7 @@ ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObj
return error;
}
- const uint32_t type_flags = return_value_type.GetTypeInfo (NULL);
+ const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr);
if (type_flags & eTypeIsScalar ||
type_flags & eTypeIsPointer)
{
@@ -648,6 +653,7 @@ ABISysV_arm64::RegisterIsVolatile (const RegisterInfo *reg_info)
case '3': // x30 (lr) and x31 (sp) treat as non-volatile
if (name[2] == '0' || name[2] == '1')
return false;
+ break;
default:
return true; // all volatile cases not handled above fall here.
}
@@ -717,7 +723,7 @@ LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
char v_name[8];
::snprintf (v_name, sizeof(v_name), "v%u", NSRN);
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(v_name, 0);
- if (reg_info == NULL)
+ if (reg_info == nullptr)
return false;
if (base_byte_size > reg_info->byte_size)
@@ -762,7 +768,7 @@ LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
return false;
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
- if (reg_info == NULL)
+ if (reg_info == nullptr)
return false;
RegisterValue reg_value;
@@ -783,7 +789,7 @@ LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
}
else
{
- const RegisterInfo *reg_info = NULL;
+ const RegisterInfo *reg_info = nullptr;
if (is_return_value)
{
// We are assuming we are decoding this immediately after returning
@@ -799,12 +805,12 @@ LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
return false;
reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
- if (reg_info == NULL)
+ if (reg_info == nullptr)
return false;
++NGRN;
}
- if (reg_info == NULL)
+ if (reg_info == nullptr)
return false;
const lldb::addr_t value_addr = reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
@@ -834,7 +840,7 @@ ABISysV_arm64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
Value value;
ExecutionContext exe_ctx (thread.shared_from_this());
- if (exe_ctx.GetTargetPtr() == NULL || exe_ctx.GetProcessPtr() == NULL)
+ if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
return return_valobj_sp;
//value.SetContext (Value::eContextTypeClangType, return_compiler_type);
@@ -846,7 +852,7 @@ ABISysV_arm64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- const uint32_t type_flags = return_compiler_type.GetTypeInfo (NULL);
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
if (type_flags & eTypeIsScalar ||
type_flags & eTypeIsPointer)
{
@@ -859,7 +865,7 @@ ABISysV_arm64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
// Extract the register context so we can read arguments from registers
if (byte_size <= 8)
{
- const RegisterInfo *x0_reg_info = NULL;
+ const RegisterInfo *x0_reg_info = nullptr;
x0_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
if (x0_reg_info)
{
@@ -872,7 +878,7 @@ ABISysV_arm64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
case 16: // uint128_t
// In register x0 and x1
{
- const RegisterInfo *x1_reg_info = NULL;
+ const RegisterInfo *x1_reg_info = nullptr;
x1_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
if (x1_reg_info)
@@ -983,13 +989,11 @@ ABISysV_arm64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
value,
ConstString(""));
-
}
else if (type_flags & eTypeIsVector)
{
if (byte_size > 0)
{
-
const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
if (v0_info)
@@ -1064,6 +1068,7 @@ ABISysV_arm64::GetPluginNameStatic()
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
ConstString
ABISysV_arm64::GetPluginName()
{
@@ -1075,4 +1080,3 @@ ABISysV_arm64::GetPluginVersion()
{
return 1;
}
-
diff --git a/source/Plugins/ABI/SysV-arm64/Makefile b/source/Plugins/ABI/SysV-arm64/Makefile
deleted file mode 100644
index a72ecd83404d..000000000000
--- a/source/Plugins/ABI/SysV-arm64/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ABI/SysV-arm64/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginABISysV_arm64
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
index e0299b6f0b94..596f3dc1166a 100644
--- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
+++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_hexagon.cpp --------------------------------------*- C++ -*-===//
+//===-- ABISysV_hexagon.cpp -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,6 +9,13 @@
#include "ABISysV_hexagon.h"
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/Triple.h"
+#include "llvm/IR/DerivedTypes.h"
+
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
@@ -27,111 +34,107 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/Triple.h"
-
-#include "llvm/IR/DerivedTypes.h"
-
using namespace lldb;
using namespace lldb_private;
static RegisterInfo g_register_infos[] =
{
// hexagon-core.xml
- { "r00" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 0, 0, LLDB_INVALID_REGNUM, 0, 0 }, NULL, NULL },
- { "r01" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 1, 1, LLDB_INVALID_REGNUM, 1, 1 }, NULL, NULL },
- { "r02" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 2, 2, LLDB_INVALID_REGNUM, 2, 2 }, NULL, NULL },
- { "r03" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 3, 3, LLDB_INVALID_REGNUM, 3, 3 }, NULL, NULL },
- { "r04" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 4, 4, LLDB_INVALID_REGNUM, 4, 4 }, NULL, NULL },
- { "r05" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 5, 5, LLDB_INVALID_REGNUM, 5, 5 }, NULL, NULL },
- { "r06" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 6, 6, LLDB_INVALID_REGNUM, 6, 6 }, NULL, NULL },
- { "r07" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 7, 7, LLDB_INVALID_REGNUM, 7, 7 }, NULL, NULL },
- { "r08" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 8, 8, LLDB_INVALID_REGNUM, 8, 8 }, NULL, NULL },
- { "r09" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 9, 9, LLDB_INVALID_REGNUM, 9, 9 }, NULL, NULL },
- { "r10" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 10, 10, LLDB_INVALID_REGNUM, 10, 10 }, NULL, NULL },
- { "r11" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 11, 11, LLDB_INVALID_REGNUM, 11, 11 }, NULL, NULL },
- { "r12" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 12, 12, LLDB_INVALID_REGNUM, 12, 12 }, NULL, NULL },
- { "r13" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 13, 13, LLDB_INVALID_REGNUM, 13, 13 }, NULL, NULL },
- { "r14" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 14, 14, LLDB_INVALID_REGNUM, 14, 14 }, NULL, NULL },
- { "r15" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 15, 15, LLDB_INVALID_REGNUM, 15, 15 }, NULL, NULL },
- { "r16" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 16, 16, LLDB_INVALID_REGNUM, 16, 16 }, NULL, NULL },
- { "r17" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 17, 17, LLDB_INVALID_REGNUM, 17, 17 }, NULL, NULL },
- { "r18" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 18, 18, LLDB_INVALID_REGNUM, 18, 18 }, NULL, NULL },
- { "r19" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 19, 19, LLDB_INVALID_REGNUM, 19, 19 }, NULL, NULL },
- { "r20" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 20, 20, LLDB_INVALID_REGNUM, 20, 20 }, NULL, NULL },
- { "r21" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 21, 21, LLDB_INVALID_REGNUM, 21, 21 }, NULL, NULL },
- { "r22" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 22, 22, LLDB_INVALID_REGNUM, 22, 22 }, NULL, NULL },
- { "r23" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 23, 23, LLDB_INVALID_REGNUM, 23, 23 }, NULL, NULL },
- { "r24" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 24, 24, LLDB_INVALID_REGNUM, 24, 24 }, NULL, NULL },
- { "r25" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 25, 25, LLDB_INVALID_REGNUM, 25, 25 }, NULL, NULL },
- { "r26" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 26, 26, LLDB_INVALID_REGNUM, 26, 26 }, NULL, NULL },
- { "r27" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 27, 27, LLDB_INVALID_REGNUM, 27, 27 }, NULL, NULL },
- { "r28" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 28, 28, LLDB_INVALID_REGNUM, 28, 28 }, NULL, NULL },
- { "sp" ,"r29", 4, 0, eEncodingUint, eFormatAddressInfo, { 29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29 }, NULL, NULL },
- { "fp" ,"r30", 4, 0, eEncodingUint, eFormatAddressInfo, { 30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30 }, NULL, NULL },
- { "lr" ,"r31", 4, 0, eEncodingUint, eFormatAddressInfo, { 31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31 }, NULL, NULL },
- { "sa0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 32, 32, LLDB_INVALID_REGNUM, 32, 32 }, NULL, NULL },
- { "lc0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 33, 33, LLDB_INVALID_REGNUM, 33, 33 }, NULL, NULL },
- { "sa1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 34, 34, LLDB_INVALID_REGNUM, 34, 34 }, NULL, NULL },
- { "lc1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 35, 35, LLDB_INVALID_REGNUM, 35, 35 }, NULL, NULL },
+ { "r00" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 0, 0, LLDB_INVALID_REGNUM, 0, 0 }, nullptr, nullptr },
+ { "r01" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 1, 1, LLDB_INVALID_REGNUM, 1, 1 }, nullptr, nullptr },
+ { "r02" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 2, 2, LLDB_INVALID_REGNUM, 2, 2 }, nullptr, nullptr },
+ { "r03" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 3, 3, LLDB_INVALID_REGNUM, 3, 3 }, nullptr, nullptr },
+ { "r04" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 4, 4, LLDB_INVALID_REGNUM, 4, 4 }, nullptr, nullptr },
+ { "r05" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 5, 5, LLDB_INVALID_REGNUM, 5, 5 }, nullptr, nullptr },
+ { "r06" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 6, 6, LLDB_INVALID_REGNUM, 6, 6 }, nullptr, nullptr },
+ { "r07" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 7, 7, LLDB_INVALID_REGNUM, 7, 7 }, nullptr, nullptr },
+ { "r08" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 8, 8, LLDB_INVALID_REGNUM, 8, 8 }, nullptr, nullptr },
+ { "r09" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 9, 9, LLDB_INVALID_REGNUM, 9, 9 }, nullptr, nullptr },
+ { "r10" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 10, 10, LLDB_INVALID_REGNUM, 10, 10 }, nullptr, nullptr },
+ { "r11" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 11, 11, LLDB_INVALID_REGNUM, 11, 11 }, nullptr, nullptr },
+ { "r12" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 12, 12, LLDB_INVALID_REGNUM, 12, 12 }, nullptr, nullptr },
+ { "r13" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 13, 13, LLDB_INVALID_REGNUM, 13, 13 }, nullptr, nullptr },
+ { "r14" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 14, 14, LLDB_INVALID_REGNUM, 14, 14 }, nullptr, nullptr },
+ { "r15" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 15, 15, LLDB_INVALID_REGNUM, 15, 15 }, nullptr, nullptr },
+ { "r16" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 16, 16, LLDB_INVALID_REGNUM, 16, 16 }, nullptr, nullptr },
+ { "r17" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 17, 17, LLDB_INVALID_REGNUM, 17, 17 }, nullptr, nullptr },
+ { "r18" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 18, 18, LLDB_INVALID_REGNUM, 18, 18 }, nullptr, nullptr },
+ { "r19" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 19, 19, LLDB_INVALID_REGNUM, 19, 19 }, nullptr, nullptr },
+ { "r20" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 20, 20, LLDB_INVALID_REGNUM, 20, 20 }, nullptr, nullptr },
+ { "r21" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 21, 21, LLDB_INVALID_REGNUM, 21, 21 }, nullptr, nullptr },
+ { "r22" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 22, 22, LLDB_INVALID_REGNUM, 22, 22 }, nullptr, nullptr },
+ { "r23" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 23, 23, LLDB_INVALID_REGNUM, 23, 23 }, nullptr, nullptr },
+ { "r24" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 24, 24, LLDB_INVALID_REGNUM, 24, 24 }, nullptr, nullptr },
+ { "r25" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 25, 25, LLDB_INVALID_REGNUM, 25, 25 }, nullptr, nullptr },
+ { "r26" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 26, 26, LLDB_INVALID_REGNUM, 26, 26 }, nullptr, nullptr },
+ { "r27" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 27, 27, LLDB_INVALID_REGNUM, 27, 27 }, nullptr, nullptr },
+ { "r28" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 28, 28, LLDB_INVALID_REGNUM, 28, 28 }, nullptr, nullptr },
+ { "sp" ,"r29", 4, 0, eEncodingUint, eFormatAddressInfo, { 29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29 }, nullptr, nullptr },
+ { "fp" ,"r30", 4, 0, eEncodingUint, eFormatAddressInfo, { 30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30 }, nullptr, nullptr },
+ { "lr" ,"r31", 4, 0, eEncodingUint, eFormatAddressInfo, { 31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31 }, nullptr, nullptr },
+ { "sa0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 32, 32, LLDB_INVALID_REGNUM, 32, 32 }, nullptr, nullptr },
+ { "lc0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 33, 33, LLDB_INVALID_REGNUM, 33, 33 }, nullptr, nullptr },
+ { "sa1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 34, 34, LLDB_INVALID_REGNUM, 34, 34 }, nullptr, nullptr },
+ { "lc1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 35, 35, LLDB_INVALID_REGNUM, 35, 35 }, nullptr, nullptr },
// --> hexagon-v4/5/55/56-sim.xml
- { "p3_0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 36, 36, LLDB_INVALID_REGNUM, 36, 36 }, NULL, NULL },
+ { "p3_0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 36, 36, LLDB_INVALID_REGNUM, 36, 36 }, nullptr, nullptr },
// PADDING {
- { "p00" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 37, 37, LLDB_INVALID_REGNUM, 37, 37 }, NULL, NULL },
+ { "p00" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 37, 37, LLDB_INVALID_REGNUM, 37, 37 }, nullptr, nullptr },
// }
- { "m0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 38, 38, LLDB_INVALID_REGNUM, 38, 38 }, NULL, NULL },
- { "m1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 39, 39, LLDB_INVALID_REGNUM, 39, 39 }, NULL, NULL },
- { "usr" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 40, 40, LLDB_INVALID_REGNUM, 40, 40 }, NULL, NULL },
- { "pc" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41 }, NULL, NULL },
- { "ugp" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 42, 42, LLDB_INVALID_REGNUM, 42, 42 }, NULL, NULL },
- { "gp" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 43, 43, LLDB_INVALID_REGNUM, 43, 43 }, NULL, NULL },
- { "cs0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 44, 44, LLDB_INVALID_REGNUM, 44, 44 }, NULL, NULL },
- { "cs1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 45, 45, LLDB_INVALID_REGNUM, 45, 45 }, NULL, NULL },
+ { "m0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 38, 38, LLDB_INVALID_REGNUM, 38, 38 }, nullptr, nullptr },
+ { "m1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 39, 39, LLDB_INVALID_REGNUM, 39, 39 }, nullptr, nullptr },
+ { "usr" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 40, 40, LLDB_INVALID_REGNUM, 40, 40 }, nullptr, nullptr },
+ { "pc" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41 }, nullptr, nullptr },
+ { "ugp" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 42, 42, LLDB_INVALID_REGNUM, 42, 42 }, nullptr, nullptr },
+ { "gp" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 43, 43, LLDB_INVALID_REGNUM, 43, 43 }, nullptr, nullptr },
+ { "cs0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 44, 44, LLDB_INVALID_REGNUM, 44, 44 }, nullptr, nullptr },
+ { "cs1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 45, 45, LLDB_INVALID_REGNUM, 45, 45 }, nullptr, nullptr },
// PADDING {
- { "p01" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 46, 46, LLDB_INVALID_REGNUM, 46, 46 }, NULL, NULL },
- { "p02" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 47, 47, LLDB_INVALID_REGNUM, 47, 47 }, NULL, NULL },
- { "p03" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 48, 48, LLDB_INVALID_REGNUM, 48, 48 }, NULL, NULL },
- { "p04" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 49, 49, LLDB_INVALID_REGNUM, 49, 49 }, NULL, NULL },
- { "p05" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 50, 50, LLDB_INVALID_REGNUM, 50, 50 }, NULL, NULL },
- { "p06" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 51, 51, LLDB_INVALID_REGNUM, 51, 51 }, NULL, NULL },
- { "p07" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 52, 52, LLDB_INVALID_REGNUM, 52, 52 }, NULL, NULL },
- { "p08" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 53, 53, LLDB_INVALID_REGNUM, 53, 53 }, NULL, NULL },
- { "p09" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 54, 54, LLDB_INVALID_REGNUM, 54, 54 }, NULL, NULL },
- { "p10" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 55, 55, LLDB_INVALID_REGNUM, 55, 55 }, NULL, NULL },
- { "p11" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 56, 56, LLDB_INVALID_REGNUM, 56, 56 }, NULL, NULL },
- { "p12" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 57, 57, LLDB_INVALID_REGNUM, 57, 57 }, NULL, NULL },
- { "p13" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 58, 58, LLDB_INVALID_REGNUM, 58, 58 }, NULL, NULL },
- { "p14" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 59, 59, LLDB_INVALID_REGNUM, 59, 59 }, NULL, NULL },
- { "p15" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 60, 60, LLDB_INVALID_REGNUM, 60, 60 }, NULL, NULL },
- { "p16" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 61, 61, LLDB_INVALID_REGNUM, 61, 61 }, NULL, NULL },
- { "p17" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 62, 62, LLDB_INVALID_REGNUM, 62, 62 }, NULL, NULL },
- { "p18" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 63, 63, LLDB_INVALID_REGNUM, 63, 63 }, NULL, NULL },
+ { "p01" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 46, 46, LLDB_INVALID_REGNUM, 46, 46 }, nullptr, nullptr },
+ { "p02" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 47, 47, LLDB_INVALID_REGNUM, 47, 47 }, nullptr, nullptr },
+ { "p03" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 48, 48, LLDB_INVALID_REGNUM, 48, 48 }, nullptr, nullptr },
+ { "p04" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 49, 49, LLDB_INVALID_REGNUM, 49, 49 }, nullptr, nullptr },
+ { "p05" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 50, 50, LLDB_INVALID_REGNUM, 50, 50 }, nullptr, nullptr },
+ { "p06" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 51, 51, LLDB_INVALID_REGNUM, 51, 51 }, nullptr, nullptr },
+ { "p07" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 52, 52, LLDB_INVALID_REGNUM, 52, 52 }, nullptr, nullptr },
+ { "p08" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 53, 53, LLDB_INVALID_REGNUM, 53, 53 }, nullptr, nullptr },
+ { "p09" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 54, 54, LLDB_INVALID_REGNUM, 54, 54 }, nullptr, nullptr },
+ { "p10" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 55, 55, LLDB_INVALID_REGNUM, 55, 55 }, nullptr, nullptr },
+ { "p11" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 56, 56, LLDB_INVALID_REGNUM, 56, 56 }, nullptr, nullptr },
+ { "p12" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 57, 57, LLDB_INVALID_REGNUM, 57, 57 }, nullptr, nullptr },
+ { "p13" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 58, 58, LLDB_INVALID_REGNUM, 58, 58 }, nullptr, nullptr },
+ { "p14" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 59, 59, LLDB_INVALID_REGNUM, 59, 59 }, nullptr, nullptr },
+ { "p15" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 60, 60, LLDB_INVALID_REGNUM, 60, 60 }, nullptr, nullptr },
+ { "p16" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 61, 61, LLDB_INVALID_REGNUM, 61, 61 }, nullptr, nullptr },
+ { "p17" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 62, 62, LLDB_INVALID_REGNUM, 62, 62 }, nullptr, nullptr },
+ { "p18" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 63, 63, LLDB_INVALID_REGNUM, 63, 63 }, nullptr, nullptr },
// }
- { "sgp0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 64, 64, LLDB_INVALID_REGNUM, 64, 64 }, NULL, NULL },
+ { "sgp0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 64, 64, LLDB_INVALID_REGNUM, 64, 64 }, nullptr, nullptr },
// PADDING {
- { "p19" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 65, 65, LLDB_INVALID_REGNUM, 65, 65 }, NULL, NULL },
+ { "p19" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 65, 65, LLDB_INVALID_REGNUM, 65, 65 }, nullptr, nullptr },
// }
- { "stid" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 66, 66, LLDB_INVALID_REGNUM, 66, 66 }, NULL, NULL },
- { "elr" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 67, 67, LLDB_INVALID_REGNUM, 67, 67 }, NULL, NULL },
- { "badva0", "", 4, 0, eEncodingUint, eFormatAddressInfo, { 68, 68, LLDB_INVALID_REGNUM, 68, 68 }, NULL, NULL },
- { "badva1", "", 4, 0, eEncodingUint, eFormatAddressInfo, { 69, 69, LLDB_INVALID_REGNUM, 69, 69 }, NULL, NULL },
- { "ssr" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 70, 70, LLDB_INVALID_REGNUM, 70, 70 }, NULL, NULL },
- { "ccr" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 71, 71, LLDB_INVALID_REGNUM, 71, 71 }, NULL, NULL },
- { "htid" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 72, 72, LLDB_INVALID_REGNUM, 72, 72 }, NULL, NULL },
+ { "stid" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 66, 66, LLDB_INVALID_REGNUM, 66, 66 }, nullptr, nullptr },
+ { "elr" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 67, 67, LLDB_INVALID_REGNUM, 67, 67 }, nullptr, nullptr },
+ { "badva0", "", 4, 0, eEncodingUint, eFormatAddressInfo, { 68, 68, LLDB_INVALID_REGNUM, 68, 68 }, nullptr, nullptr },
+ { "badva1", "", 4, 0, eEncodingUint, eFormatAddressInfo, { 69, 69, LLDB_INVALID_REGNUM, 69, 69 }, nullptr, nullptr },
+ { "ssr" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 70, 70, LLDB_INVALID_REGNUM, 70, 70 }, nullptr, nullptr },
+ { "ccr" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 71, 71, LLDB_INVALID_REGNUM, 71, 71 }, nullptr, nullptr },
+ { "htid" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 72, 72, LLDB_INVALID_REGNUM, 72, 72 }, nullptr, nullptr },
// PADDING {
- { "p20" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 73, 73, LLDB_INVALID_REGNUM, 73, 73 }, NULL, NULL },
+ { "p20" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 73, 73, LLDB_INVALID_REGNUM, 73, 73 }, nullptr, nullptr },
// }
- { "imask" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 74, 74, LLDB_INVALID_REGNUM, 74, 74 }, NULL, NULL },
+ { "imask" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 74, 74, LLDB_INVALID_REGNUM, 74, 74 }, nullptr, nullptr },
// PADDING {
- { "p21" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 75, 75, LLDB_INVALID_REGNUM, 75, 75 }, NULL, NULL },
- { "p22" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 76, 76, LLDB_INVALID_REGNUM, 76, 76 }, NULL, NULL },
- { "p23" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 77, 77, LLDB_INVALID_REGNUM, 77, 77 }, NULL, NULL },
- { "p24" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 78, 78, LLDB_INVALID_REGNUM, 78, 78 }, NULL, NULL },
- { "p25" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 79, 79, LLDB_INVALID_REGNUM, 79, 79 }, NULL, NULL },
+ { "p21" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 75, 75, LLDB_INVALID_REGNUM, 75, 75 }, nullptr, nullptr },
+ { "p22" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 76, 76, LLDB_INVALID_REGNUM, 76, 76 }, nullptr, nullptr },
+ { "p23" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 77, 77, LLDB_INVALID_REGNUM, 77, 77 }, nullptr, nullptr },
+ { "p24" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 78, 78, LLDB_INVALID_REGNUM, 78, 78 }, nullptr, nullptr },
+ { "p25" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 79, 79, LLDB_INVALID_REGNUM, 79, 79 }, nullptr, nullptr },
// }
- { "g0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 80, 80, LLDB_INVALID_REGNUM, 80, 80 }, NULL, NULL },
- { "g1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 81, 81, LLDB_INVALID_REGNUM, 81, 81 }, NULL, NULL },
- { "g2" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 82, 82, LLDB_INVALID_REGNUM, 82, 82 }, NULL, NULL },
- { "g3" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 83, 83, LLDB_INVALID_REGNUM, 83, 83 }, NULL, NULL }
+ { "g0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 80, 80, LLDB_INVALID_REGNUM, 80, 80 }, nullptr, nullptr },
+ { "g1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 81, 81, LLDB_INVALID_REGNUM, 81, 81 }, nullptr, nullptr },
+ { "g2" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 82, 82, LLDB_INVALID_REGNUM, 82, 82 }, nullptr, nullptr },
+ { "g3" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 83, 83, LLDB_INVALID_REGNUM, 83, 83 }, nullptr, nullptr }
};
static const uint32_t k_num_register_infos = sizeof(g_register_infos)/sizeof(RegisterInfo);
@@ -176,6 +179,7 @@ ABISysV_hexagon::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
ABISP
ABISysV_hexagon::CreateInstance ( const ArchSpec &arch )
{
@@ -273,7 +277,7 @@ ABISysV_hexagon::PrepareTrivialCall ( Thread &thread,
sp -= argSize;
// write this argument onto the stack of the host process
- proc.get( )->WriteMemory( sp, arg.data_ap.get(), arg.size, error );
+ proc->WriteMemory( sp, arg.data_ap.get(), arg.size, error );
if ( error.Fail( ) )
return false;
@@ -463,7 +467,7 @@ ABISysV_hexagon::RegisterIsCalleeSaved ( const RegisterInfo *reg_info )
}
void
-ABISysV_hexagon::Initialize( void )
+ABISysV_hexagon::Initialize()
{
PluginManager::RegisterPlugin
(
@@ -474,7 +478,7 @@ ABISysV_hexagon::Initialize( void )
}
void
-ABISysV_hexagon::Terminate( void )
+ABISysV_hexagon::Terminate()
{
PluginManager::UnregisterPlugin( CreateInstance );
}
@@ -489,14 +493,15 @@ ABISysV_hexagon::GetPluginNameStatic()
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
lldb_private::ConstString
-ABISysV_hexagon::GetPluginName( void )
+ABISysV_hexagon::GetPluginName()
{
return GetPluginNameStatic();
}
uint32_t
-ABISysV_hexagon::GetPluginVersion( void )
+ABISysV_hexagon::GetPluginVersion()
{
return 1;
}
diff --git a/source/Plugins/ABI/SysV-hexagon/Makefile b/source/Plugins/ABI/SysV-hexagon/Makefile
deleted file mode 100644
index 23733c7e551e..000000000000
--- a/source/Plugins/ABI/SysV-hexagon/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ABI/SysV-hexagon/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginABISysV_hexagon
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
index 0a3779a2ce94..d23afe9956ba 100644
--- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
+++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
@@ -8,6 +8,13 @@
#include "ABISysV_i386.h"
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
@@ -26,14 +33,9 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
using namespace lldb;
using namespace lldb_private;
-
-
// This source file uses the following document as a reference:
//====================================================================
// System V Application Binary Interface
@@ -51,8 +53,6 @@ using namespace lldb_private;
// February 3, 2015
//====================================================================
-
-
// DWARF Register Number Mapping
// See Table 2.14 of the reference document (specified on top of this file)
// Comment: Table 2.14 is followed till 'mm' entries.
@@ -107,7 +107,6 @@ enum dwarf_regnums
dwarf_mm7
};
-
static RegisterInfo g_register_infos[] =
{
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
@@ -187,10 +186,10 @@ ABISysV_i386::GetRegisterInfoArray (uint32_t &count)
return g_register_infos;
}
-
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
ABISP
ABISysV_i386::CreateInstance (const ArchSpec &arch)
{
@@ -272,7 +271,6 @@ ABISysV_i386::PrepareTrivialCall (Thread &thread,
return true;
}
-
static bool
ReadIntegerArgument (Scalar &scalar,
unsigned int bit_width,
@@ -294,7 +292,6 @@ ReadIntegerArgument (Scalar &scalar,
return false;
}
-
bool
ABISysV_i386::GetArgumentValues (Thread &thread,
ValueList &values) const
@@ -328,7 +325,7 @@ ABISysV_i386::GetArgumentValues (Thread &thread,
if (compiler_type)
{
bool is_signed;
- if (compiler_type.IsIntegerType (is_signed))
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
compiler_type.GetBitSize(&thread),
@@ -349,8 +346,6 @@ ABISysV_i386::GetArgumentValues (Thread &thread,
return true;
}
-
-
Error
ABISysV_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
{
@@ -496,12 +491,11 @@ ABISysV_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObje
are yet to be implemented */
error.SetErrorString ("Currently only Integral and Floating Point clang types are supported.");
}
- if(!register_write_successful)
+ if (!register_write_successful)
error.SetErrorString ("Register writing failed");
return error;
}
-
ValueObjectSP
ABISysV_i386::GetReturnValueObjectSimple (Thread &thread,
CompilerType &return_compiler_type) const
@@ -523,21 +517,19 @@ ABISysV_i386::GetReturnValueObjectSimple (Thread &thread,
unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
-
// Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
// The terminology 'Fundamental Data Types' used here is adopted from
// Table 2.1 of the reference document (specified on top of this file)
if (type_flags & eTypeIsPointer) // 'Pointer'
{
- uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff ;
+ uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
value.SetValueType(Value::eValueTypeScalar);
value.GetScalar() = ptr;
return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
value,
ConstString(""));
}
-
else if ((type_flags & eTypeIsScalar) || (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
{
value.SetValueType(Value::eValueTypeScalar);
@@ -547,7 +539,7 @@ ABISysV_i386::GetReturnValueObjectSimple (Thread &thread,
if (type_flags & eTypeIsInteger) // 'Integral' except enum
{
const bool is_signed = ((type_flags & eTypeIsSigned) != 0);
- uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff ;
+ uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
raw_value |= (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) & 0xffffffff) << 32;
switch (byte_size)
@@ -558,7 +550,7 @@ ABISysV_i386::GetReturnValueObjectSimple (Thread &thread,
case 16:
// For clang::BuiltinType::UInt128 & Int128
// ToDo: Need to decide how to handle it
- break ;
+ break;
case 8:
if (is_signed)
@@ -598,17 +590,15 @@ ABISysV_i386::GetReturnValueObjectSimple (Thread &thread,
value,
ConstString(""));
}
-
else if (type_flags & eTypeIsEnumeration) // handles enum
{
- uint32_t enm = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff ;
+ uint32_t enm = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
value.SetValueType(Value::eValueTypeScalar);
value.GetScalar() = enm;
return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
value,
ConstString(""));
}
-
else if (type_flags & eTypeIsFloat) // 'Floating Point'
{
if (byte_size <= 12) // handles float, double, long double, __float80
@@ -660,19 +650,16 @@ ABISysV_i386::GetReturnValueObjectSimple (Thread &thread,
return_compiler_type);
}
}
-
else // Neither 'Integral' nor 'Floating Point'
{
// If flow reaches here then check type_flags
// This type_flags is unhandled
}
}
-
else if (type_flags & eTypeIsComplex) // 'Complex Floating Point'
{
// ToDo: Yet to be implemented
}
-
else if (type_flags & eTypeIsVector) // 'Packed'
{
const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
@@ -754,7 +741,6 @@ ABISysV_i386::GetReturnValueObjectSimple (Thread &thread,
}
}
}
-
else // 'Decimal Floating Point'
{
//ToDo: Yet to be implemented
@@ -762,7 +748,6 @@ ABISysV_i386::GetReturnValueObjectSimple (Thread &thread,
return return_valobj_sp;
}
-
ValueObjectSP
ABISysV_i386::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_compiler_type) const
{
@@ -848,7 +833,6 @@ ABISysV_i386::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
return true;
}
-
// According to "Register Usage" in reference document (specified on top
// of this source file) ebx, ebp, esi, edi and esp registers are preserved
// i.e. non-volatile i.e. callee-saved on i386
@@ -893,7 +877,6 @@ ABISysV_i386::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
return false;
}
-
void
ABISysV_i386::Initialize()
{
@@ -902,17 +885,16 @@ ABISysV_i386::Initialize()
CreateInstance);
}
-
void
ABISysV_i386::Terminate()
{
PluginManager::UnregisterPlugin (CreateInstance);
}
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
lldb_private::ConstString
ABISysV_i386::GetPluginNameStatic()
{
@@ -920,7 +902,6 @@ ABISysV_i386::GetPluginNameStatic()
return g_name;
}
-
lldb_private::ConstString
ABISysV_i386::GetPluginName()
{
diff --git a/source/Plugins/ABI/SysV-i386/Makefile b/source/Plugins/ABI/SysV-i386/Makefile
deleted file mode 100644
index 0ac3cbee2d54..000000000000
--- a/source/Plugins/ABI/SysV-i386/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ABI/SysV-i386/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginABISysV_i386
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
index 1b77946c1d1f..d6b57f9f3939 100644
--- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
+++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
@@ -9,6 +9,13 @@
#include "ABISysV_mips.h"
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
@@ -27,9 +34,6 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -80,44 +84,44 @@ g_register_infos[] =
{
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGINS LLDB NATIVE VALUE REGS INVALIDATE REGS
// ======== ====== == === ============= =========== ============ ============== ============ ================= =================== ========== =================
- { "r0" , "zero", 4, 0, eEncodingUint, eFormatHex, { dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r1" , "AT", 4, 0, eEncodingUint, eFormatHex, { dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r2" , "v0", 4, 0, eEncodingUint, eFormatHex, { dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r3" , "v1", 4, 0, eEncodingUint, eFormatHex, { dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r4" , "arg1", 4, 0, eEncodingUint, eFormatHex, { dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r5" , "arg2", 4, 0, eEncodingUint, eFormatHex, { dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r6" , "arg3", 4, 0, eEncodingUint, eFormatHex, { dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r7" , "arg4", 4, 0, eEncodingUint, eFormatHex, { dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r8" , "arg5", 4, 0, eEncodingUint, eFormatHex, { dwarf_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r9" , "arg6", 4, 0, eEncodingUint, eFormatHex, { dwarf_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r10" , "arg7", 4, 0, eEncodingUint, eFormatHex, { dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r11" , "arg8", 4, 0, eEncodingUint, eFormatHex, { dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r12" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r15" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r16" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r17" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r18" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r19" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r20" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r21" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r22" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r23" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r24" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r25" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r26" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r27" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r28" , "gp", 4, 0, eEncodingUint, eFormatHex, { dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r29" , "sp", 4, 0, eEncodingUint, eFormatHex, { dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r30" , "fp", 4, 0, eEncodingUint, eFormatHex, { dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r31" , "ra", 4, 0, eEncodingUint, eFormatHex, { dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "sr" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "lo" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "hi" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "bad" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "cause" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "pc" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
+ { "r0" , "zero", 4, 0, eEncodingUint, eFormatHex, { dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r1" , "AT", 4, 0, eEncodingUint, eFormatHex, { dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r2" , "v0", 4, 0, eEncodingUint, eFormatHex, { dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r3" , "v1", 4, 0, eEncodingUint, eFormatHex, { dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r4" , "arg1", 4, 0, eEncodingUint, eFormatHex, { dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r5" , "arg2", 4, 0, eEncodingUint, eFormatHex, { dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r6" , "arg3", 4, 0, eEncodingUint, eFormatHex, { dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r7" , "arg4", 4, 0, eEncodingUint, eFormatHex, { dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r8" , "arg5", 4, 0, eEncodingUint, eFormatHex, { dwarf_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r9" , "arg6", 4, 0, eEncodingUint, eFormatHex, { dwarf_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r10" , "arg7", 4, 0, eEncodingUint, eFormatHex, { dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r11" , "arg8", 4, 0, eEncodingUint, eFormatHex, { dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r12" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r15" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r16" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r17" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r18" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r19" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r20" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r21" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r22" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r23" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r24" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r25" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r26" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r27" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r28" , "gp", 4, 0, eEncodingUint, eFormatHex, { dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r29" , "sp", 4, 0, eEncodingUint, eFormatHex, { dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r30" , "fp", 4, 0, eEncodingUint, eFormatHex, { dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r31" , "ra", 4, 0, eEncodingUint, eFormatHex, { dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "sr" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "lo" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "hi" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "bad" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "cause" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "pc" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
};
static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
@@ -138,6 +142,7 @@ ABISysV_mips::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
ABISP
ABISysV_mips::CreateInstance (const ArchSpec &arch)
{
@@ -181,7 +186,7 @@ ABISysV_mips::PrepareTrivialCall (Thread &thread,
if (!reg_ctx)
return false;
- const RegisterInfo *reg_info = NULL;
+ const RegisterInfo *reg_info = nullptr;
RegisterValue reg_value;
@@ -317,7 +322,7 @@ ABISysV_mips::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObje
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
bool set_it_simple = false;
- if (compiler_type.IsIntegerType (is_signed) || compiler_type.IsPointerType())
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
{
DataExtractor data;
Error data_error;
@@ -372,7 +377,6 @@ ABISysV_mips::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObje
return error;
}
-
ValueObjectSP
ABISysV_mips::GetReturnValueObjectSimple (Thread &thread, CompilerType &return_compiler_type) const
{
@@ -390,10 +394,14 @@ ABISysV_mips::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_com
return return_valobj_sp;
ExecutionContext exe_ctx (thread.shared_from_this());
- if (exe_ctx.GetTargetPtr() == NULL || exe_ctx.GetProcessPtr() == NULL)
+ if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
return return_valobj_sp;
+ Target *target = exe_ctx.GetTargetPtr();
+ const ArchSpec target_arch = target->GetArchitecture();
+ ByteOrder target_byte_order = target_arch.GetByteOrder();
value.SetCompilerType(return_compiler_type);
+ uint32_t fp_flag = target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
if (!reg_ctx)
@@ -405,9 +413,8 @@ ABISysV_mips::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_com
// In MIPS register "r2" (v0) holds the integer function return values
const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
- size_t bit_width = return_compiler_type.GetBitSize(&thread);
-
- if (return_compiler_type.IsIntegerType (is_signed))
+ size_t bit_width = return_compiler_type.GetBitSize(&thread);
+ if (return_compiler_type.IsIntegerOrEnumerationType (is_signed))
{
switch (bit_width)
{
@@ -455,45 +462,115 @@ ABISysV_mips::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_com
// Structure/Vector is always passed in memory and pointer to that memory is passed in r2.
uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r2", 0), 0);
// We have got the address. Create a memory object out of it
- return_valobj_sp = ValueObjectMemory::Create (&thread,
- "",
- Address (mem_address, NULL),
- return_compiler_type);
+ return_valobj_sp = ValueObjectMemory::Create(&thread,
+ "",
+ Address(mem_address, nullptr),
+ return_compiler_type);
return return_valobj_sp;
}
else if (return_compiler_type.IsFloatingPointType (count, is_complex))
{
- const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
- const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
-
- if (count == 1 && !is_complex)
+ if (IsSoftFloat (fp_flag))
{
+ uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0);
+ if (count != 1 && is_complex)
+ return return_valobj_sp;
switch (bit_width)
{
default:
return return_valobj_sp;
- case 64:
- {
- static_assert(sizeof(double) == sizeof(uint64_t), "");
- uint64_t raw_value;
- raw_value = reg_ctx->ReadRegisterAsUnsigned(f0_info, 0) & UINT32_MAX;
- raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(f1_info, 0) & UINT32_MAX)) << 32;
- value.GetScalar() = *reinterpret_cast<double*>(&raw_value);
- break;
- }
case 32:
- {
static_assert(sizeof(float) == sizeof(uint32_t), "");
- uint32_t raw_value = reg_ctx->ReadRegisterAsUnsigned(f0_info, 0) & UINT32_MAX;
- value.GetScalar() = *reinterpret_cast<float*>(&raw_value);
+ value.GetScalar() = *((float *)(&raw_value));
+ break;
+ case 64:
+ static_assert(sizeof(double) == sizeof(uint64_t), "");
+ const RegisterInfo *r3_reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+ if (target_byte_order == eByteOrderLittle)
+ raw_value = ((reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0)) << 32) | raw_value;
+ else
+ raw_value = (raw_value << 32) | reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0);
+ value.GetScalar() = *((double *)(&raw_value));
break;
- }
}
}
+
else
{
- // not handled yet
- return return_valobj_sp;
+ const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
+ RegisterValue f0_value;
+ DataExtractor f0_data;
+ reg_ctx->ReadRegister (f0_info, f0_value);
+ f0_value.GetData(f0_data);
+ lldb::offset_t offset = 0;
+
+ if (count == 1 && !is_complex)
+ {
+ switch (bit_width)
+ {
+ default:
+ return return_valobj_sp;
+ case 64:
+ {
+ static_assert(sizeof(double) == sizeof(uint64_t), "");
+ const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
+ RegisterValue f1_value;
+ DataExtractor f1_data;
+ reg_ctx->ReadRegister (f1_info, f1_value);
+ DataExtractor *copy_from_extractor = nullptr;
+ DataBufferSP data_sp (new DataBufferHeap(8, 0));
+ DataExtractor return_ext (data_sp,
+ target_byte_order,
+ target->GetArchitecture().GetAddressByteSize());
+
+ if (target_byte_order == eByteOrderLittle)
+ {
+ copy_from_extractor = &f0_data;
+ copy_from_extractor->CopyByteOrderedData (offset,
+ 4,
+ data_sp->GetBytes(),
+ 4,
+ target_byte_order);
+ f1_value.GetData(f1_data);
+ copy_from_extractor = &f1_data;
+ copy_from_extractor->CopyByteOrderedData (offset,
+ 4,
+ data_sp->GetBytes() + 4,
+ 4,
+ target_byte_order);
+ }
+ else
+ {
+ copy_from_extractor = &f0_data;
+ copy_from_extractor->CopyByteOrderedData (offset,
+ 4,
+ data_sp->GetBytes() + 4,
+ 4,
+ target_byte_order);
+ f1_value.GetData(f1_data);
+ copy_from_extractor = &f1_data;
+ copy_from_extractor->CopyByteOrderedData (offset,
+ 4,
+ data_sp->GetBytes(),
+ 4,
+ target_byte_order);
+ }
+ value.GetScalar() = (double) return_ext.GetDouble(&offset);
+ break;
+ }
+ case 32:
+ {
+ static_assert(sizeof(float) == sizeof(uint32_t), "");
+ value.GetScalar() = (float) f0_data.GetFloat(&offset);
+ break;
+ }
+ }
+ }
+ else
+ {
+ // not handled yet
+ return return_valobj_sp;
+ }
}
}
else
@@ -559,6 +636,12 @@ ABISysV_mips::RegisterIsVolatile (const RegisterInfo *reg_info)
}
bool
+ABISysV_mips::IsSoftFloat(uint32_t fp_flags) const
+{
+ return (fp_flags == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
+}
+
+bool
ABISysV_mips::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
{
if (reg_info)
@@ -623,6 +706,7 @@ ABISysV_mips::GetPluginNameStatic()
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
lldb_private::ConstString
ABISysV_mips::GetPluginName()
{
diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.h b/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
index 709c3bfe3adf..388009d0fa00 100644
--- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
+++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
@@ -54,6 +54,9 @@ public:
RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
bool
+ IsSoftFloat(uint32_t fp_flag) const;
+
+ bool
CallFrameAddressIsValid(lldb::addr_t cfa) override
{
// Make sure the stack call frame addresses are 8 byte aligned
diff --git a/source/Plugins/ABI/SysV-mips/Makefile b/source/Plugins/ABI/SysV-mips/Makefile
deleted file mode 100644
index c61130628433..000000000000
--- a/source/Plugins/ABI/SysV-mips/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ABI/SysV-mips/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginABISysV_mips
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
index 8226ef15f494..f74871544b69 100644
--- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
+++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_mips64.cpp ----------------------------------------*- C++ -*-===//
+//===-- ABISysV_mips64.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,6 +9,13 @@
#include "ABISysV_mips64.h"
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
@@ -27,9 +34,6 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -80,44 +84,44 @@ g_register_infos_mips64[] =
{
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
// ======== ====== == === ============= ========== ============= ================= ==================== ================= ==================== ========== ===============
- { "r0" , "zero", 8, 0, eEncodingUint, eFormatHex, { dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r1" , "AT", 8, 0, eEncodingUint, eFormatHex, { dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r2" , "v0", 8, 0, eEncodingUint, eFormatHex, { dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r3" , "v1", 8, 0, eEncodingUint, eFormatHex, { dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r4" , "arg1", 8, 0, eEncodingUint, eFormatHex, { dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r5" , "arg2", 8, 0, eEncodingUint, eFormatHex, { dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r6" , "arg3", 8, 0, eEncodingUint, eFormatHex, { dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r7" , "arg4", 8, 0, eEncodingUint, eFormatHex, { dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r8" , "arg5", 8, 0, eEncodingUint, eFormatHex, { dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r9" , "arg6", 8, 0, eEncodingUint, eFormatHex, { dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r10" , "arg7", 8, 0, eEncodingUint, eFormatHex, { dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r11" , "arg8", 8, 0, eEncodingUint, eFormatHex, { dwarf_r11, dwarf_r11, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r12" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r15" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r16" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r17" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r18" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r19" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r20" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r21" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r22" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r23" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r24" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r25" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r26" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r27" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r28" , "gp", 8, 0, eEncodingUint, eFormatHex, { dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r29" , "sp", 8, 0, eEncodingUint, eFormatHex, { dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r30" , "fp", 8, 0, eEncodingUint, eFormatHex, { dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r31" , "ra", 8, 0, eEncodingUint, eFormatHex, { dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "sr" , NULL, 4, 0, eEncodingUint, eFormatHex, { dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "lo" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "hi" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "bad" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "cause" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "pc" , NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
+ { "r0" , "zero", 8, 0, eEncodingUint, eFormatHex, { dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r1" , "AT", 8, 0, eEncodingUint, eFormatHex, { dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r2" , "v0", 8, 0, eEncodingUint, eFormatHex, { dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r3" , "v1", 8, 0, eEncodingUint, eFormatHex, { dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r4" , "arg1", 8, 0, eEncodingUint, eFormatHex, { dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r5" , "arg2", 8, 0, eEncodingUint, eFormatHex, { dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r6" , "arg3", 8, 0, eEncodingUint, eFormatHex, { dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r7" , "arg4", 8, 0, eEncodingUint, eFormatHex, { dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r8" , "arg5", 8, 0, eEncodingUint, eFormatHex, { dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r9" , "arg6", 8, 0, eEncodingUint, eFormatHex, { dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r10" , "arg7", 8, 0, eEncodingUint, eFormatHex, { dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r11" , "arg8", 8, 0, eEncodingUint, eFormatHex, { dwarf_r11, dwarf_r11, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r12" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r15" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r16" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r17" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r18" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r19" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r20" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r21" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r22" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r23" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r24" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r25" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r26" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r27" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r28" , "gp", 8, 0, eEncodingUint, eFormatHex, { dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r29" , "sp", 8, 0, eEncodingUint, eFormatHex, { dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r30" , "fp", 8, 0, eEncodingUint, eFormatHex, { dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r31" , "ra", 8, 0, eEncodingUint, eFormatHex, { dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "sr" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "lo" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "hi" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "bad" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "cause" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "pc" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
};
static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos_mips64);
@@ -138,6 +142,7 @@ ABISysV_mips64::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
ABISP
ABISysV_mips64::CreateInstance (const ArchSpec &arch)
{
@@ -181,7 +186,7 @@ ABISysV_mips64::PrepareTrivialCall (Thread &thread,
if (!reg_ctx)
return false;
- const RegisterInfo *reg_info = NULL;
+ const RegisterInfo *reg_info = nullptr;
if (args.size() > 8) // TODO handle more than 8 arguments
return false;
@@ -289,7 +294,7 @@ ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb
return error;
}
- const uint32_t type_flags = compiler_type.GetTypeInfo (NULL);
+ const uint32_t type_flags = compiler_type.GetTypeInfo(nullptr);
if (type_flags & eTypeIsScalar ||
type_flags & eTypeIsPointer)
@@ -342,7 +347,6 @@ ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb
return error;
}
-
ValueObjectSP
ABISysV_mips64::GetReturnValueObjectSimple (Thread &thread, CompilerType &return_compiler_type) const
{
@@ -358,7 +362,7 @@ ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
Error error;
ExecutionContext exe_ctx (thread.shared_from_this());
- if (exe_ctx.GetTargetPtr() == NULL || exe_ctx.GetProcessPtr() == NULL)
+ if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
return return_valobj_sp;
value.SetCompilerType(return_compiler_type);
@@ -368,9 +372,11 @@ ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
return return_valobj_sp;
Target *target = exe_ctx.GetTargetPtr();
- ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
+ const ArchSpec target_arch = target->GetArchitecture();
+ ByteOrder target_byte_order = target_arch.GetByteOrder();
const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- const uint32_t type_flags = return_compiler_type.GetTypeInfo (NULL);
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
+ uint32_t fp_flag = target_arch.GetFlags () & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
@@ -434,20 +440,52 @@ ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
{
// Don't handle complex yet.
}
+ else if (IsSoftFloat(fp_flag))
+ {
+ uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
+ switch (byte_size)
+ {
+ case 4:
+ value.GetScalar() = *((float *)(&raw_value));
+ success = true;
+ break;
+ case 8:
+ value.GetScalar() = *((double *)(&raw_value));
+ success = true;
+ break;
+ case 16:
+ uint64_t result[2];
+ if (target_byte_order == eByteOrderLittle)
+ {
+ result[0] = raw_value;
+ result[1] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
+ value.GetScalar() = *((long double *)(result));
+ }
+ else
+ {
+ result[0] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
+ result[1] = raw_value;
+ value.GetScalar() = *((long double *)(result));
+ }
+ success = true;
+ break;
+ }
+
+ }
else
{
if (byte_size <= sizeof(long double))
{
const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
- const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0);
- RegisterValue f0_value, f2_value;
- DataExtractor f0_data, f2_data;
+
+ RegisterValue f0_value;
+ DataExtractor f0_data;
reg_ctx->ReadRegister (f0_info, f0_value);
- reg_ctx->ReadRegister (f2_info, f2_value);
+
f0_value.GetData(f0_data);
- f2_value.GetData(f2_data);
+
lldb::offset_t offset = 0;
if (byte_size == sizeof(float))
@@ -462,7 +500,11 @@ ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
}
else if (byte_size == sizeof(long double))
{
- DataExtractor *copy_from_extractor = NULL;
+ const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0);
+ RegisterValue f2_value;
+ DataExtractor f2_data;
+ reg_ctx->ReadRegister (f2_info, f2_value);
+ DataExtractor *copy_from_extractor = nullptr;
DataBufferSP data_sp (new DataBufferHeap(16, 0));
DataExtractor return_ext (data_sp,
target_byte_order,
@@ -470,27 +512,42 @@ ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
if (target_byte_order == eByteOrderLittle)
{
- f0_data.Append(f2_data);
copy_from_extractor = &f0_data;
+ copy_from_extractor->CopyByteOrderedData (0,
+ 8,
+ data_sp->GetBytes(),
+ byte_size - 8,
+ target_byte_order);
+ f2_value.GetData(f2_data);
+ copy_from_extractor = &f2_data;
+ copy_from_extractor->CopyByteOrderedData (0,
+ 8,
+ data_sp->GetBytes() + 8,
+ byte_size - 8,
+ target_byte_order);
}
else
{
- f2_data.Append(f0_data);
- copy_from_extractor = &f2_data;
+ copy_from_extractor = &f0_data;
+ copy_from_extractor->CopyByteOrderedData (0,
+ 8,
+ data_sp->GetBytes() + 8,
+ byte_size - 8,
+ target_byte_order);
+ f2_value.GetData(f2_data);
+ copy_from_extractor = &f2_data;
+ copy_from_extractor->CopyByteOrderedData (0,
+ 8,
+ data_sp->GetBytes(),
+ byte_size - 8,
+ target_byte_order);
}
- copy_from_extractor->CopyByteOrderedData (0,
- byte_size,
- data_sp->GetBytes(),
- byte_size,
- target_byte_order);
-
return_valobj_sp = ValueObjectConstResult::Create (&thread,
return_compiler_type,
ConstString(""),
return_ext);
return return_valobj_sp;
-
}
}
}
@@ -535,7 +592,7 @@ ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
// Check if this structure contains only floating point fields
for (uint32_t idx = 0; idx < num_children; idx++)
{
- CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
+ CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset, nullptr, nullptr);
if (field_compiler_type.IsFloatingPointType (count, is_complex))
use_fp_regs = 1;
@@ -559,10 +616,10 @@ ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
for (uint32_t idx = 0; idx < num_children; idx++)
{
- CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
+ CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset, nullptr, nullptr);
const size_t field_byte_width = field_compiler_type.GetByteSize(nullptr);
- DataExtractor *copy_from_extractor = NULL;
+ DataExtractor *copy_from_extractor = nullptr;
if (idx == 0)
{
@@ -620,7 +677,7 @@ ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
bool is_signed;
uint32_t padding;
- CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
+ CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset, nullptr, nullptr);
const size_t field_byte_width = field_compiler_type.GetByteSize(nullptr);
// if we don't know the size of the field (e.g. invalid type), just bail out
@@ -629,7 +686,7 @@ ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
uint32_t field_byte_offset = field_bit_offset/8;
- if (field_compiler_type.IsIntegerType (is_signed)
+ if (field_compiler_type.IsIntegerOrEnumerationType (is_signed)
|| field_compiler_type.IsPointerType ()
|| field_compiler_type.IsFloatingPointType (count, is_complex))
{
@@ -661,7 +718,7 @@ ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
else
{
// There isn't any space left for this field, this should not happen as we have already checked
- // the overall size is not greater than 16 bytes. For now, return a NULL return value object.
+ // the overall size is not greater than 16 bytes. For now, return a nullptr return value object.
return return_valobj_sp;
}
}
@@ -720,10 +777,10 @@ ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r2", 0), 0);
// We have got the address. Create a memory object out of it
- return_valobj_sp = ValueObjectMemory::Create (&thread,
- "",
- Address (mem_address, NULL),
- return_compiler_type);
+ return_valobj_sp = ValueObjectMemory::Create(&thread,
+ "",
+ Address(mem_address, nullptr),
+ return_compiler_type);
}
return return_valobj_sp;
}
@@ -777,6 +834,12 @@ ABISysV_mips64::RegisterIsVolatile (const RegisterInfo *reg_info)
}
bool
+ABISysV_mips64::IsSoftFloat (uint32_t fp_flag) const
+{
+ return (fp_flag == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
+}
+
+bool
ABISysV_mips64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
{
if (reg_info)
@@ -818,6 +881,7 @@ ABISysV_mips64::GetPluginNameStatic()
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
lldb_private::ConstString
ABISysV_mips64::GetPluginName()
{
diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
index 3290331e05a0..9f1ea0922db3 100644
--- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
+++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
@@ -53,6 +53,9 @@ public:
bool
RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+ bool
+ IsSoftFloat(uint32_t fp_flag) const;
+
// The SysV mips ABI requires that stack frames be 16 byte aligned.
// When there is a trap handler on the stack, e.g. _sigtramp in userland
// code, we've seen that the stack pointer is often not aligned properly
diff --git a/source/Plugins/ABI/SysV-mips64/Makefile b/source/Plugins/ABI/SysV-mips64/Makefile
deleted file mode 100644
index b7e6dc615cb0..000000000000
--- a/source/Plugins/ABI/SysV-mips64/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ABI/SysV-mips64/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginABISysV_mips64
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
index f0da18637ba8..20ff17d0b763 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_ppc.cpp --------------------------------------*- C++ -*-===//
+//===-- ABISysV_ppc.cpp -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,6 +9,13 @@
#include "ABISysV_ppc.h"
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
@@ -27,9 +34,6 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -111,49 +115,50 @@ enum dwarf_regnums
// Note that the size and offset will be updated by platform-specific classes.
#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
{ #reg, alt, 8, 0, eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4}, NULL, NULL }
+ eFormatHex, { kind1, kind2, kind3, kind4}, nullptr, nullptr }
+
static const RegisterInfo
g_register_infos[] =
{
// General purpose registers. eh_frame, DWARF, Generic, Process Plugin
- DEFINE_GPR(r0, NULL, dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r1, "sp", dwarf_r1, dwarf_r1, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r2, NULL, dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r3, "arg1",dwarf_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r4, "arg2",dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG2 ,LLDB_INVALID_REGNUM),
- DEFINE_GPR(r5, "arg3",dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r6, "arg4",dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r7, "arg5",dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r8, "arg6",dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r9, "arg7",dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r10, "arg8",dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r11, NULL, dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r12, NULL, dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r13, NULL, dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r14, NULL, dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r15, NULL, dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r16, NULL, dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r17, NULL, dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r18, NULL, dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r19, NULL, dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r20, NULL, dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r21, NULL, dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r22, NULL, dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r23, NULL, dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r24, NULL, dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r25, NULL, dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r26, NULL, dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r27, NULL, dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r28, NULL, dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r29, NULL, dwarf_r29, dwarf_r29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r30, NULL, dwarf_r30, dwarf_r30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r31, NULL, dwarf_r31, dwarf_r31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(lr, "lr", dwarf_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM),
- DEFINE_GPR(cr, "cr", dwarf_cr, dwarf_cr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
- DEFINE_GPR(xer, "xer", dwarf_xer, dwarf_xer, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ctr, "ctr", dwarf_ctr, dwarf_ctr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(pc, "pc", dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
- { NULL, NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_cfa, dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, NULL, NULL},
+ DEFINE_GPR(r0, nullptr, dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r1, "sp", dwarf_r1, dwarf_r1, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r2, nullptr, dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r3, "arg1", dwarf_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r4, "arg2", dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG2 ,LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r5, "arg3", dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r6, "arg4", dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r7, "arg5", dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, "arg6", dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, "arg7", dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, "arg8", dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r16, nullptr, dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r17, nullptr, dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r18, nullptr, dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r19, nullptr, dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r20, nullptr, dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r21, nullptr, dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r22, nullptr, dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r23, nullptr, dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r24, nullptr, dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r25, nullptr, dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r26, nullptr, dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r27, nullptr, dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r28, nullptr, dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r29, nullptr, dwarf_r29, dwarf_r29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r30, nullptr, dwarf_r30, dwarf_r30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r31, nullptr, dwarf_r31, dwarf_r31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(lr, "lr", dwarf_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cr, "cr", dwarf_cr, dwarf_cr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(xer, "xer", dwarf_xer, dwarf_xer, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ctr, "ctr", dwarf_ctr, dwarf_ctr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(pc, "pc", dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ { nullptr, nullptr, 8, 0, eEncodingUint, eFormatHex, { dwarf_cfa, dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr }
};
static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
@@ -165,7 +170,6 @@ ABISysV_ppc::GetRegisterInfoArray (uint32_t &count)
return g_register_infos;
}
-
size_t
ABISysV_ppc::GetRedZoneSize () const
{
@@ -175,6 +179,7 @@ ABISysV_ppc::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
ABISP
ABISysV_ppc::CreateInstance (const ArchSpec &arch)
{
@@ -216,7 +221,7 @@ ABISysV_ppc::PrepareTrivialCall (Thread &thread,
if (!reg_ctx)
return false;
- const RegisterInfo *reg_info = NULL;
+ const RegisterInfo *reg_info = nullptr;
if (args.size() > 8) // TODO handle more than 8 arguments
return false;
@@ -398,7 +403,7 @@ ABISysV_ppc::GetArgumentValues (Thread &thread,
return false;
bool is_signed;
- if (compiler_type.IsIntegerType (is_signed))
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
compiler_type.GetBitSize(&thread),
@@ -449,7 +454,7 @@ ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjec
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
bool set_it_simple = false;
- if (compiler_type.IsIntegerType (is_signed) || compiler_type.IsPointerType())
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
{
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
@@ -473,7 +478,6 @@ ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjec
{
error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
}
-
}
else if (compiler_type.IsFloatingPointType (count, is_complex))
{
@@ -517,7 +521,6 @@ ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjec
return error;
}
-
ValueObjectSP
ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
CompilerType &return_compiler_type) const
@@ -625,7 +628,6 @@ ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
value,
ConstString(""));
-
}
else if (type_flags & eTypeIsPointer)
{
@@ -641,7 +643,6 @@ ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
if (byte_size > 0)
{
-
const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
if (altivec_reg)
{
@@ -738,7 +739,7 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_comp
bool is_complex;
uint32_t count;
- CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
+ CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset, nullptr, nullptr);
const size_t field_bit_width = field_compiler_type.GetBitSize(&thread);
// If there are any unaligned fields, this is stored in memory.
@@ -751,11 +752,10 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_comp
uint32_t field_byte_width = field_bit_width/8;
uint32_t field_byte_offset = field_bit_offset/8;
-
- DataExtractor *copy_from_extractor = NULL;
+ DataExtractor *copy_from_extractor = nullptr;
uint32_t copy_from_offset = 0;
- if (field_compiler_type.IsIntegerType (is_signed) || field_compiler_type.IsPointerType ())
+ if (field_compiler_type.IsIntegerOrEnumerationType (is_signed) || field_compiler_type.IsPointerType ())
{
if (integer_bytes < 8)
{
@@ -772,7 +772,6 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_comp
copy_from_extractor = &rdx_data;
copy_from_offset = 0;
integer_bytes = 8 + field_byte_width;
-
}
}
else if (integer_bytes + field_byte_width <= 16)
@@ -784,7 +783,7 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_comp
else
{
// The last field didn't fit. I can't see how that would happen w/o the overall size being
- // greater than 16 bytes. For now, return a NULL return value object.
+ // greater than 16 bytes. For now, return a nullptr return value object.
return return_valobj_sp;
}
}
@@ -818,9 +817,9 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_comp
CompilerType next_field_compiler_type = return_compiler_type.GetFieldAtIndex (idx + 1,
name,
&next_field_bit_offset,
- NULL,
- NULL);
- if (next_field_compiler_type.IsIntegerType (is_signed))
+ nullptr,
+ nullptr);
+ if (next_field_compiler_type.IsIntegerOrEnumerationType (is_signed))
in_gpr = true;
else
{
@@ -828,7 +827,6 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_comp
in_gpr = false;
}
}
-
}
else if (field_byte_offset % 4 == 0)
{
@@ -842,9 +840,9 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_comp
CompilerType prev_field_compiler_type = return_compiler_type.GetFieldAtIndex (idx - 1,
name,
&prev_field_bit_offset,
- NULL,
- NULL);
- if (prev_field_compiler_type.IsIntegerType (is_signed))
+ nullptr,
+ nullptr);
+ if (prev_field_compiler_type.IsIntegerOrEnumerationType (is_signed))
in_gpr = true;
else
{
@@ -852,7 +850,6 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_comp
in_gpr = false;
}
}
-
}
else
{
@@ -909,7 +906,6 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_comp
}
}
-
// FIXME: This is just taking a guess, r3 may very well no longer hold the return storage location.
// If we are going to do this right, when we make a new frame we should check to see if it uses a memory
// return, and if we are at the first instruction and if so stash away the return location. Then we would
@@ -919,10 +915,10 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_comp
{
unsigned r3_id = reg_ctx_sp->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
- return_valobj_sp = ValueObjectMemory::Create (&thread,
- "",
- Address (storage_addr, NULL),
- return_compiler_type);
+ return_valobj_sp = ValueObjectMemory::Create(&thread,
+ "",
+ Address(storage_addr, nullptr),
+ return_compiler_type);
}
}
@@ -987,8 +983,6 @@ ABISysV_ppc::RegisterIsVolatile (const RegisterInfo *reg_info)
return !RegisterIsCalleeSaved (reg_info);
}
-
-
// See "Register Usage" in the
// "System V Application Binary Interface"
// "64-bit PowerPC ELF Application Binary Interface Supplement"
@@ -1034,8 +1028,6 @@ ABISysV_ppc::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
return false;
}
-
-
void
ABISysV_ppc::Initialize()
{
@@ -1060,6 +1052,7 @@ ABISysV_ppc::GetPluginNameStatic()
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
lldb_private::ConstString
ABISysV_ppc::GetPluginName()
{
@@ -1071,4 +1064,3 @@ ABISysV_ppc::GetPluginVersion()
{
return 1;
}
-
diff --git a/source/Plugins/ABI/SysV-ppc/Makefile b/source/Plugins/ABI/SysV-ppc/Makefile
deleted file mode 100644
index 7a6d38d68337..000000000000
--- a/source/Plugins/ABI/SysV-ppc/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ABI/SysV-hexagon/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginABISysV_ppc
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
index 96c54ce97eec..fea847dd17ee 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_ppc64.cpp --------------------------------------*- C++ -*-===//
+//===-- ABISysV_ppc64.cpp ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,6 +9,13 @@
#include "ABISysV_ppc64.h"
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
@@ -27,9 +34,6 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -108,53 +112,53 @@ enum dwarf_regnums
dwarf_cfa,
};
-
// Note that the size and offset will be updated by platform-specific classes.
#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
{ #reg, alt, 8, 0, eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4}, NULL, NULL }
+ eFormatHex, { kind1, kind2, kind3, kind4}, nullptr, nullptr }
+
static const RegisterInfo
g_register_infos[] =
{
// General purpose registers. eh_frame, DWARF, Generic, Process Plugin
- DEFINE_GPR(r0, NULL, dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r1, "sp", dwarf_r1, dwarf_r1, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r2, NULL, dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r3, "arg1",dwarf_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r4, "arg2",dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG2 ,LLDB_INVALID_REGNUM),
- DEFINE_GPR(r5, "arg3",dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r6, "arg4",dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r7, "arg5",dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r8, "arg6",dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r9, "arg7",dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r10, "arg8",dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r11, NULL, dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r12, NULL, dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r13, NULL, dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r14, NULL, dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r15, NULL, dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r16, NULL, dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r17, NULL, dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r18, NULL, dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r19, NULL, dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r20, NULL, dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r21, NULL, dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r22, NULL, dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r23, NULL, dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r24, NULL, dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r25, NULL, dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r26, NULL, dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r27, NULL, dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r28, NULL, dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r29, NULL, dwarf_r29, dwarf_r29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r30, NULL, dwarf_r30, dwarf_r30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r31, NULL, dwarf_r31, dwarf_r31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(lr, "lr", dwarf_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM),
- DEFINE_GPR(cr, "cr", dwarf_cr, dwarf_cr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
- DEFINE_GPR(xer, "xer", dwarf_xer, dwarf_xer, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ctr, "ctr", dwarf_ctr, dwarf_ctr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(pc, "pc", dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
- { NULL, NULL, 8, 0, eEncodingUint, eFormatHex, { dwarf_cfa, dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, NULL, NULL},
+ DEFINE_GPR(r0, nullptr, dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r1, "sp", dwarf_r1, dwarf_r1, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r2, nullptr, dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r3, "arg1", dwarf_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r4, "arg2", dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG2 ,LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r5, "arg3", dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r6, "arg4", dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r7, "arg5", dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, "arg6", dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, "arg7", dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, "arg8", dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r16, nullptr, dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r17, nullptr, dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r18, nullptr, dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r19, nullptr, dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r20, nullptr, dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r21, nullptr, dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r22, nullptr, dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r23, nullptr, dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r24, nullptr, dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r25, nullptr, dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r26, nullptr, dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r27, nullptr, dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r28, nullptr, dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r29, nullptr, dwarf_r29, dwarf_r29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r30, nullptr, dwarf_r30, dwarf_r30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r31, nullptr, dwarf_r31, dwarf_r31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(lr, "lr", dwarf_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cr, "cr", dwarf_cr, dwarf_cr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(xer, "xer", dwarf_xer, dwarf_xer, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ctr, "ctr", dwarf_ctr, dwarf_ctr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(pc, "pc", dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ { nullptr, nullptr, 8, 0, eEncodingUint, eFormatHex, { dwarf_cfa, dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr }
};
static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
@@ -166,7 +170,6 @@ ABISysV_ppc64::GetRegisterInfoArray (uint32_t &count)
return g_register_infos;
}
-
size_t
ABISysV_ppc64::GetRedZoneSize () const
{
@@ -176,6 +179,7 @@ ABISysV_ppc64::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
ABISP
ABISysV_ppc64::CreateInstance (const ArchSpec &arch)
{
@@ -217,7 +221,7 @@ ABISysV_ppc64::PrepareTrivialCall (Thread &thread,
if (!reg_ctx)
return false;
- const RegisterInfo *reg_info = NULL;
+ const RegisterInfo *reg_info = nullptr;
if (args.size() > 8) // TODO handle more than 8 arguments
return false;
@@ -399,7 +403,7 @@ ABISysV_ppc64::GetArgumentValues (Thread &thread,
return false;
bool is_signed;
- if (compiler_type.IsIntegerType (is_signed))
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
compiler_type.GetBitSize(&thread),
@@ -450,7 +454,7 @@ ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObj
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
bool set_it_simple = false;
- if (compiler_type.IsIntegerType (is_signed) || compiler_type.IsPointerType())
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
{
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
@@ -474,7 +478,6 @@ ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObj
{
error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
}
-
}
else if (compiler_type.IsFloatingPointType (count, is_complex))
{
@@ -518,7 +521,6 @@ ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObj
return error;
}
-
ValueObjectSP
ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
CompilerType &return_compiler_type) const
@@ -626,7 +628,6 @@ ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
value,
ConstString(""));
-
}
else if (type_flags & eTypeIsPointer)
{
@@ -642,7 +643,6 @@ ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
if (byte_size > 0)
{
-
const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
if (altivec_reg)
{
@@ -739,7 +739,7 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
bool is_complex;
uint32_t count;
- CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
+ CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset, nullptr, nullptr);
const size_t field_bit_width = field_compiler_type.GetBitSize(&thread);
// If there are any unaligned fields, this is stored in memory.
@@ -752,11 +752,10 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
uint32_t field_byte_width = field_bit_width/8;
uint32_t field_byte_offset = field_bit_offset/8;
-
- DataExtractor *copy_from_extractor = NULL;
+ DataExtractor *copy_from_extractor = nullptr;
uint32_t copy_from_offset = 0;
- if (field_compiler_type.IsIntegerType (is_signed) || field_compiler_type.IsPointerType ())
+ if (field_compiler_type.IsIntegerOrEnumerationType (is_signed) || field_compiler_type.IsPointerType ())
{
if (integer_bytes < 8)
{
@@ -785,7 +784,7 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
else
{
// The last field didn't fit. I can't see how that would happen w/o the overall size being
- // greater than 16 bytes. For now, return a NULL return value object.
+ // greater than 16 bytes. For now, return a nullptr return value object.
return return_valobj_sp;
}
}
@@ -819,9 +818,9 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
CompilerType next_field_compiler_type = return_compiler_type.GetFieldAtIndex (idx + 1,
name,
&next_field_bit_offset,
- NULL,
- NULL);
- if (next_field_compiler_type.IsIntegerType (is_signed))
+ nullptr,
+ nullptr);
+ if (next_field_compiler_type.IsIntegerOrEnumerationType (is_signed))
in_gpr = true;
else
{
@@ -829,7 +828,6 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
in_gpr = false;
}
}
-
}
else if (field_byte_offset % 4 == 0)
{
@@ -843,9 +841,9 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
CompilerType prev_field_compiler_type = return_compiler_type.GetFieldAtIndex (idx - 1,
name,
&prev_field_bit_offset,
- NULL,
- NULL);
- if (prev_field_compiler_type.IsIntegerType (is_signed))
+ nullptr,
+ nullptr);
+ if (prev_field_compiler_type.IsIntegerOrEnumerationType (is_signed))
in_gpr = true;
else
{
@@ -853,7 +851,6 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
in_gpr = false;
}
}
-
}
else
{
@@ -910,7 +907,6 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
}
}
-
// FIXME: This is just taking a guess, r3 may very well no longer hold the return storage location.
// If we are going to do this right, when we make a new frame we should check to see if it uses a memory
// return, and if we are at the first instruction and if so stash away the return location. Then we would
@@ -920,10 +916,10 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_co
{
unsigned r3_id = reg_ctx_sp->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
- return_valobj_sp = ValueObjectMemory::Create (&thread,
- "",
- Address (storage_addr, NULL),
- return_compiler_type);
+ return_valobj_sp = ValueObjectMemory::Create(&thread,
+ "",
+ Address(storage_addr, nullptr),
+ return_compiler_type);
}
}
@@ -989,8 +985,6 @@ ABISysV_ppc64::RegisterIsVolatile (const RegisterInfo *reg_info)
return !RegisterIsCalleeSaved (reg_info);
}
-
-
// See "Register Usage" in the
// "System V Application Binary Interface"
// "64-bit PowerPC ELF Application Binary Interface Supplement"
@@ -1039,8 +1033,6 @@ ABISysV_ppc64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
return false;
}
-
-
void
ABISysV_ppc64::Initialize()
{
@@ -1065,6 +1057,7 @@ ABISysV_ppc64::GetPluginNameStatic()
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
lldb_private::ConstString
ABISysV_ppc64::GetPluginName()
{
@@ -1076,4 +1069,3 @@ ABISysV_ppc64::GetPluginVersion()
{
return 1;
}
-
diff --git a/source/Plugins/ABI/SysV-ppc64/Makefile b/source/Plugins/ABI/SysV-ppc64/Makefile
deleted file mode 100644
index 43fc41d42713..000000000000
--- a/source/Plugins/ABI/SysV-ppc64/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ABI/SysV-hexagon/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginABISysV_ppc64
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
new file mode 100644
index 000000000000..055905523f81
--- /dev/null
+++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
@@ -0,0 +1,807 @@
+//===-- ABISysV_s390x.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABISysV_s390x.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+// Project includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegisterValue.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"
+
+using namespace lldb;
+using namespace lldb_private;
+
+enum dwarf_regnums
+{
+ // General Purpose Registers
+ dwarf_r0_s390x = 0,
+ dwarf_r1_s390x,
+ dwarf_r2_s390x,
+ dwarf_r3_s390x,
+ dwarf_r4_s390x,
+ dwarf_r5_s390x,
+ dwarf_r6_s390x,
+ dwarf_r7_s390x,
+ dwarf_r8_s390x,
+ dwarf_r9_s390x,
+ dwarf_r10_s390x,
+ dwarf_r11_s390x,
+ dwarf_r12_s390x,
+ dwarf_r13_s390x,
+ dwarf_r14_s390x,
+ dwarf_r15_s390x,
+ // Floating Point Registers / Vector Registers 0-15
+ dwarf_f0_s390x = 16,
+ dwarf_f2_s390x,
+ dwarf_f4_s390x,
+ dwarf_f6_s390x,
+ dwarf_f1_s390x,
+ dwarf_f3_s390x,
+ dwarf_f5_s390x,
+ dwarf_f7_s390x,
+ dwarf_f8_s390x,
+ dwarf_f10_s390x,
+ dwarf_f12_s390x,
+ dwarf_f14_s390x,
+ dwarf_f9_s390x,
+ dwarf_f11_s390x,
+ dwarf_f13_s390x,
+ dwarf_f15_s390x,
+ // Access Registers
+ dwarf_acr0_s390x = 48,
+ dwarf_acr1_s390x,
+ dwarf_acr2_s390x,
+ dwarf_acr3_s390x,
+ dwarf_acr4_s390x,
+ dwarf_acr5_s390x,
+ dwarf_acr6_s390x,
+ dwarf_acr7_s390x,
+ dwarf_acr8_s390x,
+ dwarf_acr9_s390x,
+ dwarf_acr10_s390x,
+ dwarf_acr11_s390x,
+ dwarf_acr12_s390x,
+ dwarf_acr13_s390x,
+ dwarf_acr14_s390x,
+ dwarf_acr15_s390x,
+ // Program Status Word
+ dwarf_pswm_s390x = 64,
+ dwarf_pswa_s390x,
+ // Vector Registers 16-31
+ dwarf_v16_s390x = 68,
+ dwarf_v18_s390x,
+ dwarf_v20_s390x,
+ dwarf_v22_s390x,
+ dwarf_v17_s390x,
+ dwarf_v19_s390x,
+ dwarf_v21_s390x,
+ dwarf_v23_s390x,
+ dwarf_v24_s390x,
+ dwarf_v26_s390x,
+ dwarf_v28_s390x,
+ dwarf_v30_s390x,
+ dwarf_v25_s390x,
+ dwarf_v27_s390x,
+ dwarf_v29_s390x,
+ dwarf_v31_s390x,
+};
+
+// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
+
+#define DEFINE_REG(name, size, alt, generic) \
+ { \
+ #name, alt, size, 0, eEncodingUint, eFormatHex, \
+ { dwarf_##name##_s390x, dwarf_##name##_s390x, generic, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, \
+ NULL, NULL, \
+ }
+
+static RegisterInfo g_register_infos[] =
+{
+ DEFINE_REG(r0, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(r1, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(r2, 8, "arg1", LLDB_REGNUM_GENERIC_ARG1),
+ DEFINE_REG(r3, 8, "arg2", LLDB_REGNUM_GENERIC_ARG2),
+ DEFINE_REG(r4, 8, "arg3", LLDB_REGNUM_GENERIC_ARG3),
+ DEFINE_REG(r5, 8, "arg4", LLDB_REGNUM_GENERIC_ARG4),
+ DEFINE_REG(r6, 8, "arg5", LLDB_REGNUM_GENERIC_ARG5),
+ DEFINE_REG(r7, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(r8, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(r9, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(r10, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(r11, 8, "fp", LLDB_REGNUM_GENERIC_FP),
+ DEFINE_REG(r12, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(r13, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(r14, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(r15, 8, "sp", LLDB_REGNUM_GENERIC_SP),
+ DEFINE_REG(acr0, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr1, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr2, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr3, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr4, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr5, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr6, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr7, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr8, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr9, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr10, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr11, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr12, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr13, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr14, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(acr15, 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(pswm, 8, "flags", LLDB_REGNUM_GENERIC_FLAGS),
+ DEFINE_REG(pswa, 8, "pc", LLDB_REGNUM_GENERIC_PC),
+ DEFINE_REG(f0, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f1, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f2, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f3, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f4, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f5, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f6, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f7, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f8, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f9, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f10, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f11, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f12, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f13, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f14, 8, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_REG(f15, 8, nullptr, LLDB_INVALID_REGNUM),
+};
+
+static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+static bool g_register_info_names_constified = false;
+
+const lldb_private::RegisterInfo *
+ABISysV_s390x::GetRegisterInfoArray(uint32_t &count)
+{
+ // Make the C-string names and alt_names for the register infos into const
+ // C-string values by having the ConstString unique the names in the global
+ // constant C-string pool.
+ if (!g_register_info_names_constified)
+ {
+ g_register_info_names_constified = true;
+ for (uint32_t i = 0; i < k_num_register_infos; ++i)
+ {
+ if (g_register_infos[i].name)
+ g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
+ if (g_register_infos[i].alt_name)
+ g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
+ }
+ }
+ count = k_num_register_infos;
+ return g_register_infos;
+}
+
+size_t
+ABISysV_s390x::GetRedZoneSize() const
+{
+ return 0;
+}
+
+//------------------------------------------------------------------
+// Static Functions
+//------------------------------------------------------------------
+
+ABISP
+ABISysV_s390x::CreateInstance(const ArchSpec &arch)
+{
+ static ABISP g_abi_sp;
+ if (arch.GetTriple().getArch() == llvm::Triple::systemz)
+ {
+ if (!g_abi_sp)
+ g_abi_sp.reset(new ABISysV_s390x);
+ return g_abi_sp;
+ }
+ return ABISP();
+}
+
+bool
+ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ {
+ StreamString s;
+ s.Printf("ABISysV_s390x::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64
+ ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
+ thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, (uint64_t)return_addr);
+
+ for (size_t i = 0; i < args.size(); ++i)
+ s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1), args[i]);
+ s.PutCString(")");
+ log->PutCString(s.GetString().c_str());
+ }
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
+
+ const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfoByName("r14", 0);
+ ProcessSP process_sp(thread.GetProcess());
+
+ // Allocate a new stack frame and space for stack arguments if necessary
+
+ addr_t arg_pos = 0;
+ if (args.size() > 5)
+ {
+ sp -= 8 * (args.size() - 5);
+ arg_pos = sp;
+ }
+
+ sp -= 160;
+
+ // Process arguments
+
+ for (size_t i = 0; i < args.size(); ++i)
+ {
+ 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);
+ if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+ return false;
+ }
+ else
+ {
+ Error error;
+ if (log)
+ log->Printf("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;
+ }
+ }
+
+ // %r14 is set to the return address
+
+ if (log)
+ log->Printf("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);
+
+ 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);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
+ return false;
+
+ return true;
+}
+
+static bool
+ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, bool is_signed, Thread &thread,
+ uint32_t *argument_register_ids, unsigned int &current_argument_register,
+ addr_t &current_stack_argument)
+{
+ if (bit_width > 64)
+ return false; // Scalar can't hold large integer arguments
+
+ if (current_argument_register < 5)
+ {
+ scalar =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0);
+ current_argument_register++;
+ if (is_signed)
+ scalar.SignExtend(bit_width);
+ }
+ else
+ {
+ uint32_t byte_size = (bit_width + (8 - 1)) / 8;
+ Error error;
+ if (thread.GetProcess()->ReadScalarIntegerFromMemory(current_stack_argument + 8 - byte_size, byte_size,
+ is_signed, scalar, error))
+ {
+ current_stack_argument += 8;
+ return true;
+ }
+ return false;
+ }
+ return true;
+}
+
+bool
+ABISysV_s390x::GetArgumentValues(Thread &thread, ValueList &values) const
+{
+ unsigned int num_values = values.GetSize();
+ unsigned int value_index;
+
+ // Extract the register context so we can read arguments from registers
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+
+ if (!reg_ctx)
+ return false;
+
+ // Get the pointer to the first stack argument so we have a place to start
+ // when reading data
+
+ addr_t sp = reg_ctx->GetSP(0);
+
+ if (!sp)
+ return false;
+
+ addr_t current_stack_argument = sp + 160;
+
+ uint32_t argument_register_ids[5];
+
+ argument_register_ids[0] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)->kinds[eRegisterKindLLDB];
+ argument_register_ids[1] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)->kinds[eRegisterKindLLDB];
+ argument_register_ids[2] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)->kinds[eRegisterKindLLDB];
+ argument_register_ids[3] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)->kinds[eRegisterKindLLDB];
+ argument_register_ids[4] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)->kinds[eRegisterKindLLDB];
+
+ unsigned int current_argument_register = 0;
+
+ for (value_index = 0; value_index < num_values; ++value_index)
+ {
+ Value *value = values.GetValueAtIndex(value_index);
+
+ if (!value)
+ return false;
+
+ // We currently only support extracting values with Clang QualTypes.
+ // Do we care about others?
+ CompilerType compiler_type = value->GetCompilerType();
+ if (!compiler_type)
+ return false;
+ bool is_signed;
+
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed))
+ {
+ ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread), is_signed, thread,
+ argument_register_ids, current_argument_register, current_stack_argument);
+ }
+ else if (compiler_type.IsPointerType())
+ {
+ ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread), false, thread,
+ argument_register_ids, current_argument_register, current_stack_argument);
+ }
+ }
+
+ return true;
+}
+
+Error
+ABISysV_s390x::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
+{
+ Error error;
+ if (!new_value_sp)
+ {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
+
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type)
+ {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
+
+ Thread *thread = frame_sp->GetThread().get();
+
+ bool is_signed;
+ uint32_t count;
+ bool is_complex;
+
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+ bool set_it_simple = false;
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed) || compiler_type.IsPointerType())
+ {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
+
+ DataExtractor data;
+ Error data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail())
+ {
+ error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
+ return error;
+ }
+ lldb::offset_t offset = 0;
+ if (num_bytes <= 8)
+ {
+ uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
+ set_it_simple = true;
+ }
+ else
+ {
+ error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
+ }
+ }
+ else if (compiler_type.IsFloatingPointType(count, is_complex))
+ {
+ if (is_complex)
+ error.SetErrorString("We don't support returning complex values at present");
+ else
+ {
+ size_t bit_width = compiler_type.GetBitSize(frame_sp.get());
+ if (bit_width <= 64)
+ {
+ const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
+ RegisterValue f0_value;
+ DataExtractor data;
+ Error data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail())
+ {
+ error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
+
+ unsigned char buffer[8];
+ ByteOrder byte_order = data.GetByteOrder();
+
+ data.CopyByteOrderedData(0, num_bytes, buffer, 8, byte_order);
+ f0_value.SetBytes(buffer, 8, byte_order);
+ reg_ctx->WriteRegister(f0_info, f0_value);
+ set_it_simple = true;
+ }
+ else
+ {
+ // FIXME - don't know how to do long doubles yet.
+ error.SetErrorString("We don't support returning float values > 64 bits at present");
+ }
+ }
+ }
+
+ if (!set_it_simple)
+ {
+ // Okay we've got a structure or something that doesn't fit in a simple register.
+ // We should figure out where it really goes, but we don't support this yet.
+ error.SetErrorString("We only support setting simple integer and float return types at present.");
+ }
+
+ return error;
+}
+
+ValueObjectSP
+ABISysV_s390x::GetReturnValueObjectSimple(Thread &thread, CompilerType &return_compiler_type) const
+{
+ ValueObjectSP return_valobj_sp;
+ Value value;
+
+ if (!return_compiler_type)
+ return return_valobj_sp;
+
+ // value.SetContext (Value::eContextTypeClangType, return_value_type);
+ value.SetCompilerType(return_compiler_type);
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo();
+ if (type_flags & eTypeIsScalar)
+ {
+ value.SetValueType(Value::eValueTypeScalar);
+
+ bool success = false;
+ if (type_flags & eTypeIsInteger)
+ {
+ // Extract the register context so we can read arguments from registers
+
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ uint64_t raw_value =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r2", 0), 0);
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ switch (byte_size)
+ {
+ default:
+ break;
+
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
+ else
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
+
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
+ }
+ else if (type_flags & eTypeIsFloat)
+ {
+ if (type_flags & eTypeIsComplex)
+ {
+ // Don't handle complex yet.
+ }
+ else
+ {
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ if (byte_size <= sizeof(long double))
+ {
+ const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
+ RegisterValue f0_value;
+ if (reg_ctx->ReadRegister(f0_info, f0_value))
+ {
+ DataExtractor data;
+ if (f0_value.GetData(data))
+ {
+ lldb::offset_t offset = 0;
+ if (byte_size == sizeof(float))
+ {
+ value.GetScalar() = (float)data.GetFloat(&offset);
+ success = true;
+ }
+ else if (byte_size == sizeof(double))
+ {
+ value.GetScalar() = (double)data.GetDouble(&offset);
+ success = true;
+ }
+ else if (byte_size == sizeof(long double))
+ {
+ // Don't handle long double yet.
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (success)
+ return_valobj_sp =
+ ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ }
+ else if (type_flags & eTypeIsPointer)
+ {
+ unsigned r2_id = reg_ctx->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
+ value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
+ value.SetValueType(Value::eValueTypeScalar);
+ return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ }
+
+ return return_valobj_sp;
+}
+
+ValueObjectSP
+ABISysV_s390x::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_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
+ if (return_valobj_sp)
+ return return_valobj_sp;
+
+ RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+ if (!reg_ctx_sp)
+ return return_valobj_sp;
+
+ if (return_compiler_type.IsAggregateType())
+ {
+ // FIXME: This is just taking a guess, r2 may very well no longer hold the return storage location.
+ // If we are going to do this right, when we make a new frame we should check to see if it uses a memory
+ // return, and if we are at the first instruction and if so stash away the return location. Then we would
+ // only return the memory return value if we know it is valid.
+
+ unsigned r2_id = reg_ctx_sp->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
+ lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
+ return_valobj_sp = ValueObjectMemory::Create(&thread, "", Address(storage_addr, nullptr), return_compiler_type);
+ }
+
+ return return_valobj_sp;
+}
+
+bool
+ABISysV_s390x::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 + 160
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r15_s390x, 160);
+
+ // The previous PC is in r14
+ row->SetRegisterLocationToRegister(dwarf_pswa_s390x, dwarf_r14_s390x, true);
+
+ // All other registers are the same.
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("s390x at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ return true;
+}
+
+bool
+ABISysV_s390x::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan)
+{
+ // There's really no default way to unwind on s390x.
+ // Trust the .eh_frame CFI, which should always be good.
+ return false;
+}
+
+bool
+ABISysV_s390x::GetFallbackRegisterLocation (const RegisterInfo *reg_info,
+ UnwindPlan::Row::RegisterLocation &unwind_regloc)
+{
+ // If a volatile register is being requested, we don't want to forward the next frame's register contents
+ // up the stack -- the register is not retrievable at this frame.
+ if (RegisterIsVolatile(reg_info))
+ {
+ unwind_regloc.SetUndefined();
+ return true;
+ }
+
+ return false;
+}
+
+bool
+ABISysV_s390x::RegisterIsVolatile(const RegisterInfo *reg_info)
+{
+ return !RegisterIsCalleeSaved(reg_info);
+}
+
+bool
+ABISysV_s390x::RegisterIsCalleeSaved(const RegisterInfo *reg_info)
+{
+ if (reg_info)
+ {
+ // Preserved registers are :
+ // r6-r13, r15
+ // f8-f15
+
+ const char *name = reg_info->name;
+ if (name[0] == 'r')
+ {
+ switch (name[1])
+ {
+ case '6': // r6
+ case '7': // r7
+ case '8': // r8
+ case '9': // r9
+ return name[2] == '\0';
+
+ case '1': // r10, r11, r12, r13, r15
+ if ((name[2] >= '0' && name[2] <= '3') || name[2] == '5')
+ return name[3] == '\0';
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (name[0] == 'f')
+ {
+ switch (name[1])
+ {
+ case '8': // r8
+ case '9': // r9
+ return name[2] == '\0';
+
+ case '1': // r10, r11, r12, r13, r14, r15
+ if (name[2] >= '0' && name[2] <= '5')
+ return name[3] == '\0';
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Accept shorter-variant versions
+ if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
+ return true;
+ if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
+ return true;
+ if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
+ return true;
+ }
+ return false;
+}
+
+void
+ABISysV_s390x::Initialize()
+{
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "System V ABI for s390x targets", CreateInstance);
+}
+
+void
+ABISysV_s390x::Terminate()
+{
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString
+ABISysV_s390x::GetPluginNameStatic()
+{
+ static ConstString g_name("sysv-s390x");
+ return g_name;
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+
+lldb_private::ConstString
+ABISysV_s390x::GetPluginName()
+{
+ return GetPluginNameStatic();
+}
+
+uint32_t
+ABISysV_s390x::GetPluginVersion()
+{
+ return 1;
+}
diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
new file mode 100644
index 000000000000..3aba9c1917c6
--- /dev/null
+++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
@@ -0,0 +1,120 @@
+//===-- ABISysV_s390x.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ABISysV_s390x_h_
+#define liblldb_ABISysV_s390x_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Target/ABI.h"
+
+class ABISysV_s390x : public lldb_private::ABI
+{
+public:
+ ~ABISysV_s390x() 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;
+
+ bool
+ GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override;
+
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &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
+ GetFallbackRegisterLocation (const lldb_private::RegisterInfo *reg_info,
+ lldb_private::UnwindPlan::Row::RegisterLocation &unwind_regloc) override;
+
+ bool
+ CallFrameAddressIsValid(lldb::addr_t cfa) override
+ {
+ // Make sure the stack call frame addresses are 8 byte aligned
+ if (cfa & (8ull - 1ull))
+ return false; // Not 8 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool
+ CodeAddressIsValid(lldb::addr_t pc) override
+ {
+ // Code addressed must be 2 byte aligned
+ if (pc & 1ull)
+ return false;
+ return true;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb::ABISP
+ CreateInstance(const lldb_private::ArchSpec &arch);
+
+ static lldb_private::ConstString
+ GetPluginNameStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ lldb_private::ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
+
+protected:
+ void
+ CreateRegisterMapIfNeeded();
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const;
+
+ bool
+ RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
+
+private:
+ ABISysV_s390x() : lldb_private::ABI()
+ {
+ // Call CreateInstance instead.
+ }
+};
+
+#endif // liblldb_ABISysV_s390x_h_
diff --git a/source/Plugins/ABI/SysV-s390x/CMakeLists.txt b/source/Plugins/ABI/SysV-s390x/CMakeLists.txt
new file mode 100644
index 000000000000..c3992db023e6
--- /dev/null
+++ b/source/Plugins/ABI/SysV-s390x/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_lldb_library(lldbPluginABISysV_s390x
+ ABISysV_s390x.cpp
+ )
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 11e383d269c3..136f46a1d259 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -9,6 +9,13 @@
#include "ABISysV_x86_64.h"
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
@@ -27,9 +34,6 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -98,79 +102,79 @@ static RegisterInfo g_register_infos[] =
{
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
// ======== ======= == === ============= =================== ======================= ===================== =========================== ===================== ====================== ========== ===============
- { "rax" , NULL, 8, 0, eEncodingUint , eFormatHex , { dwarf_rax , dwarf_rax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "rbx" , NULL, 8, 0, eEncodingUint , eFormatHex , { dwarf_rbx , dwarf_rbx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "rcx" , "arg4", 8, 0, eEncodingUint , eFormatHex , { dwarf_rcx , dwarf_rcx , LLDB_REGNUM_GENERIC_ARG4 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "rdx" , "arg3", 8, 0, eEncodingUint , eFormatHex , { dwarf_rdx , dwarf_rdx , LLDB_REGNUM_GENERIC_ARG3 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "rsi" , "arg2", 8, 0, eEncodingUint , eFormatHex , { dwarf_rsi , dwarf_rsi , LLDB_REGNUM_GENERIC_ARG2 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "rdi" , "arg1", 8, 0, eEncodingUint , eFormatHex , { dwarf_rdi , dwarf_rdi , LLDB_REGNUM_GENERIC_ARG1 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "rbp" , "fp", 8, 0, eEncodingUint , eFormatHex , { dwarf_rbp , dwarf_rbp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "rsp" , "sp", 8, 0, eEncodingUint , eFormatHex , { dwarf_rsp , dwarf_rsp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r8" , "arg5", 8, 0, eEncodingUint , eFormatHex , { dwarf_r8 , dwarf_r8 , LLDB_REGNUM_GENERIC_ARG5 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r9" , "arg6", 8, 0, eEncodingUint , eFormatHex , { dwarf_r9 , dwarf_r9 , LLDB_REGNUM_GENERIC_ARG6 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r10" , NULL, 8, 0, eEncodingUint , eFormatHex , { dwarf_r10 , dwarf_r10 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r11" , NULL, 8, 0, eEncodingUint , eFormatHex , { dwarf_r11 , dwarf_r11 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r12" , NULL, 8, 0, eEncodingUint , eFormatHex , { dwarf_r12 , dwarf_r12 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r13" , NULL, 8, 0, eEncodingUint , eFormatHex , { dwarf_r13 , dwarf_r13 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r14" , NULL, 8, 0, eEncodingUint , eFormatHex , { dwarf_r14 , dwarf_r14 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "r15" , NULL, 8, 0, eEncodingUint , eFormatHex , { dwarf_r15 , dwarf_r15 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "rip" , "pc", 8, 0, eEncodingUint , eFormatHex , { dwarf_rip , dwarf_rip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "rflags", NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_REGNUM_GENERIC_FLAGS , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "cs" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ss" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ds" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "es" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fs" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "gs" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm0" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm0 , dwarf_stmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm1" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm1 , dwarf_stmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm2" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm2 , dwarf_stmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm3" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm3 , dwarf_stmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm4" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm4 , dwarf_stmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm5" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm5 , dwarf_stmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm6" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm6 , dwarf_stmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "stmm7" , NULL, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm7 , dwarf_stmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fctrl" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fstat" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ftag" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fiseg" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fioff" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "foseg" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fooff" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "fop" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm0" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm0 , dwarf_xmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm1" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm1 , dwarf_xmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm2" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm2 , dwarf_xmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm3" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm3 , dwarf_xmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm4" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm4 , dwarf_xmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm5" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm5 , dwarf_xmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm6" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm6 , dwarf_xmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm7" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm7 , dwarf_xmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm8" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm8 , dwarf_xmm8 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm9" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm9 , dwarf_xmm9 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm10" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm10 , dwarf_xmm10 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm11" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm11 , dwarf_xmm11 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm12" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm12 , dwarf_xmm12 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm13" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm13 , dwarf_xmm13 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm14" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm14 , dwarf_xmm14 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "xmm15" , NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm15 , dwarf_xmm15 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "mxcsr" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm0" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm0 , dwarf_ymm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm1" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm1 , dwarf_ymm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm2" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm2 , dwarf_ymm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm3" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm3 , dwarf_ymm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm4" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm4 , dwarf_ymm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm5" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm5 , dwarf_ymm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm6" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm6 , dwarf_ymm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm7" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm7 , dwarf_ymm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm8" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm8 , dwarf_ymm8 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm9" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm9 , dwarf_ymm9 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm10" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm10 , dwarf_ymm10 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm11" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm11 , dwarf_ymm11 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm12" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm12 , dwarf_ymm12 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm13" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm13 , dwarf_ymm13 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm14" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm14 , dwarf_ymm14 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL},
- { "ymm15" , NULL, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm15 , dwarf_ymm15 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL}
+ { "rax" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_rax , dwarf_rax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "rbx" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_rbx , dwarf_rbx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "rcx" , "arg4", 8, 0, eEncodingUint , eFormatHex , { dwarf_rcx , dwarf_rcx , LLDB_REGNUM_GENERIC_ARG4 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "rdx" , "arg3", 8, 0, eEncodingUint , eFormatHex , { dwarf_rdx , dwarf_rdx , LLDB_REGNUM_GENERIC_ARG3 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "rsi" , "arg2", 8, 0, eEncodingUint , eFormatHex , { dwarf_rsi , dwarf_rsi , LLDB_REGNUM_GENERIC_ARG2 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "rdi" , "arg1", 8, 0, eEncodingUint , eFormatHex , { dwarf_rdi , dwarf_rdi , LLDB_REGNUM_GENERIC_ARG1 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "rbp" , "fp", 8, 0, eEncodingUint , eFormatHex , { dwarf_rbp , dwarf_rbp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "rsp" , "sp", 8, 0, eEncodingUint , eFormatHex , { dwarf_rsp , dwarf_rsp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r8" , "arg5", 8, 0, eEncodingUint , eFormatHex , { dwarf_r8 , dwarf_r8 , LLDB_REGNUM_GENERIC_ARG5 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r9" , "arg6", 8, 0, eEncodingUint , eFormatHex , { dwarf_r9 , dwarf_r9 , LLDB_REGNUM_GENERIC_ARG6 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r10" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_r10 , dwarf_r10 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r11" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_r11 , dwarf_r11 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r12" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_r12 , dwarf_r12 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r13" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_r13 , dwarf_r13 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r14" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_r14 , dwarf_r14 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "r15" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_r15 , dwarf_r15 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "rip" , "pc", 8, 0, eEncodingUint , eFormatHex , { dwarf_rip , dwarf_rip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "rflags", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_REGNUM_GENERIC_FLAGS , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "cs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ss" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ds" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "es" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "gs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm0" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm0 , dwarf_stmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm1" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm1 , dwarf_stmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm2" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm2 , dwarf_stmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm3" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm3 , dwarf_stmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm4" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm4 , dwarf_stmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm5" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm5 , dwarf_stmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm6" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm6 , dwarf_stmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "stmm7" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm7 , dwarf_stmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fctrl" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fstat" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ftag" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fiseg" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fioff" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "foseg" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fooff" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "fop" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm0" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm0 , dwarf_xmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm1" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm1 , dwarf_xmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm2" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm2 , dwarf_xmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm3" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm3 , dwarf_xmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm4" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm4 , dwarf_xmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm5" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm5 , dwarf_xmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm6" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm6 , dwarf_xmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm7" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm7 , dwarf_xmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm8" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm8 , dwarf_xmm8 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm9" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm9 , dwarf_xmm9 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm10" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm10 , dwarf_xmm10 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm11" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm11 , dwarf_xmm11 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm12" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm12 , dwarf_xmm12 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm13" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm13 , dwarf_xmm13 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm14" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm14 , dwarf_xmm14 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "xmm15" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm15 , dwarf_xmm15 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "mxcsr" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm0" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm0 , dwarf_ymm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm1" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm1 , dwarf_ymm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm2" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm2 , dwarf_ymm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm3" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm3 , dwarf_ymm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm4" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm4 , dwarf_ymm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm5" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm5 , dwarf_ymm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm6" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm6 , dwarf_ymm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm7" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm7 , dwarf_ymm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm8" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm8 , dwarf_ymm8 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm9" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm9 , dwarf_ymm9 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm10" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm10 , dwarf_ymm10 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm11" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm11 , dwarf_ymm11 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm12" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm12 , dwarf_ymm12 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm13" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm13 , dwarf_ymm13 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm14" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm14 , dwarf_ymm14 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+ { "ymm15" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm15 , dwarf_ymm15 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr }
};
static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
@@ -197,7 +201,6 @@ ABISysV_x86_64::GetRegisterInfoArray (uint32_t &count)
return g_register_infos;
}
-
size_t
ABISysV_x86_64::GetRedZoneSize () const
{
@@ -207,6 +210,7 @@ ABISysV_x86_64::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
ABISP
ABISysV_x86_64::CreateInstance (const ArchSpec &arch)
{
@@ -248,7 +252,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thread &thread,
if (!reg_ctx)
return false;
- const RegisterInfo *reg_info = NULL;
+ const RegisterInfo *reg_info = nullptr;
if (args.size() > 6) // TODO handle more than 6 arguments
return false;
@@ -428,7 +432,7 @@ ABISysV_x86_64::GetArgumentValues (Thread &thread,
return false;
bool is_signed;
- if (compiler_type.IsIntegerType (is_signed))
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
compiler_type.GetBitSize(&thread),
@@ -479,7 +483,7 @@ ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
bool set_it_simple = false;
- if (compiler_type.IsIntegerType (is_signed) || compiler_type.IsPointerType())
+ if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
{
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
@@ -503,7 +507,6 @@ ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb
{
error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
}
-
}
else if (compiler_type.IsFloatingPointType (count, is_complex))
{
@@ -551,7 +554,6 @@ ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb
return error;
}
-
ValueObjectSP
ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
CompilerType &return_compiler_type) const
@@ -663,7 +665,6 @@ ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
value,
ConstString(""));
-
}
else if (type_flags & eTypeIsPointer)
{
@@ -823,7 +824,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
bool is_complex;
uint32_t count;
- CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
+ CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset, nullptr, nullptr);
const size_t field_bit_width = field_compiler_type.GetBitSize(&thread);
// if we don't know the size of the field (e.g. invalid type), just bail out
@@ -839,12 +840,11 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
uint32_t field_byte_width = field_bit_width/8;
uint32_t field_byte_offset = field_bit_offset/8;
-
- DataExtractor *copy_from_extractor = NULL;
+ DataExtractor *copy_from_extractor = nullptr;
uint32_t copy_from_offset = 0;
- if (field_compiler_type.IsIntegerType (is_signed) || field_compiler_type.IsPointerType ())
+ if (field_compiler_type.IsIntegerOrEnumerationType (is_signed) || field_compiler_type.IsPointerType ())
{
if (integer_bytes < 8)
{
@@ -861,7 +861,6 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
copy_from_extractor = &rdx_data;
copy_from_offset = 0;
integer_bytes = 8 + field_byte_width;
-
}
}
else if (integer_bytes + field_byte_width <= 16)
@@ -873,7 +872,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
else
{
// The last field didn't fit. I can't see how that would happen w/o the overall size being
- // greater than 16 bytes. For now, return a NULL return value object.
+ // greater than 16 bytes. For now, return a nullptr return value object.
return return_valobj_sp;
}
}
@@ -913,9 +912,9 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
CompilerType next_field_compiler_type = return_compiler_type.GetFieldAtIndex (idx + 1,
name,
&next_field_bit_offset,
- NULL,
- NULL);
- if (next_field_compiler_type.IsIntegerType (is_signed))
+ nullptr,
+ nullptr);
+ if (next_field_compiler_type.IsIntegerOrEnumerationType (is_signed))
in_gpr = true;
else
{
@@ -923,7 +922,6 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
in_gpr = false;
}
}
-
}
else if (field_byte_offset % 4 == 0)
{
@@ -937,9 +935,9 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
CompilerType prev_field_compiler_type = return_compiler_type.GetFieldAtIndex (idx - 1,
name,
&prev_field_bit_offset,
- NULL,
- NULL);
- if (prev_field_compiler_type.IsIntegerType (is_signed))
+ nullptr,
+ nullptr);
+ if (prev_field_compiler_type.IsIntegerOrEnumerationType (is_signed))
in_gpr = true;
else
{
@@ -947,7 +945,6 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
in_gpr = false;
}
}
-
}
else
{
@@ -1008,8 +1005,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
return_ext);
}
}
-
-
+
// FIXME: This is just taking a guess, rax may very well no longer hold the return storage location.
// If we are going to do this right, when we make a new frame we should check to see if it uses a memory
// return, and if we are at the first instruction and if so stash away the return location. Then we would
@@ -1019,10 +1015,10 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_c
{
unsigned rax_id = reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
- return_valobj_sp = ValueObjectMemory::Create (&thread,
- "",
- Address (storage_addr, NULL),
- return_compiler_type);
+ return_valobj_sp = ValueObjectMemory::Create(&thread,
+ "",
+ Address(storage_addr, nullptr),
+ return_compiler_type);
}
}
@@ -1090,8 +1086,6 @@ ABISysV_x86_64::RegisterIsVolatile (const RegisterInfo *reg_info)
return !RegisterIsCalleeSaved (reg_info);
}
-
-
// See "Register Usage" in the
// "System V Application Binary Interface"
// "AMD64 Architecture Processor Supplement"
@@ -1145,7 +1139,6 @@ ABISysV_x86_64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
if (name[2] == 'p')
return name[3] == '\0';
break;
-
}
}
if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
@@ -1158,8 +1151,6 @@ ABISysV_x86_64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
return false;
}
-
-
void
ABISysV_x86_64::Initialize()
{
@@ -1184,6 +1175,7 @@ ABISysV_x86_64::GetPluginNameStatic()
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
lldb_private::ConstString
ABISysV_x86_64::GetPluginName()
{
@@ -1195,4 +1187,3 @@ ABISysV_x86_64::GetPluginVersion()
{
return 1;
}
-
diff --git a/source/Plugins/ABI/SysV-x86_64/Makefile b/source/Plugins/ABI/SysV-x86_64/Makefile
deleted file mode 100644
index 32990a64f956..000000000000
--- a/source/Plugins/ABI/SysV-x86_64/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ABI/SysV-x86_64/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginABISysV_x86_64
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
index 6d124b689341..4d24cf1ab6de 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -11,20 +11,20 @@
// C++ Includes
// Project includes
#include "llvm-c/Disassembler.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCDisassembler.h"
-#include "llvm/MC/MCExternalSymbolizer.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+#include "llvm/MC/MCDisassembler/MCExternalSymbolizer.h"
+#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
-#include "llvm/ADT/SmallString.h"
// Other libraries and framework includes
#include "DisassemblerLLVMC.h"
@@ -53,7 +53,7 @@ public:
const lldb_private::Address &address,
AddressClass addr_class) :
Instruction (address, addr_class),
- m_disasm_sp (disasm.shared_from_this()),
+ m_disasm_wp (std::static_pointer_cast<DisassemblerLLVMC>(disasm.shared_from_this())),
m_does_branch (eLazyBoolCalculate),
m_has_delay_slot (eLazyBoolCalculate),
m_is_valid (false),
@@ -68,34 +68,38 @@ public:
{
if (m_does_branch == eLazyBoolCalculate)
{
- GetDisassemblerLLVMC().Lock(this, NULL);
- DataExtractor data;
- if (m_opcode.GetData(data))
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp)
{
- bool is_alternate_isa;
- lldb::addr_t pc = m_address.GetFileAddress();
-
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
- const uint8_t *opcode_data = data.GetDataStart();
- const size_t opcode_data_len = data.GetByteSize();
- llvm::MCInst inst;
- const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
- opcode_data_len,
- pc,
- inst);
- // Be conservative, if we didn't understand the instruction, say it might branch...
- if (inst_size == 0)
- m_does_branch = eLazyBoolYes;
- else
+ disasm_sp->Lock(this, NULL);
+ DataExtractor data;
+ if (m_opcode.GetData(data))
{
- const bool can_branch = mc_disasm_ptr->CanBranch(inst);
- if (can_branch)
+ bool is_alternate_isa;
+ lldb::addr_t pc = m_address.GetFileAddress();
+
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
+ const uint8_t *opcode_data = data.GetDataStart();
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
+ // Be conservative, if we didn't understand the instruction, say it might branch...
+ if (inst_size == 0)
m_does_branch = eLazyBoolYes;
else
- m_does_branch = eLazyBoolNo;
+ {
+ const bool can_branch = mc_disasm_ptr->CanBranch(inst);
+ if (can_branch)
+ m_does_branch = eLazyBoolYes;
+ else
+ m_does_branch = eLazyBoolNo;
+ }
}
+ disasm_sp->Unlock();
}
- GetDisassemblerLLVMC().Unlock();
}
return m_does_branch == eLazyBoolYes;
}
@@ -105,34 +109,38 @@ public:
{
if (m_has_delay_slot == eLazyBoolCalculate)
{
- GetDisassemblerLLVMC().Lock(this, NULL);
- DataExtractor data;
- if (m_opcode.GetData(data))
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp)
{
- bool is_alternate_isa;
- lldb::addr_t pc = m_address.GetFileAddress();
-
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
- const uint8_t *opcode_data = data.GetDataStart();
- const size_t opcode_data_len = data.GetByteSize();
- llvm::MCInst inst;
- const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
- opcode_data_len,
- pc,
- inst);
- // if we didn't understand the instruction, say it doesn't have a delay slot...
- if (inst_size == 0)
- m_has_delay_slot = eLazyBoolNo;
- else
+ disasm_sp->Lock(this, NULL);
+ DataExtractor data;
+ if (m_opcode.GetData(data))
{
- const bool has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst);
- if (has_delay_slot)
- m_has_delay_slot = eLazyBoolYes;
- else
+ bool is_alternate_isa;
+ lldb::addr_t pc = m_address.GetFileAddress();
+
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
+ const uint8_t *opcode_data = data.GetDataStart();
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
+ // if we didn't understand the instruction, say it doesn't have a delay slot...
+ if (inst_size == 0)
m_has_delay_slot = eLazyBoolNo;
+ else
+ {
+ const bool has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst);
+ if (has_delay_slot)
+ m_has_delay_slot = eLazyBoolYes;
+ else
+ m_has_delay_slot = eLazyBoolNo;
+ }
}
+ disasm_sp->Unlock();
}
- GetDisassemblerLLVMC().Unlock();
}
return m_has_delay_slot == eLazyBoolYes;
}
@@ -141,18 +149,22 @@ public:
GetDisasmToUse (bool &is_alternate_isa)
{
is_alternate_isa = false;
- DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
- if (llvm_disasm.m_alternate_disasm_ap.get() != NULL)
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp)
{
- const AddressClass address_class = GetAddressClass ();
-
- if (address_class == eAddressClassCodeAlternateISA)
+ if (disasm_sp->m_alternate_disasm_ap.get() != NULL)
{
- is_alternate_isa = true;
- return llvm_disasm.m_alternate_disasm_ap.get();
+ const AddressClass address_class = GetAddressClass ();
+
+ if (address_class == eAddressClassCodeAlternateISA)
+ {
+ is_alternate_isa = true;
+ return disasm_sp->m_alternate_disasm_ap.get();
+ }
}
+ return disasm_sp->m_disasm_ap.get();
}
- return llvm_disasm.m_disasm_ap.get();
+ return nullptr;
}
size_t
@@ -163,101 +175,105 @@ public:
// All we have to do is read the opcode which can be easy for some
// architectures
bool got_op = false;
- DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
- const ArchSpec &arch = llvm_disasm.GetArchitecture();
- const lldb::ByteOrder byte_order = data.GetByteOrder();
-
- const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
- const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
- if (min_op_byte_size == max_op_byte_size)
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp)
{
- // Fixed size instructions, just read that amount of data.
- if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
- return false;
+ const ArchSpec &arch = disasm_sp->GetArchitecture();
+ const lldb::ByteOrder byte_order = data.GetByteOrder();
- switch (min_op_byte_size)
+ const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
+ const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
+ if (min_op_byte_size == max_op_byte_size)
{
- case 1:
- m_opcode.SetOpcode8 (data.GetU8 (&data_offset), byte_order);
- got_op = true;
- break;
-
- case 2:
- m_opcode.SetOpcode16 (data.GetU16 (&data_offset), byte_order);
- got_op = true;
- break;
-
- case 4:
- m_opcode.SetOpcode32 (data.GetU32 (&data_offset), byte_order);
- got_op = true;
- break;
-
- case 8:
- m_opcode.SetOpcode64 (data.GetU64 (&data_offset), byte_order);
- got_op = true;
- break;
-
- default:
- m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), min_op_byte_size);
- got_op = true;
- break;
- }
- }
- if (!got_op)
- {
- bool is_alternate_isa = false;
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
+ // Fixed size instructions, just read that amount of data.
+ if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
+ return false;
+
+ switch (min_op_byte_size)
+ {
+ case 1:
+ m_opcode.SetOpcode8 (data.GetU8 (&data_offset), byte_order);
+ got_op = true;
+ break;
+
+ case 2:
+ m_opcode.SetOpcode16 (data.GetU16 (&data_offset), byte_order);
+ got_op = true;
+ break;
+
+ case 4:
+ m_opcode.SetOpcode32 (data.GetU32 (&data_offset), byte_order);
+ got_op = true;
+ break;
+
+ case 8:
+ m_opcode.SetOpcode64 (data.GetU64 (&data_offset), byte_order);
+ got_op = true;
+ break;
- const llvm::Triple::ArchType machine = arch.GetMachine();
- if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
+ default:
+ m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), min_op_byte_size);
+ got_op = true;
+ break;
+ }
+ }
+ if (!got_op)
{
- if (machine == llvm::Triple::thumb || is_alternate_isa)
+ bool is_alternate_isa = false;
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
+
+ const llvm::Triple::ArchType machine = arch.GetMachine();
+ if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
{
- uint32_t thumb_opcode = data.GetU16(&data_offset);
- if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
+ if (machine == llvm::Triple::thumb || is_alternate_isa)
{
- m_opcode.SetOpcode16 (thumb_opcode, byte_order);
- m_is_valid = true;
+ uint32_t thumb_opcode = data.GetU16(&data_offset);
+ if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
+ {
+ m_opcode.SetOpcode16 (thumb_opcode, byte_order);
+ m_is_valid = true;
+ }
+ else
+ {
+ thumb_opcode <<= 16;
+ thumb_opcode |= data.GetU16(&data_offset);
+ m_opcode.SetOpcode16_2 (thumb_opcode, byte_order);
+ m_is_valid = true;
+ }
}
else
{
- thumb_opcode <<= 16;
- thumb_opcode |= data.GetU16(&data_offset);
- m_opcode.SetOpcode16_2 (thumb_opcode, byte_order);
+ m_opcode.SetOpcode32 (data.GetU32(&data_offset), byte_order);
m_is_valid = true;
}
}
else
{
- m_opcode.SetOpcode32 (data.GetU32(&data_offset), byte_order);
- m_is_valid = true;
- }
- }
- else
- {
- // The opcode isn't evenly sized, so we need to actually use the llvm
- // disassembler to parse it and get the size.
- uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
- const size_t opcode_data_len = data.BytesLeft(data_offset);
- const addr_t pc = m_address.GetFileAddress();
- llvm::MCInst inst;
-
- llvm_disasm.Lock(this, NULL);
- const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
- opcode_data_len,
- pc,
- inst);
- llvm_disasm.Unlock();
- if (inst_size == 0)
- m_opcode.Clear();
- else
- {
- m_opcode.SetOpcodeBytes(opcode_data, inst_size);
- m_is_valid = true;
+ // The opcode isn't evenly sized, so we need to actually use the llvm
+ // disassembler to parse it and get the size.
+ uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
+ const size_t opcode_data_len = data.BytesLeft(data_offset);
+ const addr_t pc = m_address.GetFileAddress();
+ llvm::MCInst inst;
+
+ disasm_sp->Lock(this, NULL);
+ const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
+ disasm_sp->Unlock();
+ if (inst_size == 0)
+ m_opcode.Clear();
+ else
+ {
+ m_opcode.SetOpcodeBytes(opcode_data, inst_size);
+ m_is_valid = true;
+ }
}
}
+ return m_opcode.GetByteSize();
}
- return m_opcode.GetByteSize();
+ return 0;
}
void
@@ -283,146 +299,148 @@ public:
std::string out_string;
std::string comment_string;
- DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
-
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp)
+ {
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
- if (address_class == eAddressClassCodeAlternateISA)
- mc_disasm_ptr = llvm_disasm.m_alternate_disasm_ap.get();
- else
- mc_disasm_ptr = llvm_disasm.m_disasm_ap.get();
+ if (address_class == eAddressClassCodeAlternateISA)
+ mc_disasm_ptr = disasm_sp->m_alternate_disasm_ap.get();
+ else
+ mc_disasm_ptr = disasm_sp->m_disasm_ap.get();
- lldb::addr_t pc = m_address.GetFileAddress();
- m_using_file_addr = true;
+ lldb::addr_t pc = m_address.GetFileAddress();
+ m_using_file_addr = true;
- const bool data_from_file = GetDisassemblerLLVMC().m_data_from_file;
- bool use_hex_immediates = true;
- Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC;
+ const bool data_from_file = disasm_sp->m_data_from_file;
+ bool use_hex_immediates = true;
+ Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC;
- if (exe_ctx)
- {
- Target *target = exe_ctx->GetTargetPtr();
- if (target)
+ if (exe_ctx)
{
- use_hex_immediates = target->GetUseHexImmediates();
- hex_style = target->GetHexImmediateStyle();
-
- if (!data_from_file)
+ Target *target = exe_ctx->GetTargetPtr();
+ if (target)
{
- const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
- if (load_addr != LLDB_INVALID_ADDRESS)
+ use_hex_immediates = target->GetUseHexImmediates();
+ hex_style = target->GetHexImmediateStyle();
+
+ if (!data_from_file)
{
- pc = load_addr;
- m_using_file_addr = false;
+ const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
+ if (load_addr != LLDB_INVALID_ADDRESS)
+ {
+ pc = load_addr;
+ m_using_file_addr = false;
+ }
}
}
}
- }
- llvm_disasm.Lock(this, exe_ctx);
+ disasm_sp->Lock(this, exe_ctx);
- const uint8_t *opcode_data = data.GetDataStart();
- const size_t opcode_data_len = data.GetByteSize();
- llvm::MCInst inst;
- size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
- opcode_data_len,
- pc,
- inst);
+ const uint8_t *opcode_data = data.GetDataStart();
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
- if (inst_size > 0)
- {
- mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style);
- mc_disasm_ptr->PrintMCInst(inst, out_string, comment_string);
-
- if (!comment_string.empty())
+ if (inst_size > 0)
{
- AppendComment(comment_string);
+ mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style);
+ mc_disasm_ptr->PrintMCInst(inst, out_string, comment_string);
+
+ if (!comment_string.empty())
+ {
+ AppendComment(comment_string);
+ }
}
- }
- llvm_disasm.Unlock();
+ disasm_sp->Unlock();
- if (inst_size == 0)
- {
- m_comment.assign ("unknown opcode");
- inst_size = m_opcode.GetByteSize();
- StreamString mnemonic_strm;
- lldb::offset_t offset = 0;
- lldb::ByteOrder byte_order = data.GetByteOrder();
- switch (inst_size)
+ if (inst_size == 0)
{
- case 1:
- {
- const uint8_t uval8 = data.GetU8 (&offset);
- m_opcode.SetOpcode8 (uval8, byte_order);
- m_opcode_name.assign (".byte");
- mnemonic_strm.Printf("0x%2.2x", uval8);
- }
- break;
- case 2:
- {
- const uint16_t uval16 = data.GetU16(&offset);
- m_opcode.SetOpcode16(uval16, byte_order);
- m_opcode_name.assign (".short");
- mnemonic_strm.Printf("0x%4.4x", uval16);
- }
- break;
- case 4:
- {
- const uint32_t uval32 = data.GetU32(&offset);
- m_opcode.SetOpcode32(uval32, byte_order);
- m_opcode_name.assign (".long");
- mnemonic_strm.Printf("0x%8.8x", uval32);
- }
- break;
- case 8:
- {
- const uint64_t uval64 = data.GetU64(&offset);
- m_opcode.SetOpcode64(uval64, byte_order);
- m_opcode_name.assign (".quad");
- mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
- }
- break;
- default:
- if (inst_size == 0)
- return;
- else
- {
- const uint8_t *bytes = data.PeekData(offset, inst_size);
- if (bytes == NULL)
+ m_comment.assign ("unknown opcode");
+ inst_size = m_opcode.GetByteSize();
+ StreamString mnemonic_strm;
+ lldb::offset_t offset = 0;
+ lldb::ByteOrder byte_order = data.GetByteOrder();
+ switch (inst_size)
+ {
+ case 1:
+ {
+ const uint8_t uval8 = data.GetU8 (&offset);
+ m_opcode.SetOpcode8 (uval8, byte_order);
+ m_opcode_name.assign (".byte");
+ mnemonic_strm.Printf("0x%2.2x", uval8);
+ }
+ break;
+ case 2:
+ {
+ const uint16_t uval16 = data.GetU16(&offset);
+ m_opcode.SetOpcode16(uval16, byte_order);
+ m_opcode_name.assign (".short");
+ mnemonic_strm.Printf("0x%4.4x", uval16);
+ }
+ break;
+ case 4:
+ {
+ const uint32_t uval32 = data.GetU32(&offset);
+ m_opcode.SetOpcode32(uval32, byte_order);
+ m_opcode_name.assign (".long");
+ mnemonic_strm.Printf("0x%8.8x", uval32);
+ }
+ break;
+ case 8:
+ {
+ const uint64_t uval64 = data.GetU64(&offset);
+ m_opcode.SetOpcode64(uval64, byte_order);
+ m_opcode_name.assign (".quad");
+ mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
+ }
+ break;
+ default:
+ if (inst_size == 0)
return;
- m_opcode_name.assign (".byte");
- m_opcode.SetOpcodeBytes(bytes, inst_size);
- mnemonic_strm.Printf("0x%2.2x", bytes[0]);
- for (uint32_t i=1; i<inst_size; ++i)
- mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
- }
- break;
+ else
+ {
+ const uint8_t *bytes = data.PeekData(offset, inst_size);
+ if (bytes == NULL)
+ return;
+ m_opcode_name.assign (".byte");
+ m_opcode.SetOpcodeBytes(bytes, inst_size);
+ mnemonic_strm.Printf("0x%2.2x", bytes[0]);
+ for (uint32_t i=1; i<inst_size; ++i)
+ mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
+ }
+ break;
+ }
+ m_mnemonics.swap(mnemonic_strm.GetString());
+ return;
}
- m_mnemonics.swap(mnemonic_strm.GetString());
- return;
- }
- else
- {
- if (m_does_branch == eLazyBoolCalculate)
+ else
{
- const bool can_branch = mc_disasm_ptr->CanBranch(inst);
- if (can_branch)
- m_does_branch = eLazyBoolYes;
- else
- m_does_branch = eLazyBoolNo;
+ if (m_does_branch == eLazyBoolCalculate)
+ {
+ const bool can_branch = mc_disasm_ptr->CanBranch(inst);
+ if (can_branch)
+ m_does_branch = eLazyBoolYes;
+ else
+ m_does_branch = eLazyBoolNo;
+ }
}
- }
- static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?");
+ static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?");
- RegularExpression::Match matches(3);
+ RegularExpression::Match matches(3);
- if (s_regex.Execute(out_string.c_str(), &matches))
- {
- matches.GetMatchAtIndex(out_string.c_str(), 1, m_opcode_name);
- matches.GetMatchAtIndex(out_string.c_str(), 2, m_mnemonics);
+ if (s_regex.Execute(out_string.c_str(), &matches))
+ {
+ matches.GetMatchAtIndex(out_string.c_str(), 1, m_opcode_name);
+ matches.GetMatchAtIndex(out_string.c_str(), 2, m_mnemonics);
+ }
}
}
}
@@ -444,14 +462,14 @@ public:
return m_opcode.GetByteSize();
}
- DisassemblerLLVMC &
- GetDisassemblerLLVMC ()
+ std::shared_ptr<DisassemblerLLVMC>
+ GetDisassembler ()
{
- return *(DisassemblerLLVMC *)m_disasm_sp.get();
+ return m_disasm_wp.lock();
}
protected:
- DisassemblerSP m_disasm_sp; // for ownership
+ std::weak_ptr<DisassemblerLLVMC> m_disasm_wp;
LazyBool m_does_branch;
LazyBool m_has_delay_slot;
bool m_is_valid;
@@ -633,7 +651,7 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s
}
else
{
- thumb_arch_name = "thumbv7";
+ thumb_arch_name = "thumbv8.2a";
}
thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name.c_str()));
}
@@ -643,22 +661,12 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s
// in case the code uses instructions which are not available in the oldest arm version
// (used when no sub architecture is specified)
if (triple.getArch() == llvm::Triple::arm && triple.getSubArch() == llvm::Triple::NoSubArch)
- triple.setArchName("armv8.1a");
+ triple.setArchName("armv8.2a");
const char *triple_str = triple.getTriple().c_str();
- // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization
- //
- // Cortex-M3 devices (e.g. armv7m) can only execute thumb (T2) instructions,
- // so hardcode the primary disassembler to thumb mode. Same for Cortex-M4 (armv7em).
- //
- // Handle the Cortex-M0 (armv6m) the same; the ISA is a subset of the T and T32
- // instructions defined in ARMv7-A.
-
- if ((triple.getArch() == llvm::Triple::arm || triple.getArch() == llvm::Triple::thumb)
- && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m
- || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em
- || arch.GetCore() == ArchSpec::Core::eCore_arm_armv6m))
+ // ARM Cortex M0-M7 devices only execute thumb instructions
+ if (arch.IsAlwaysThumbInstructions ())
{
triple_str = thumb_arch.GetTriple().getTriple().c_str();
}
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
index 6359146d81d8..e8f09a4d3abb 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <memory>
+#include <mutex>
#include <string>
// Other libraries and framework includes
@@ -22,7 +23,6 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/Mutex.h"
// Opaque references to C++ Objects in LLVM's MC.
namespace llvm
@@ -147,7 +147,7 @@ protected:
void Lock(InstructionLLVMC *inst,
const lldb_private::ExecutionContext *exe_ctx)
{
- m_mutex.Lock();
+ m_mutex.lock();
m_inst = inst;
m_exe_ctx = exe_ctx;
}
@@ -156,12 +156,12 @@ protected:
{
m_inst = NULL;
m_exe_ctx = NULL;
- m_mutex.Unlock();
+ m_mutex.unlock();
}
const lldb_private::ExecutionContext *m_exe_ctx;
InstructionLLVMC *m_inst;
- lldb_private::Mutex m_mutex;
+ std::mutex m_mutex;
bool m_data_from_file;
std::unique_ptr<LLVMCDisassembler> m_disasm_ap;
diff --git a/source/Plugins/Disassembler/llvm/Makefile b/source/Plugins/Disassembler/llvm/Makefile
deleted file mode 100644
index a1309cdd081f..000000000000
--- a/source/Plugins/Disassembler/llvm/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Disassembler/llvm/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginDisassemblerLLVM
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 218b0b7a1eee..4021b44c96a9 100644
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -181,8 +181,8 @@ DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
// At this point if there is an ExecutableModule, it is a kernel and the Target is some variant of an Apple system.
// If the Process hasn't provided the kernel load address, we need to look around in memory to find it.
- addr_t kernel_load_address = SearchForDarwinKernel (process);
- if (kernel_load_address != LLDB_INVALID_ADDRESS)
+ const addr_t kernel_load_address = SearchForDarwinKernel (process);
+ if (CheckForKernelImageAtAddress (kernel_load_address, process).IsValid())
{
process->SetCanRunCode(false);
return new DynamicLoaderDarwinKernel (process, kernel_load_address);
@@ -254,27 +254,29 @@ DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints (Process *process)
Error read_err;
addr_t addr = LLDB_INVALID_ADDRESS;
- if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+ addr_t kernel_addresses_64[] = { 0xffffff8000002010ULL, 0xffffff8000004010ULL,
+ 0xfffffff000002010ULL, 0xfffffff000004010ULL,
+ LLDB_INVALID_ADDRESS };
+ addr_t kernel_addresses_32[] = { 0xffff0110,
+ LLDB_INVALID_ADDRESS };
+ for (size_t i = 0; kernel_addresses_64[i] != LLDB_INVALID_ADDRESS; i++)
{
- addr = process->ReadUnsignedIntegerFromMemory (0xffffff8000002010ULL, 8, LLDB_INVALID_ADDRESS, read_err);
- if (CheckForKernelImageAtAddress (addr, process).IsValid())
- {
- return addr;
- }
- addr = process->ReadUnsignedIntegerFromMemory (0xffffff8000004010ULL, 8, LLDB_INVALID_ADDRESS, read_err);
+ addr = process->ReadUnsignedIntegerFromMemory (kernel_addresses_64[i], 8, LLDB_INVALID_ADDRESS, read_err);
if (CheckForKernelImageAtAddress (addr, process).IsValid())
{
return addr;
}
}
- else
+
+ for (size_t i = 0; kernel_addresses_32[i] != LLDB_INVALID_ADDRESS; i++)
{
- addr = process->ReadUnsignedIntegerFromMemory (0xffff0110, 4, LLDB_INVALID_ADDRESS, read_err);
+ addr = process->ReadUnsignedIntegerFromMemory (kernel_addresses_32[i], 4, LLDB_INVALID_ADDRESS, read_err);
if (CheckForKernelImageAtAddress (addr, process).IsValid())
{
return addr;
}
}
+
return LLDB_INVALID_ADDRESS;
}
@@ -301,28 +303,14 @@ DynamicLoaderDarwinKernel::SearchForKernelNearPC (Process *process)
if (pc == LLDB_INVALID_ADDRESS)
return LLDB_INVALID_ADDRESS;
- addr_t kernel_range_low;
- if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
- {
- kernel_range_low = 1ULL << 63;
- }
- else
- {
- kernel_range_low = 1ULL << 31;
- }
-
- // Outside the normal kernel address range, this is probably userland code running right now
- if (pc < kernel_range_low)
- return LLDB_INVALID_ADDRESS;
-
// The kernel will load at at one megabyte boundary (0x100000), or at that boundary plus
- // an offset of one page (0x1000) or two, depending on the device.
+ // an offset of one page (0x1000) or two, or four (0x4000), depending on the device.
// Round the current pc down to the nearest one megabyte boundary - the place where we will start searching.
addr_t addr = pc & ~0xfffff;
- int i = 0;
- while (i < 32 && pc >= kernel_range_low)
+ // Search backwards 32 megabytes, looking for the start of the kernel at each one-megabyte boundary.
+ for (int i = 0; i < 32; i++, addr -= 0x100000)
{
if (CheckForKernelImageAtAddress (addr, process).IsValid())
return addr;
@@ -332,8 +320,6 @@ DynamicLoaderDarwinKernel::SearchForKernelNearPC (Process *process)
return addr + 0x2000;
if (CheckForKernelImageAtAddress (addr + 0x4000, process).IsValid())
return addr + 0x4000;
- i++;
- addr -= 0x100000;
}
return LLDB_INVALID_ADDRESS;
@@ -397,9 +383,13 @@ DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch (Process *process)
lldb_private::UUID
DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress (lldb::addr_t addr, Process *process)
{
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
if (addr == LLDB_INVALID_ADDRESS)
return UUID();
+ if (log)
+ log->Printf ("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: looking for kernel binary at 0x%" PRIx64, addr);
+
// First try a quick test -- read the first 4 bytes and see if there is a valid Mach-O magic field there
// (the first field of the mach_header/mach_header_64 struct).
@@ -415,19 +405,19 @@ DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress (lldb::addr_t addr, Proc
// Read the mach header and see whether it looks like a kernel
llvm::MachO::mach_header header;
- if (process->DoReadMemory (addr, &header, sizeof(header), read_error) != sizeof(header))
+ if (process->DoReadMemory (addr, &header, sizeof (header), read_error) != sizeof (header))
return UUID();
if (header.magic == llvm::MachO::MH_CIGAM ||
header.magic == llvm::MachO::MH_CIGAM_64)
{
- header.magic = llvm::ByteSwap_32(header.magic);
- header.cputype = llvm::ByteSwap_32(header.cputype);
- header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
- header.filetype = llvm::ByteSwap_32(header.filetype);
- header.ncmds = llvm::ByteSwap_32(header.ncmds);
- header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
- header.flags = llvm::ByteSwap_32(header.flags);
+ header.magic = llvm::ByteSwap_32 (header.magic);
+ header.cputype = llvm::ByteSwap_32 (header.cputype);
+ header.cpusubtype = llvm::ByteSwap_32 (header.cpusubtype);
+ header.filetype = llvm::ByteSwap_32 (header.filetype);
+ header.ncmds = llvm::ByteSwap_32 (header.ncmds);
+ header.sizeofcmds = llvm::ByteSwap_32 (header.sizeofcmds);
+ header.flags = llvm::ByteSwap_32 (header.flags);
}
// A kernel is an executable which does not have the dynamic link object flag set.
@@ -450,6 +440,8 @@ DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress (lldb::addr_t addr, Proc
{
process->GetTarget().SetArchitecture (kernel_arch);
}
+ if (log)
+ log->Printf ("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: kernel binary image found at 0x%" PRIx64, addr);
return memory_module_sp->GetUUID();
}
}
@@ -460,16 +452,16 @@ DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress (lldb::addr_t addr, Proc
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process, lldb::addr_t kernel_addr) :
- DynamicLoader(process),
- m_kernel_load_address (kernel_addr),
- m_kernel(),
- m_kext_summary_header_ptr_addr (),
- m_kext_summary_header_addr (),
- m_kext_summary_header (),
- m_known_kexts (),
- m_mutex(Mutex::eMutexTypeRecursive),
- m_break_id (LLDB_INVALID_BREAK_ID)
+DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process, lldb::addr_t kernel_addr)
+ : DynamicLoader(process),
+ m_kernel_load_address(kernel_addr),
+ m_kernel(),
+ m_kext_summary_header_ptr_addr(),
+ m_kext_summary_header_addr(),
+ m_kext_summary_header(),
+ m_known_kexts(),
+ m_mutex(),
+ m_break_id(LLDB_INVALID_BREAK_ID)
{
Error error;
PlatformSP platform_sp(Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
@@ -478,7 +470,7 @@ DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process, lldb::ad
// shouldn't be done if kext loading is explicitly disabled.
if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts())
{
- process->GetTarget().SetPlatform (platform_sp);
+ process->GetTarget().SetPlatform(platform_sp);
}
}
@@ -529,7 +521,7 @@ DynamicLoaderDarwinKernel::DidLaunch ()
void
DynamicLoaderDarwinKernel::Clear (bool clear_process)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
m_process->ClearBreakpointSiteByID(m_break_id);
@@ -1139,7 +1131,7 @@ DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context,
bool
DynamicLoaderDarwinKernel::ReadKextSummaryHeader ()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// the all image infos is already valid for this process stop ID
@@ -1224,8 +1216,8 @@ DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr,
Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
if (log)
log->Printf ("Kexts-changed breakpoint hit, there are %d kexts currently.\n", count);
-
- Mutex::Locker locker(m_mutex);
+
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
return false;
@@ -1446,8 +1438,8 @@ DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
bool
DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
{
- Mutex::Locker locker(m_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
if (ReadKextSummaryHeader ())
{
if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid())
@@ -1516,7 +1508,7 @@ DynamicLoaderDarwinKernel::PutToLog(Log *log) const
if (log == NULL)
return;
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64 " { version=%u, entry_size=%u, entry_count=%u }",
m_kext_summary_header_addr.GetFileAddress(),
m_kext_summary_header.version,
@@ -1559,6 +1551,7 @@ DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
"OSKextLoadedKextSummariesUpdated",
eFunctionNameTypeFull,
eLanguageTypeUnknown,
+ 0,
skip_prologue,
internal_bp,
hardware).get();
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
index 7ebda48cec93..47fba086a4a9 100644
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
+++ b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
@@ -12,8 +12,9 @@
// C Includes
// C++ Includes
-#include <vector>
+#include <mutex>
#include <string>
+#include <vector>
// Other libraries and framework includes
// Project includes
@@ -21,7 +22,6 @@
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Core/UUID.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/Process.h"
class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader
@@ -52,6 +52,9 @@ public:
static void
DebuggerInitialize (lldb_private::Debugger &debugger);
+ static lldb::addr_t
+ SearchForDarwinKernel (lldb_private::Process *process);
+
//------------------------------------------------------------------
/// Called after attaching a process.
///
@@ -337,9 +340,6 @@ protected:
KextImageInfo::collection &image_infos);
static lldb::addr_t
- SearchForDarwinKernel (lldb_private::Process *process);
-
- static lldb::addr_t
SearchForKernelAtSameLoadAddr (lldb_private::Process *process);
static lldb::addr_t
@@ -361,7 +361,7 @@ protected:
lldb_private::Address m_kext_summary_header_addr;
OSKextLoadedKextSummaryHeader m_kext_summary_header;
KextImageInfo::collection m_known_kexts;
- mutable lldb_private::Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
lldb::user_id_t m_break_id;
private:
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/Makefile b/source/Plugins/DynamicLoader/Darwin-Kernel/Makefile
deleted file mode 100644
index d2342fd06772..000000000000
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Disassembler/llvm/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginDynamicLoaderDarwinKernel
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
index 28493170ac36..1f77539ca8df 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
@@ -574,34 +574,6 @@ DynamicLoaderHexagonDYLD::LoadAllCurrentModules()
m_process->GetTarget().ModulesDidLoad(module_list);
}
-/// Helper for the entry breakpoint callback. Resolves the load addresses
-/// of all dependent modules.
-ModuleSP
-DynamicLoaderHexagonDYLD::LoadModuleAtAddress(const FileSpec &file,
- addr_t link_map_addr,
- addr_t base_addr,
- bool base_addr_is_offset)
-{
- Target &target = m_process->GetTarget();
- ModuleList &modules = target.GetImages();
- ModuleSP module_sp;
-
- ModuleSpec module_spec (file, target.GetArchitecture());
-
- // check if module is currently loaded
- if ((module_sp = modules.FindFirstModule (module_spec)))
- {
- UpdateLoadedSections(module_sp, link_map_addr, base_addr, true);
- }
- // try to load this module from disk
- else if ((module_sp = target.GetSharedModule(module_spec)))
- {
- UpdateLoadedSections(module_sp, link_map_addr, base_addr, true);
- }
-
- return module_sp;
-}
-
/// Computes a value for m_load_offset returning the computed address on
/// success and LLDB_INVALID_ADDRESS on failure.
addr_t
@@ -674,7 +646,8 @@ static int ReadInt(Process *process, addr_t addr)
}
lldb::addr_t
-DynamicLoaderHexagonDYLD::GetThreadLocalData (const lldb::ModuleSP module, const lldb::ThreadSP thread)
+DynamicLoaderHexagonDYLD::GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr)
{
auto it = m_loaded_modules.find (module);
if (it == m_loaded_modules.end())
@@ -715,5 +688,8 @@ DynamicLoaderHexagonDYLD::GetThreadLocalData (const lldb::ModuleSP module, const
"module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 ", modid=%i, tls_block=0x%" PRIx64,
mod->GetObjectName().AsCString(""), link_map, tp, modid, tls_block);
- return tls_block;
+ if (tls_block == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+ else
+ return tls_block + tls_file_addr;
}
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
index e10d4ee64209..67c32887d091 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
@@ -59,7 +59,7 @@ public:
CanLoadImage() override;
lldb::addr_t
- GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread) override;
+ GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override;
//------------------------------------------------------------------
// PluginInterface protocol
@@ -123,14 +123,6 @@ protected:
void
UnloadSections(const lldb::ModuleSP module) override;
- /// Locates or creates a module given by @p file and updates/loads the
- /// resulting module at the virtual base address @p base_addr.
- lldb::ModuleSP
- LoadModuleAtAddress(const lldb_private::FileSpec &file,
- lldb::addr_t link_map_addr,
- lldb::addr_t base_addr,
- bool base_addr_is_offset) override;
-
/// Callback routine invoked when we hit the breakpoint on process entry.
///
/// This routine is responsible for resolving the load addresses of all
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/Makefile b/source/Plugins/DynamicLoader/Hexagon-DYLD/Makefile
deleted file mode 100644
index 43334562ebb1..000000000000
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/DynamicLoader/Hexagon-DYLD/Makefile ----*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginDynamicLoaderHexagon
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt b/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
index 2c44877662f5..4d916b15f761 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
@@ -1,3 +1,4 @@
add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD
DynamicLoaderMacOSXDYLD.cpp
+ DynamicLoaderDarwin.cpp
)
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
new file mode 100644
index 000000000000..efca1bea4ad6
--- /dev/null
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -0,0 +1,1143 @@
+//===-- DynamicLoaderDarwin.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/State.h"
+#include "lldb/Expression/DiagnosticManager.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/ABI.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanCallFunction.h"
+#include "lldb/Target/ThreadPlanRunToAddress.h"
+
+#include "DynamicLoaderDarwin.h"
+
+//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
+#ifdef ENABLE_DEBUG_PRINTF
+#include <stdio.h>
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#else
+#define DEBUG_PRINTF(fmt, ...)
+#endif
+
+#ifndef __APPLE__
+#include "Utility/UuidCompatibility.h"
+#else
+#include <uuid/uuid.h>
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+//----------------------------------------------------------------------
+// Constructor
+//----------------------------------------------------------------------
+DynamicLoaderDarwin::DynamicLoaderDarwin (Process* process)
+ : DynamicLoader(process),
+ m_dyld_module_wp(),
+ m_libpthread_module_wp(),
+ m_pthread_getspecific_addr(),
+ m_tid_to_tls_map(),
+ m_dyld_image_infos(),
+ m_dyld_image_infos_stop_id(UINT32_MAX),
+ m_dyld(),
+ m_mutex()
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+DynamicLoaderDarwin::~DynamicLoaderDarwin()
+{
+}
+
+//------------------------------------------------------------------
+/// Called after attaching a process.
+///
+/// Allow DynamicLoader plug-ins to execute some code after
+/// attaching to a process.
+//------------------------------------------------------------------
+void
+DynamicLoaderDarwin::DidAttach ()
+{
+ PrivateInitialize(m_process);
+ DoInitialImageFetch ();
+ SetNotificationBreakpoint ();
+}
+
+//------------------------------------------------------------------
+/// Called after attaching a process.
+///
+/// Allow DynamicLoader plug-ins to execute some code after
+/// attaching to a process.
+//------------------------------------------------------------------
+void
+DynamicLoaderDarwin::DidLaunch ()
+{
+ PrivateInitialize(m_process);
+ DoInitialImageFetch ();
+ SetNotificationBreakpoint ();
+}
+
+
+//----------------------------------------------------------------------
+// Clear out the state of this class.
+//----------------------------------------------------------------------
+void
+DynamicLoaderDarwin::Clear (bool clear_process)
+{
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (clear_process)
+ m_process = NULL;
+ m_dyld_image_infos.clear();
+ m_dyld_image_infos_stop_id = UINT32_MAX;
+ m_dyld.Clear(false);
+}
+
+ModuleSP
+DynamicLoaderDarwin::FindTargetModuleForImageInfo (ImageInfo &image_info, bool can_create, bool *did_create_ptr)
+{
+ if (did_create_ptr)
+ *did_create_ptr = false;
+
+ Target &target = m_process->GetTarget();
+ const ModuleList &target_images = target.GetImages();
+ ModuleSpec module_spec (image_info.file_spec);
+ module_spec.GetUUID() = image_info.uuid;
+ ModuleSP module_sp (target_images.FindFirstModule (module_spec));
+
+ if (module_sp && !module_spec.GetUUID().IsValid() && !module_sp->GetUUID().IsValid())
+ {
+ // No UUID, we must rely upon the cached module modification
+ // time and the modification time of the file on disk
+ if (module_sp->GetModificationTime() != module_sp->GetFileSpec().GetModificationTime())
+ module_sp.reset();
+ }
+
+ if (!module_sp)
+ {
+ if (can_create)
+ {
+ module_sp = target.GetSharedModule (module_spec);
+ if (!module_sp || module_sp->GetObjectFile() == NULL)
+ module_sp = m_process->ReadModuleFromMemory (image_info.file_spec, image_info.address);
+
+ if (did_create_ptr)
+ *did_create_ptr = (bool) module_sp;
+ }
+ }
+ return module_sp;
+}
+
+DynamicLoaderDarwin::ImageInfo *
+DynamicLoaderDarwin::FindImageInfoForAddress (addr_t load_address)
+{
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ const size_t image_count = m_dyld_image_infos.size();
+ for (size_t i = 0; i < image_count; i++)
+ {
+ if (load_address == m_dyld_image_infos[i].address)
+ {
+ return &m_dyld_image_infos[i];
+ }
+ }
+ return NULL;
+}
+
+void
+DynamicLoaderDarwin::UnloadImages (const std::vector<lldb::addr_t> &solib_addresses)
+{
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
+ return;
+
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+ Target &target = m_process->GetTarget();
+ if (log)
+ log->Printf ("Removing %" PRId64 " modules.", (uint64_t) solib_addresses.size());
+
+ ModuleList unloaded_module_list;
+
+ for (addr_t solib_addr : solib_addresses)
+ {
+ Address header;
+ if (header.SetLoadAddress (solib_addr, &target))
+ {
+ if (header.GetOffset() == 0)
+ {
+ ModuleSP module_to_remove (header.GetModule());
+ if (module_to_remove.get())
+ {
+ if (log)
+ log->Printf ("Removing module at address 0x%" PRIx64, solib_addr);
+ // remove the sections from the Target
+ UnloadSections (module_to_remove);
+ // add this to the list of modules to remove
+ unloaded_module_list.AppendIfNeeded (module_to_remove);
+ // remove the entry from the m_dyld_image_infos
+ ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
+ for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
+ {
+ if (solib_addr == (*pos).address)
+ {
+ m_dyld_image_infos.erase(pos);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (unloaded_module_list.GetSize() > 0)
+ {
+ if (log)
+ {
+ log->PutCString("Unloaded:");
+ unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderDarwin::UnloadModules");
+ }
+ m_process->GetTarget().GetImages().Remove (unloaded_module_list);
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
+ }
+}
+
+//----------------------------------------------------------------------
+// Update the load addresses for all segments in MODULE using the
+// updated INFO that is passed in.
+//----------------------------------------------------------------------
+bool
+DynamicLoaderDarwin::UpdateImageLoadAddress (Module *module, ImageInfo& info)
+{
+ bool changed = false;
+ if (module)
+ {
+ ObjectFile *image_object_file = module->GetObjectFile();
+ if (image_object_file)
+ {
+ SectionList *section_list = image_object_file->GetSectionList ();
+ if (section_list)
+ {
+ std::vector<uint32_t> inaccessible_segment_indexes;
+ // We now know the slide amount, so go through all sections
+ // and update the load addresses with the correct values.
+ const size_t num_segments = info.segments.size();
+ for (size_t i=0; i<num_segments; ++i)
+ {
+ // Only load a segment if it has protections. Things like
+ // __PAGEZERO don't have any protections, and they shouldn't
+ // be slid
+ SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
+
+ if (info.segments[i].maxprot == 0)
+ {
+ inaccessible_segment_indexes.push_back(i);
+ }
+ else
+ {
+ const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide;
+ static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
+
+ if (section_sp)
+ {
+ // __LINKEDIT sections from files in the shared cache
+ // can overlap so check to see what the segment name is
+ // and pass "false" so we don't warn of overlapping
+ // "Section" objects, and "true" for all other sections.
+ const bool warn_multiple = section_sp->GetName() != g_section_name_LINKEDIT;
+
+ changed = m_process->GetTarget().SetSectionLoadAddress (section_sp, new_section_load_addr, warn_multiple);
+ }
+ else
+ {
+ Host::SystemLog (Host::eSystemLogWarning,
+ "warning: unable to find and load segment named '%s' at 0x%" PRIx64 " in '%s' in macosx dynamic loader plug-in.\n",
+ info.segments[i].name.AsCString("<invalid>"),
+ (uint64_t)new_section_load_addr,
+ image_object_file->GetFileSpec().GetPath().c_str());
+ }
+ }
+ }
+
+ // If the loaded the file (it changed) and we have segments that
+ // are not readable or writeable, add them to the invalid memory
+ // region cache for the process. This will typically only be
+ // the __PAGEZERO segment in the main executable. We might be able
+ // to apply this more generally to more sections that have no
+ // protections in the future, but for now we are going to just
+ // do __PAGEZERO.
+ if (changed && !inaccessible_segment_indexes.empty())
+ {
+ for (uint32_t i=0; i<inaccessible_segment_indexes.size(); ++i)
+ {
+ const uint32_t seg_idx = inaccessible_segment_indexes[i];
+ SectionSP section_sp(section_list->FindSectionByName(info.segments[seg_idx].name));
+
+ if (section_sp)
+ {
+ static ConstString g_pagezero_section_name("__PAGEZERO");
+ if (g_pagezero_section_name == section_sp->GetName())
+ {
+ // __PAGEZERO never slides...
+ const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr;
+ const lldb::addr_t vmsize = info.segments[seg_idx].vmsize;
+ Process::LoadRange pagezero_range (vmaddr, vmsize);
+ m_process->AddInvalidMemoryRegion(pagezero_range);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ // We might have an in memory image that was loaded as soon as it was created
+ if (info.load_stop_id == m_process->GetStopID())
+ changed = true;
+ else if (changed)
+ {
+ // Update the stop ID when this library was updated
+ info.load_stop_id = m_process->GetStopID();
+ }
+ return changed;
+}
+
+//----------------------------------------------------------------------
+// Unload the segments in MODULE using the INFO that is passed in.
+//----------------------------------------------------------------------
+bool
+DynamicLoaderDarwin::UnloadModuleSections (Module *module, ImageInfo& info)
+{
+ bool changed = false;
+ if (module)
+ {
+ ObjectFile *image_object_file = module->GetObjectFile();
+ if (image_object_file)
+ {
+ SectionList *section_list = image_object_file->GetSectionList ();
+ if (section_list)
+ {
+ const size_t num_segments = info.segments.size();
+ for (size_t i=0; i<num_segments; ++i)
+ {
+ SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
+ if (section_sp)
+ {
+ const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide;
+ if (m_process->GetTarget().SetSectionUnloaded (section_sp, old_section_load_addr))
+ changed = true;
+ }
+ else
+ {
+ Host::SystemLog (Host::eSystemLogWarning,
+ "warning: unable to find and unload segment named '%s' in '%s' in macosx dynamic loader plug-in.\n",
+ info.segments[i].name.AsCString("<invalid>"),
+ image_object_file->GetFileSpec().GetPath().c_str());
+ }
+ }
+ }
+ }
+ }
+ return changed;
+}
+
+
+// Given a JSON dictionary (from debugserver, most likely) of binary images loaded in the inferior
+// process, add the images to the ImageInfo collection.
+
+bool
+DynamicLoaderDarwin::JSONImageInformationIntoImageInfo (StructuredData::ObjectSP image_details, ImageInfo::collection &image_infos)
+{
+ StructuredData::ObjectSP images_sp = image_details->GetAsDictionary()->GetValueForKey("images");
+ if (images_sp.get() == nullptr)
+ return false;
+
+ image_infos.resize (images_sp->GetAsArray()->GetSize());
+
+ for (size_t i = 0; i < image_infos.size(); i++)
+ {
+ StructuredData::ObjectSP image_sp = images_sp->GetAsArray()->GetItemAtIndex(i);
+ if (image_sp.get() == nullptr || image_sp->GetAsDictionary() == nullptr)
+ return false;
+ StructuredData::Dictionary *image = image_sp->GetAsDictionary();
+ if (image->HasKey("load_address") == false
+ || image->HasKey("pathname") == false
+ || image->HasKey("mod_date") == false
+ || image->HasKey("mach_header") == false
+ || image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr
+ || image->HasKey("segments") == false
+ || image->GetValueForKey("segments")->GetAsArray() == nullptr
+ || image->HasKey("uuid") == false )
+ {
+ return false;
+ }
+ image_infos[i].address = image->GetValueForKey("load_address")->GetAsInteger()->GetValue();
+ image_infos[i].mod_date = image->GetValueForKey("mod_date")->GetAsInteger()->GetValue();
+ image_infos[i].file_spec.SetFile(image->GetValueForKey("pathname")->GetAsString()->GetValue().c_str(), false);
+
+ StructuredData::Dictionary *mh = image->GetValueForKey("mach_header")->GetAsDictionary();
+ image_infos[i].header.magic = mh->GetValueForKey("magic")->GetAsInteger()->GetValue();
+ image_infos[i].header.cputype = mh->GetValueForKey("cputype")->GetAsInteger()->GetValue();
+ image_infos[i].header.cpusubtype = mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue();
+ image_infos[i].header.filetype = mh->GetValueForKey("filetype")->GetAsInteger()->GetValue();
+
+ // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't currently send them
+ // in the reply.
+
+ if (mh->HasKey("flags"))
+ image_infos[i].header.flags = mh->GetValueForKey("flags")->GetAsInteger()->GetValue();
+ else
+ image_infos[i].header.flags = 0;
+
+ if (mh->HasKey("ncmds"))
+ image_infos[i].header.ncmds = mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue();
+ else
+ image_infos[i].header.ncmds = 0;
+
+ if (mh->HasKey("sizeofcmds"))
+ image_infos[i].header.sizeofcmds = mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue();
+ else
+ image_infos[i].header.sizeofcmds = 0;
+
+ StructuredData::Array *segments = image->GetValueForKey("segments")->GetAsArray();
+ uint32_t segcount = segments->GetSize();
+ for (size_t j = 0; j < segcount; j++)
+ {
+ Segment segment;
+ StructuredData::Dictionary *seg = segments->GetItemAtIndex(j)->GetAsDictionary();
+ segment.name = ConstString(seg->GetValueForKey("name")->GetAsString()->GetValue().c_str());
+ segment.vmaddr = seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue();
+ segment.vmsize = seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue();
+ segment.fileoff = seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue();
+ segment.filesize = seg->GetValueForKey("filesize")->GetAsInteger()->GetValue();
+ segment.maxprot = seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue();
+
+ // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't currently send them
+ // in the reply.
+
+ if (seg->HasKey("initprot"))
+ segment.initprot = seg->GetValueForKey("initprot")->GetAsInteger()->GetValue();
+ else
+ segment.initprot = 0;
+
+ if (seg->HasKey("flags"))
+ segment.flags = seg->GetValueForKey("flags")->GetAsInteger()->GetValue();
+ else
+ segment.flags = 0;
+
+ if (seg->HasKey("nsects"))
+ segment.nsects = seg->GetValueForKey("nsects")->GetAsInteger()->GetValue();
+ else
+ segment.nsects = 0;
+
+ image_infos[i].segments.push_back (segment);
+ }
+
+ image_infos[i].uuid.SetFromCString (image->GetValueForKey("uuid")->GetAsString()->GetValue().c_str());
+
+ // All sections listed in the dyld image info structure will all
+ // either be fixed up already, or they will all be off by a single
+ // slide amount that is determined by finding the first segment
+ // that is at file offset zero which also has bytes (a file size
+ // that is greater than zero) in the object file.
+
+ // Determine the slide amount (if any)
+ const size_t num_sections = image_infos[i].segments.size();
+ for (size_t k = 0; k < num_sections; ++k)
+ {
+ // Iterate through the object file sections to find the
+ // first section that starts of file offset zero and that
+ // has bytes in the file...
+ if ((image_infos[i].segments[k].fileoff == 0 && image_infos[i].segments[k].filesize > 0)
+ || (image_infos[i].segments[k].name == ConstString("__TEXT")))
+ {
+ image_infos[i].slide = image_infos[i].address - image_infos[i].segments[k].vmaddr;
+ // We have found the slide amount, so we can exit
+ // this for loop.
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+void
+DynamicLoaderDarwin::UpdateDYLDImageInfoFromNewImageInfos (ImageInfo::collection &image_infos)
+{
+ const size_t image_infos_size = image_infos.size();
+ for (size_t i = 0; i < image_infos_size; i++)
+ {
+ if (image_infos[i].header.filetype == llvm::MachO::MH_DYLINKER)
+ {
+ UpdateDYLDImageInfoFromNewImageInfo (image_infos[i]);
+ break; // FIXME simulator debugging w/ multiple dylds
+ }
+ }
+}
+
+void
+DynamicLoaderDarwin::UpdateDYLDImageInfoFromNewImageInfo (ImageInfo &image_info)
+{
+ // FIXME simulator debugging w/ multiple dylds
+ if (image_info.header.filetype == llvm::MachO::MH_DYLINKER)
+ {
+ const bool can_create = true;
+ ModuleSP dyld_sp = FindTargetModuleForImageInfo (image_info, can_create, NULL);
+ if (dyld_sp.get())
+ {
+ Target &target = m_process->GetTarget();
+ target.GetImages().AppendIfNeeded (dyld_sp);
+ UpdateImageLoadAddress (dyld_sp.get(), image_info);
+ SetDYLDModule (dyld_sp);
+ }
+ }
+}
+
+void
+DynamicLoaderDarwin::AddExecutableModuleIfInImageInfos (ImageInfo::collection &image_infos)
+{
+ const size_t image_infos_size = image_infos.size();
+ for (size_t i = 0; i < image_infos_size; i++)
+ {
+ if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE)
+ {
+ Target &target = m_process->GetTarget();
+ const bool can_create = true;
+ ModuleSP exe_module_sp (FindTargetModuleForImageInfo (image_infos[i], can_create, NULL));
+
+ if (exe_module_sp)
+ {
+ UpdateImageLoadAddress (exe_module_sp.get(), image_infos[i]);
+
+ if (exe_module_sp.get() != target.GetExecutableModulePointer())
+ {
+ // Don't load dependent images since we are in dyld where we will know
+ // and find out about all images that are loaded. Also when setting the
+ // executable module, it will clear the targets module list, and if we
+ // have an in memory dyld module, it will get removed from the list
+ // so we will need to add it back after setting the executable module,
+ // so we first try and see if we already have a weak pointer to the
+ // dyld module, make it into a shared pointer, then add the executable,
+ // then re-add it back to make sure it is always in the list.
+
+ const bool get_dependent_images = false;
+ m_process->GetTarget().SetExecutableModule (exe_module_sp,
+ get_dependent_images);
+
+ UpdateDYLDImageInfoFromNewImageInfos (image_infos);
+ }
+ }
+ }
+ }
+}
+
+void
+DynamicLoaderDarwin::SetDYLDModule (lldb::ModuleSP &dyld_module_sp)
+{
+ m_dyld_module_wp = dyld_module_sp;
+}
+
+ModuleSP
+DynamicLoaderDarwin::GetDYLDModule ()
+{
+ ModuleSP dyld_sp (m_dyld_module_wp.lock());
+ return dyld_sp;
+}
+
+bool
+DynamicLoaderDarwin::AddModulesUsingImageInfos (ImageInfo::collection &image_infos)
+{
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ // Now add these images to the main list.
+ ModuleList loaded_module_list;
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+ Target &target = m_process->GetTarget();
+ ModuleList& target_images = target.GetImages();
+
+ for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
+ {
+ if (log)
+ {
+ log->Printf ("Adding new image at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
+ image_infos[idx].PutToLog (log);
+ }
+
+ m_dyld_image_infos.push_back(image_infos[idx]);
+
+ ModuleSP image_module_sp (FindTargetModuleForImageInfo (image_infos[idx], true, NULL));
+
+ if (image_module_sp)
+ {
+ ObjectFile *objfile = image_module_sp->GetObjectFile ();
+ if (objfile)
+ {
+ SectionList *sections = objfile->GetSectionList();
+ if (sections)
+ {
+ ConstString commpage_dbstr("__commpage");
+ Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
+ if (commpage_section)
+ {
+ ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ());
+ module_spec.GetObjectName() = commpage_dbstr;
+ ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec));
+ if (!commpage_image_module_sp)
+ {
+ module_spec.SetObjectOffset (objfile->GetFileOffset() + commpage_section->GetFileOffset());
+ module_spec.SetObjectSize (objfile->GetByteSize());
+ commpage_image_module_sp = target.GetSharedModule (module_spec);
+ if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
+ {
+ commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
+ image_infos[idx].address);
+ // Always load a memory image right away in the target in case
+ // we end up trying to read the symbol table from memory... The
+ // __LINKEDIT will need to be mapped so we can figure out where
+ // the symbol table bits are...
+ bool changed = false;
+ UpdateImageLoadAddress (commpage_image_module_sp.get(), image_infos[idx]);
+ target.GetImages().Append(commpage_image_module_sp);
+ if (changed)
+ {
+ image_infos[idx].load_stop_id = m_process->GetStopID();
+ loaded_module_list.AppendIfNeeded (commpage_image_module_sp);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // UpdateImageLoadAddress will return true if any segments
+ // change load address. We need to check this so we don't
+ // mention that all loaded shared libraries are newly loaded
+ // each time we hit out dyld breakpoint since dyld will list all
+ // shared libraries each time.
+ if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
+ {
+ target_images.AppendIfNeeded(image_module_sp);
+ loaded_module_list.AppendIfNeeded (image_module_sp);
+ }
+ }
+ }
+
+ if (loaded_module_list.GetSize() > 0)
+ {
+ if (log)
+ loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderDarwin::ModulesDidLoad");
+ m_process->GetTarget().ModulesDidLoad (loaded_module_list);
+ }
+ return true;
+}
+
+
+//----------------------------------------------------------------------
+// On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch
+// functions written in hand-written assembly, and also have hand-written unwind
+// information in the eh_frame section. Normally we prefer analyzing the
+// assembly instructions of a currently executing frame to unwind from that frame --
+// but on hand-written functions this profiling can fail. We should use the
+// eh_frame instructions for these functions all the time.
+//
+// As an aside, it would be better if the eh_frame entries had a flag (or were
+// extensible so they could have an Apple-specific flag) which indicates that
+// the instructions are asynchronous -- accurate at every instruction, instead
+// of our normal default assumption that they are not.
+//----------------------------------------------------------------------
+
+bool
+DynamicLoaderDarwin::AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
+{
+ ModuleSP module_sp;
+ if (sym_ctx.symbol)
+ {
+ module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
+ }
+ if (module_sp.get() == NULL && sym_ctx.function)
+ {
+ module_sp = sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
+ }
+ if (module_sp.get() == NULL)
+ return false;
+
+ ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
+ if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary (module_sp))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+
+//----------------------------------------------------------------------
+// Dump a Segment to the file handle provided.
+//----------------------------------------------------------------------
+void
+DynamicLoaderDarwin::Segment::PutToLog (Log *log, lldb::addr_t slide) const
+{
+ if (log)
+ {
+ if (slide == 0)
+ log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
+ name.AsCString(""),
+ vmaddr + slide,
+ vmaddr + slide + vmsize);
+ else
+ log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") slide = 0x%" PRIx64,
+ name.AsCString(""),
+ vmaddr + slide,
+ vmaddr + slide + vmsize,
+ slide);
+ }
+}
+
+const DynamicLoaderDarwin::Segment *
+DynamicLoaderDarwin::ImageInfo::FindSegment (const ConstString &name) const
+{
+ const size_t num_segments = segments.size();
+ for (size_t i=0; i<num_segments; ++i)
+ {
+ if (segments[i].name == name)
+ return &segments[i];
+ }
+ return NULL;
+}
+
+
+//----------------------------------------------------------------------
+// Dump an image info structure to the file handle provided.
+//----------------------------------------------------------------------
+void
+DynamicLoaderDarwin::ImageInfo::PutToLog (Log *log) const
+{
+ if (log == NULL)
+ return;
+ const uint8_t *u = (const uint8_t *)uuid.GetBytes();
+
+ if (address == LLDB_INVALID_ADDRESS)
+ {
+ if (u)
+ {
+ log->Printf("\t modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s' (UNLOADED)",
+ mod_date,
+ u[ 0], u[ 1], u[ 2], u[ 3],
+ u[ 4], u[ 5], u[ 6], u[ 7],
+ u[ 8], u[ 9], u[10], u[11],
+ u[12], u[13], u[14], u[15],
+ file_spec.GetPath().c_str());
+ }
+ else
+ log->Printf("\t modtime=0x%8.8" PRIx64 " path='%s' (UNLOADED)",
+ mod_date,
+ file_spec.GetPath().c_str());
+ }
+ else
+ {
+ if (u)
+ {
+ log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s'",
+ address,
+ mod_date,
+ u[ 0], u[ 1], u[ 2], u[ 3],
+ u[ 4], u[ 5], u[ 6], u[ 7],
+ u[ 8], u[ 9], u[10], u[11],
+ u[12], u[13], u[14], u[15],
+ file_spec.GetPath().c_str());
+ }
+ else
+ {
+ log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " path='%s'",
+ address,
+ mod_date,
+ file_spec.GetPath().c_str());
+
+ }
+ for (uint32_t i=0; i<segments.size(); ++i)
+ segments[i].PutToLog(log, slide);
+ }
+}
+
+void
+DynamicLoaderDarwin::PrivateInitialize(Process *process)
+{
+ DEBUG_PRINTF("DynamicLoaderDarwin::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
+ Clear(true);
+ m_process = process;
+ m_process->GetTarget().ClearAllLoadedSections();
+}
+
+//----------------------------------------------------------------------
+// Member function that gets called when the process state changes.
+//----------------------------------------------------------------------
+void
+DynamicLoaderDarwin::PrivateProcessStateChanged (Process *process, StateType state)
+{
+ DEBUG_PRINTF("DynamicLoaderDarwin::%s(%s)\n", __FUNCTION__, StateAsCString(state));
+ switch (state)
+ {
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateInvalid:
+ case eStateUnloaded:
+ case eStateExited:
+ case eStateDetached:
+ Clear(false);
+ break;
+
+ case eStateStopped:
+ // Keep trying find dyld and set our notification breakpoint each time
+ // we stop until we succeed
+ if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
+ {
+ if (NeedToDoInitialImageFetch ())
+ DoInitialImageFetch ();
+
+ SetNotificationBreakpoint ();
+ }
+ break;
+
+ case eStateRunning:
+ case eStateStepping:
+ case eStateCrashed:
+ case eStateSuspended:
+ break;
+ }
+}
+
+ThreadPlanSP
+DynamicLoaderDarwin::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
+{
+ ThreadPlanSP thread_plan_sp;
+ StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
+ const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
+ Symbol *current_symbol = current_context.symbol;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ TargetSP target_sp (thread.CalculateTarget());
+
+ if (current_symbol != NULL)
+ {
+ std::vector<Address> addresses;
+
+ if (current_symbol->IsTrampoline())
+ {
+ const ConstString &trampoline_name = current_symbol->GetMangled().GetName(current_symbol->GetLanguage(), Mangled::ePreferMangled);
+
+ if (trampoline_name)
+ {
+ const ModuleList &images = target_sp->GetImages();
+
+ SymbolContextList code_symbols;
+ images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, code_symbols);
+ size_t num_code_symbols = code_symbols.GetSize();
+
+ if (num_code_symbols > 0)
+ {
+ for (uint32_t i = 0; i < num_code_symbols; i++)
+ {
+ SymbolContext context;
+ AddressRange addr_range;
+ if (code_symbols.GetContextAtIndex(i, context))
+ {
+ context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
+ addresses.push_back(addr_range.GetBaseAddress());
+ if (log)
+ {
+ addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
+
+ log->Printf ("Found a trampoline target symbol at 0x%" PRIx64 ".", load_addr);
+ }
+ }
+ }
+ }
+
+ SymbolContextList reexported_symbols;
+ images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeReExported, reexported_symbols);
+ size_t num_reexported_symbols = reexported_symbols.GetSize();
+ if (num_reexported_symbols > 0)
+ {
+ for (uint32_t i = 0; i < num_reexported_symbols; i++)
+ {
+ SymbolContext context;
+ if (reexported_symbols.GetContextAtIndex(i, context))
+ {
+ if (context.symbol)
+ {
+ Symbol *actual_symbol = context.symbol->ResolveReExportedSymbol(*target_sp.get());
+ if (actual_symbol)
+ {
+ const Address actual_symbol_addr = actual_symbol->GetAddress();
+ if (actual_symbol_addr.IsValid())
+ {
+ addresses.push_back(actual_symbol_addr);
+ if (log)
+ {
+ lldb::addr_t load_addr = actual_symbol_addr.GetLoadAddress(target_sp.get());
+ log->Printf ("Found a re-exported symbol: %s at 0x%" PRIx64 ".",
+ actual_symbol->GetName().GetCString(), load_addr);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ SymbolContextList indirect_symbols;
+ images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver, indirect_symbols);
+ size_t num_indirect_symbols = indirect_symbols.GetSize();
+ if (num_indirect_symbols > 0)
+ {
+ for (uint32_t i = 0; i < num_indirect_symbols; i++)
+ {
+ SymbolContext context;
+ AddressRange addr_range;
+ if (indirect_symbols.GetContextAtIndex(i, context))
+ {
+ context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
+ addresses.push_back(addr_range.GetBaseAddress());
+ if (log)
+ {
+ addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
+
+ log->Printf ("Found an indirect target symbol at 0x%" PRIx64 ".", load_addr);
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (current_symbol->GetType() == eSymbolTypeReExported)
+ {
+ // I am not sure we could ever end up stopped AT a re-exported symbol. But just in case:
+
+ const Symbol *actual_symbol = current_symbol->ResolveReExportedSymbol(*(target_sp.get()));
+ if (actual_symbol)
+ {
+ Address target_addr(actual_symbol->GetAddress());
+ if (target_addr.IsValid())
+ {
+ if (log)
+ log->Printf ("Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64 ".",
+ current_symbol->GetName().GetCString(),
+ actual_symbol->GetName().GetCString(),
+ target_addr.GetLoadAddress(target_sp.get()));
+ addresses.push_back (target_addr.GetLoadAddress(target_sp.get()));
+
+ }
+ }
+ }
+
+ if (addresses.size() > 0)
+ {
+ // First check whether any of the addresses point to Indirect symbols, and if they do, resolve them:
+ std::vector<lldb::addr_t> load_addrs;
+ for (Address address : addresses)
+ {
+ Symbol *symbol = address.CalculateSymbolContextSymbol();
+ if (symbol && symbol->IsIndirect())
+ {
+ Error error;
+ Address symbol_address = symbol->GetAddress();
+ addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(&symbol_address, error);
+ if (error.Success())
+ {
+ load_addrs.push_back(resolved_addr);
+ if (log)
+ log->Printf("ResolveIndirectFunction found resolved target for %s at 0x%" PRIx64 ".",
+ symbol->GetName().GetCString(), resolved_addr);
+ }
+ }
+ else
+ {
+ load_addrs.push_back(address.GetLoadAddress(target_sp.get()));
+ }
+
+ }
+ thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, load_addrs, stop_others));
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("Could not find symbol for step through.");
+ }
+
+ return thread_plan_sp;
+}
+
+size_t
+DynamicLoaderDarwin::FindEquivalentSymbols (lldb_private::Symbol *original_symbol,
+ lldb_private::ModuleList &images,
+ lldb_private::SymbolContextList &equivalent_symbols)
+{
+ const ConstString &trampoline_name = original_symbol->GetMangled().GetName(original_symbol->GetLanguage(), Mangled::ePreferMangled);
+ if (!trampoline_name)
+ return 0;
+
+ size_t initial_size = equivalent_symbols.GetSize();
+
+ static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$";
+ std::string equivalent_regex_buf("^");
+ equivalent_regex_buf.append (trampoline_name.GetCString());
+ equivalent_regex_buf.append (resolver_name_regex);
+
+ RegularExpression equivalent_name_regex (equivalent_regex_buf.c_str());
+ const bool append = true;
+ images.FindSymbolsMatchingRegExAndType (equivalent_name_regex, eSymbolTypeCode, equivalent_symbols, append);
+
+ return equivalent_symbols.GetSize() - initial_size;
+}
+
+lldb::ModuleSP
+DynamicLoaderDarwin::GetPThreadLibraryModule()
+{
+ ModuleSP module_sp = m_libpthread_module_wp.lock();
+ if (!module_sp)
+ {
+ SymbolContextList sc_list;
+ ModuleSpec module_spec;
+ module_spec.GetFileSpec().GetFilename().SetCString("libsystem_pthread.dylib");
+ ModuleList module_list;
+ if (m_process->GetTarget().GetImages().FindModules(module_spec, module_list))
+ {
+ if (module_list.GetSize() == 1)
+ {
+ module_sp = module_list.GetModuleAtIndex(0);
+ if (module_sp)
+ m_libpthread_module_wp = module_sp;
+ }
+ }
+ }
+ return module_sp;
+}
+
+Address
+DynamicLoaderDarwin::GetPthreadSetSpecificAddress()
+{
+ if (!m_pthread_getspecific_addr.IsValid())
+ {
+ ModuleSP module_sp = GetPThreadLibraryModule();
+ if (module_sp)
+ {
+ lldb_private::SymbolContextList sc_list;
+ module_sp->FindSymbolsWithNameAndType(ConstString("pthread_getspecific"), eSymbolTypeCode, sc_list);
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(0, sc))
+ {
+ if (sc.symbol)
+ m_pthread_getspecific_addr = sc.symbol->GetAddress();
+ }
+ }
+ }
+ return m_pthread_getspecific_addr;
+}
+
+lldb::addr_t
+DynamicLoaderDarwin::GetThreadLocalData(const lldb::ModuleSP module_sp, const lldb::ThreadSP thread_sp,
+ lldb::addr_t tls_file_addr)
+{
+ if (!thread_sp || !module_sp)
+ return LLDB_INVALID_ADDRESS;
+
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ const uint32_t addr_size = m_process->GetAddressByteSize();
+ uint8_t buf[sizeof(lldb::addr_t) * 3];
+
+ lldb_private::Address tls_addr;
+ if (module_sp->ResolveFileAddress(tls_file_addr, tls_addr))
+ {
+ Error error;
+ const size_t tsl_data_size = addr_size * 3;
+ Target &target = m_process->GetTarget();
+ if (target.ReadMemory(tls_addr, false, buf, tsl_data_size, error) == tsl_data_size)
+ {
+ const ByteOrder byte_order = m_process->GetByteOrder();
+ DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
+ lldb::offset_t offset = addr_size; // Skip the first pointer
+ const lldb::addr_t pthread_key = data.GetAddress(&offset);
+ const lldb::addr_t tls_offset = data.GetAddress(&offset);
+ if (pthread_key != 0)
+ {
+ // First check to see if we have already figured out the location
+ // of TLS data for the pthread_key on a specific thread yet. If we
+ // have we can re-use it since its location will not change unless
+ // the process execs.
+ const tid_t tid = thread_sp->GetID();
+ auto tid_pos = m_tid_to_tls_map.find(tid);
+ if (tid_pos != m_tid_to_tls_map.end())
+ {
+ auto tls_pos = tid_pos->second.find(pthread_key);
+ if (tls_pos != tid_pos->second.end())
+ {
+ return tls_pos->second + tls_offset;
+ }
+ }
+ StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(0);
+ if (frame_sp)
+ {
+ ClangASTContext *clang_ast_context = target.GetScratchClangASTContext();
+
+ if (!clang_ast_context)
+ return LLDB_INVALID_ADDRESS;
+
+ CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Address pthread_getspecific_addr = GetPthreadSetSpecificAddress();
+ if (pthread_getspecific_addr.IsValid())
+ {
+ EvaluateExpressionOptions options;
+
+ lldb::ThreadPlanSP thread_plan_sp(
+ new ThreadPlanCallFunction(*thread_sp, pthread_getspecific_addr, clang_void_ptr_type,
+ llvm::ArrayRef<lldb::addr_t>(pthread_key), options));
+
+ DiagnosticManager execution_errors;
+ ExecutionContext exe_ctx(thread_sp);
+ lldb::ExpressionResults results =
+ m_process->RunThreadPlan(exe_ctx, thread_plan_sp, options, execution_errors);
+
+ if (results == lldb::eExpressionCompleted)
+ {
+ lldb::ValueObjectSP result_valobj_sp = thread_plan_sp->GetReturnValueObject();
+ if (result_valobj_sp)
+ {
+ const lldb::addr_t pthread_key_data = result_valobj_sp->GetValueAsUnsigned(0);
+ if (pthread_key_data)
+ {
+ m_tid_to_tls_map[tid].insert(std::make_pair(pthread_key, pthread_key_data));
+ return pthread_key_data + tls_offset;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
new file mode 100644
index 000000000000..b7dd51d288df
--- /dev/null
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
@@ -0,0 +1,293 @@
+//===-- DynamicLoaderDarwin.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DynamicLoaderDarwin_h_
+#define liblldb_DynamicLoaderDarwin_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <mutex>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Core/StructuredData.h"
+#include "lldb/Core/UUID.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/SafeMachO.h"
+
+namespace lldb_private {
+
+class DynamicLoaderDarwin : public lldb_private::DynamicLoader
+{
+public:
+ DynamicLoaderDarwin(lldb_private::Process *process);
+
+ virtual ~DynamicLoaderDarwin() override;
+
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ void
+ DidAttach() override;
+
+ void
+ DidLaunch() override;
+
+ lldb::ThreadPlanSP
+ GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override;
+
+ size_t
+ FindEquivalentSymbols(lldb_private::Symbol *original_symbol,
+ lldb_private::ModuleList &module_list,
+ lldb_private::SymbolContextList &equivalent_symbols) override;
+
+ lldb::addr_t
+ GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override;
+
+ bool
+ AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
+
+ virtual void
+ DoInitialImageFetch () = 0;
+
+ virtual bool
+ NeedToDoInitialImageFetch () = 0;
+
+protected:
+ void
+ PrivateInitialize (lldb_private::Process *process);
+
+ void
+ PrivateProcessStateChanged (lldb_private::Process *process,
+ lldb::StateType state);
+
+ void
+ Clear (bool clear_process);
+
+ // Clear method for classes derived from this one
+ virtual void
+ DoClear () = 0;
+
+ void
+ SetDYLDModule (lldb::ModuleSP &dyld_module_sp);
+
+ lldb::ModuleSP
+ GetDYLDModule ();
+
+ class Segment
+ {
+ public:
+ Segment() :
+ name(),
+ vmaddr(LLDB_INVALID_ADDRESS),
+ vmsize(0),
+ fileoff(0),
+ filesize(0),
+ maxprot(0),
+ initprot(0),
+ nsects(0),
+ flags(0)
+ {
+ }
+
+ lldb_private::ConstString name;
+ lldb::addr_t vmaddr;
+ lldb::addr_t vmsize;
+ lldb::addr_t fileoff;
+ lldb::addr_t filesize;
+ uint32_t maxprot;
+ uint32_t initprot;
+ uint32_t nsects;
+ uint32_t flags;
+
+ bool
+ operator==(const Segment& rhs) const
+ {
+ return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
+ }
+
+ void
+ PutToLog (lldb_private::Log *log,
+ lldb::addr_t slide) const;
+
+ };
+
+ struct ImageInfo
+ {
+ lldb::addr_t address; // Address of mach header for this dylib
+ lldb::addr_t slide; // The amount to slide all segments by if there is a global slide.
+ lldb::addr_t mod_date; // Modification date for this dylib
+ lldb_private::FileSpec file_spec; // Resolved path for this dylib
+ lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
+ llvm::MachO::mach_header header; // The mach header for this image
+ std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior)
+ uint32_t load_stop_id; // The process stop ID that the sections for this image were loaded
+
+ ImageInfo() :
+ address(LLDB_INVALID_ADDRESS),
+ slide(0),
+ mod_date(0),
+ file_spec(),
+ uuid(),
+ header(),
+ segments(),
+ load_stop_id(0)
+ {
+ }
+
+ void
+ Clear(bool load_cmd_data_only)
+ {
+ if (!load_cmd_data_only)
+ {
+ address = LLDB_INVALID_ADDRESS;
+ slide = 0;
+ mod_date = 0;
+ file_spec.Clear();
+ ::memset (&header, 0, sizeof(header));
+ }
+ uuid.Clear();
+ segments.clear();
+ load_stop_id = 0;
+ }
+
+ bool
+ operator == (const ImageInfo& rhs) const
+ {
+ return address == rhs.address
+ && slide == rhs.slide
+ && mod_date == rhs.mod_date
+ && file_spec == rhs.file_spec
+ && uuid == rhs.uuid
+ && memcmp(&header, &rhs.header, sizeof(header)) == 0
+ && segments == rhs.segments;
+ }
+
+ bool
+ UUIDValid() const
+ {
+ return uuid.IsValid();
+ }
+
+ uint32_t
+ GetAddressByteSize ()
+ {
+ if (header.cputype)
+ {
+ if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
+ return 8;
+ else
+ return 4;
+ }
+ return 0;
+ }
+
+ lldb_private::ArchSpec
+ GetArchitecture () const
+ {
+ return lldb_private::ArchSpec (lldb_private::eArchTypeMachO, header.cputype, header.cpusubtype);
+ }
+
+ const Segment *
+ FindSegment (const lldb_private::ConstString &name) const;
+
+ void
+ PutToLog (lldb_private::Log *log) const;
+
+ typedef std::vector<ImageInfo> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+ };
+
+ bool
+ UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo& info);
+
+ bool
+ UnloadModuleSections (lldb_private::Module *module, ImageInfo& info);
+
+ ImageInfo *
+ FindImageInfoForAddress (lldb::addr_t load_address);
+
+ lldb::ModuleSP
+ FindTargetModuleForImageInfo (ImageInfo &image_info,
+ bool can_create,
+ bool *did_create_ptr);
+
+ void
+ UnloadImages (const std::vector<lldb::addr_t> &solib_addresses);
+
+ virtual bool
+ SetNotificationBreakpoint () = 0;
+
+ virtual void
+ ClearNotificationBreakpoint () = 0;
+
+ virtual bool
+ DidSetNotificationBreakpoint () = 0;
+
+ typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
+ typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
+
+ std::recursive_mutex &
+ GetMutex () const
+ {
+ return m_mutex;
+ }
+
+ lldb::ModuleSP
+ GetPThreadLibraryModule();
+
+ lldb_private::Address
+ GetPthreadSetSpecificAddress();
+
+ bool
+ JSONImageInformationIntoImageInfo (lldb_private::StructuredData::ObjectSP image_details, ImageInfo::collection &image_infos);
+
+ // If image_infos contains / may contain dyld image, call this method
+ // to keep our internal record keeping of the special dyld binary up-to-date.
+ void
+ UpdateDYLDImageInfoFromNewImageInfos (ImageInfo::collection &image_infos);
+
+ // if image_info is a dyld binary, call this method
+ void
+ UpdateDYLDImageInfoFromNewImageInfo (ImageInfo &image_info);
+
+ // If image_infos contains / may contain executable image, call this method
+ // to keep our internal record keeping of the special dyld binary up-to-date.
+ void
+ AddExecutableModuleIfInImageInfos (ImageInfo::collection &image_infos);
+
+ bool
+ AddModulesUsingImageInfos (ImageInfo::collection &image_infos);
+
+ lldb::ModuleWP m_dyld_module_wp;
+ lldb::ModuleWP m_libpthread_module_wp;
+ lldb_private::Address m_pthread_getspecific_addr;
+ ThreadIDToTLSMap m_tid_to_tls_map;
+ ImageInfo::collection m_dyld_image_infos; // Current shared libraries information
+ uint32_t m_dyld_image_infos_stop_id; // The process stop ID that "m_dyld_image_infos" is valid for
+ ImageInfo m_dyld;
+ mutable std::recursive_mutex m_mutex;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwin);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_DynamicLoaderDarwin_h_
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index fba11f6aea85..a8bc216fb17e 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -29,6 +29,7 @@
#include "lldb/Target/StackFrame.h"
#include "DynamicLoaderMacOSXDYLD.h"
+#include "DynamicLoaderDarwin.h"
//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
@@ -47,47 +48,6 @@
using namespace lldb;
using namespace lldb_private;
-/// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
-/// I am putting it here so I can invoke it in the Trampoline code here, but
-/// it should be moved to the ObjC Runtime support when it is set up.
-
-
-DynamicLoaderMacOSXDYLD::DYLDImageInfo *
-DynamicLoaderMacOSXDYLD::GetImageInfo (Module *module)
-{
- const UUID &module_uuid = module->GetUUID();
- DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
-
- // First try just by UUID as it is the safest.
- if (module_uuid.IsValid())
- {
- for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
- {
- if (pos->uuid == module_uuid)
- return &(*pos);
- }
-
- if (m_dyld.uuid == module_uuid)
- return &m_dyld;
- }
-
- // Next try by platform path only for things that don't have a valid UUID
- // since if a file has a valid UUID in real life it should also in the
- // dyld info. This is the next safest because the paths in the dyld info
- // are platform paths, not local paths. For local debugging platform == local
- // paths.
- const FileSpec &platform_file_spec = module->GetPlatformFileSpec();
- for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
- {
- if (pos->file_spec == platform_file_spec && pos->uuid.IsValid() == false)
- return &(*pos);
- }
-
- if (m_dyld.file_spec == platform_file_spec && m_dyld.uuid.IsValid() == false)
- return &m_dyld;
-
- return NULL;
-}
//----------------------------------------------------------------------
// Create an instance of this class. This function is filled into
@@ -139,16 +99,12 @@ DynamicLoaderMacOSXDYLD::CreateInstance (Process* process, bool force)
// Constructor
//----------------------------------------------------------------------
DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
- DynamicLoader(process),
- m_dyld(),
- m_dyld_module_wp(),
+ DynamicLoaderDarwin(process),
m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
m_dyld_all_image_infos(),
m_dyld_all_image_infos_stop_id (UINT32_MAX),
m_break_id(LLDB_INVALID_BREAK_ID),
- m_dyld_image_infos(),
- m_dyld_image_infos_stop_id (UINT32_MAX),
- m_mutex(Mutex::eMutexTypeRecursive),
+ m_mutex(),
m_process_image_addr_is_all_images_infos (false)
{
}
@@ -158,40 +114,15 @@ DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
//----------------------------------------------------------------------
DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD()
{
- Clear(true);
-}
-
-//------------------------------------------------------------------
-/// Called after attaching a process.
-///
-/// Allow DynamicLoader plug-ins to execute some code after
-/// attaching to a process.
-//------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::DidAttach ()
-{
- PrivateInitialize(m_process);
- LocateDYLD ();
- SetNotificationBreakpoint ();
-}
-
-//------------------------------------------------------------------
-/// Called after attaching a process.
-///
-/// Allow DynamicLoader plug-ins to execute some code after
-/// attaching to a process.
-//------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::DidLaunch ()
-{
- PrivateInitialize(m_process);
- LocateDYLD ();
- SetNotificationBreakpoint ();
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->GetTarget().RemoveBreakpointByID (m_break_id);
}
bool
DynamicLoaderMacOSXDYLD::ProcessDidExec ()
{
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ bool did_exec = false;
if (m_process)
{
// If we are stopped after an exec, we will have only one thread...
@@ -205,76 +136,86 @@ DynamicLoaderMacOSXDYLD::ProcessDidExec ()
{
// The image info address from the process is the 'dyld_all_image_infos'
// address and it has changed.
- return true;
+ did_exec = true;
}
-
- if (m_process_image_addr_is_all_images_infos == false && shlib_addr == m_dyld.address)
+ else if (m_process_image_addr_is_all_images_infos == false && shlib_addr == m_dyld.address)
{
// The image info address from the process is the mach_header
// address for dyld and it has changed.
- return true;
+ did_exec = true;
}
-
- // ASLR might be disabled and dyld could have ended up in the same
- // location. We should try and detect if we are stopped at '_dyld_start'
- ThreadSP thread_sp (m_process->GetThreadList().GetThreadAtIndex(0));
- if (thread_sp)
+ else
{
- lldb::StackFrameSP frame_sp (thread_sp->GetStackFrameAtIndex(0));
- if (frame_sp)
+ // ASLR might be disabled and dyld could have ended up in the same
+ // location. We should try and detect if we are stopped at '_dyld_start'
+ ThreadSP thread_sp(m_process->GetThreadList().GetThreadAtIndex(0));
+ if (thread_sp)
{
- const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
- if (symbol)
+ lldb::StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
+ if (frame_sp)
{
- if (symbol->GetName() == ConstString("_dyld_start"))
- return true;
+ const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
+ if (symbol)
+ {
+ if (symbol->GetName() == ConstString("_dyld_start"))
+ did_exec = true;
+ }
}
}
}
+
+ if (did_exec)
+ {
+ m_libpthread_module_wp.reset();
+ m_pthread_getspecific_addr.Clear();
+ }
}
}
- return false;
+ return did_exec;
}
-
-
//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
void
-DynamicLoaderMacOSXDYLD::Clear (bool clear_process)
+DynamicLoaderMacOSXDYLD::DoClear ()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (LLDB_BREAK_ID_IS_VALID(m_break_id))
m_process->GetTarget().RemoveBreakpointByID (m_break_id);
- if (clear_process)
- m_process = NULL;
- m_dyld.Clear(false);
m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
m_dyld_all_image_infos.Clear();
m_break_id = LLDB_INVALID_BREAK_ID;
- m_dyld_image_infos.clear();
}
//----------------------------------------------------------------------
// Check if we have found DYLD yet
//----------------------------------------------------------------------
bool
-DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() const
+DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint()
{
return LLDB_BREAK_ID_IS_VALID (m_break_id);
}
+void
+DynamicLoaderMacOSXDYLD::ClearNotificationBreakpoint ()
+{
+ if (LLDB_BREAK_ID_IS_VALID (m_break_id))
+ {
+ m_process->GetTarget().RemoveBreakpointByID (m_break_id);
+ }
+}
+
//----------------------------------------------------------------------
// Try and figure out where dyld is by first asking the Process
// if it knows (which currently calls down in the lldb::Process
// to get the DYLD info (available on SnowLeopard only). If that fails,
// then check in the default addresses.
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::LocateDYLD()
+void
+DynamicLoaderMacOSXDYLD::DoInitialImageFetch()
{
if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS)
{
@@ -299,7 +240,8 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
case llvm::MachO::MH_CIGAM:
case llvm::MachO::MH_CIGAM_64:
m_process_image_addr_is_all_images_infos = false;
- return ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
+ return;
default:
break;
@@ -316,9 +258,10 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
if (ReadAllImageInfosStructure ())
{
if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
- return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
else
- return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
+ return;
}
}
@@ -330,53 +273,18 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
const ArchSpec &exe_arch = executable->GetArchitecture();
if (exe_arch.GetAddressByteSize() == 8)
{
- return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
}
else if (exe_arch.GetMachine() == llvm::Triple::arm || exe_arch.GetMachine() == llvm::Triple::thumb || exe_arch.GetMachine() == llvm::Triple::aarch64)
{
- return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
}
else
{
- return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
- }
- }
- return false;
-}
-
-ModuleSP
-DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
-{
- if (did_create_ptr)
- *did_create_ptr = false;
-
- Target &target = m_process->GetTarget();
- const ModuleList &target_images = target.GetImages();
- ModuleSpec module_spec (image_info.file_spec);
- module_spec.GetUUID() = image_info.uuid;
- ModuleSP module_sp (target_images.FindFirstModule (module_spec));
-
- if (module_sp && !module_spec.GetUUID().IsValid() && !module_sp->GetUUID().IsValid())
- {
- // No UUID, we must rely upon the cached module modification
- // time and the modification time of the file on disk
- if (module_sp->GetModificationTime() != module_sp->GetFileSpec().GetModificationTime())
- module_sp.reset();
- }
-
- if (!module_sp)
- {
- if (can_create)
- {
- module_sp = target.GetSharedModule (module_spec);
- if (!module_sp || module_sp->GetObjectFile() == NULL)
- module_sp = m_process->ReadModuleFromMemory (image_info.file_spec, image_info.address);
-
- if (did_create_ptr)
- *did_create_ptr = (bool) module_sp;
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
}
}
- return module_sp;
+ return;
}
//----------------------------------------------------------------------
@@ -386,6 +294,7 @@ DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (DYLDImageInfo &image_
bool
DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr)
{
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
DataExtractor data; // Load command data
if (ReadMachHeader (addr, &m_dyld.header, &data))
{
@@ -397,12 +306,11 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::
{
if (m_dyld.file_spec)
{
- dyld_module_sp = FindTargetModuleForDYLDImageInfo (m_dyld, true, NULL);
+ UpdateDYLDImageInfoFromNewImageInfo (m_dyld);
- if (dyld_module_sp)
- UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld);
}
}
+ dyld_module_sp = GetDYLDModule();
Target &target = m_process->GetTarget();
@@ -430,7 +338,7 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::
ModuleList modules;
modules.Append(dyld_module_sp);
target.ModulesDidLoad(modules);
- m_dyld_module_wp = dyld_module_sp;
+ SetDYLDModule (dyld_module_sp);
}
return true;
}
@@ -439,152 +347,12 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::
}
bool
-DynamicLoaderMacOSXDYLD::NeedToLocateDYLD () const
+DynamicLoaderMacOSXDYLD::NeedToDoInitialImageFetch ()
{
return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
}
//----------------------------------------------------------------------
-// Update the load addresses for all segments in MODULE using the
-// updated INFO that is passed in.
-//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo& info)
-{
- bool changed = false;
- if (module)
- {
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file)
- {
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- std::vector<uint32_t> inaccessible_segment_indexes;
- // We now know the slide amount, so go through all sections
- // and update the load addresses with the correct values.
- const size_t num_segments = info.segments.size();
- for (size_t i=0; i<num_segments; ++i)
- {
- // Only load a segment if it has protections. Things like
- // __PAGEZERO don't have any protections, and they shouldn't
- // be slid
- SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
-
- if (info.segments[i].maxprot == 0)
- {
- inaccessible_segment_indexes.push_back(i);
- }
- else
- {
- const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide;
- static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
-
- if (section_sp)
- {
- // __LINKEDIT sections from files in the shared cache
- // can overlap so check to see what the segment name is
- // and pass "false" so we don't warn of overlapping
- // "Section" objects, and "true" for all other sections.
- const bool warn_multiple = section_sp->GetName() != g_section_name_LINKEDIT;
-
- changed = m_process->GetTarget().SetSectionLoadAddress (section_sp, new_section_load_addr, warn_multiple);
- }
- else
- {
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: unable to find and load segment named '%s' at 0x%" PRIx64 " in '%s' in macosx dynamic loader plug-in.\n",
- info.segments[i].name.AsCString("<invalid>"),
- (uint64_t)new_section_load_addr,
- image_object_file->GetFileSpec().GetPath().c_str());
- }
- }
- }
-
- // If the loaded the file (it changed) and we have segments that
- // are not readable or writeable, add them to the invalid memory
- // region cache for the process. This will typically only be
- // the __PAGEZERO segment in the main executable. We might be able
- // to apply this more generally to more sections that have no
- // protections in the future, but for now we are going to just
- // do __PAGEZERO.
- if (changed && !inaccessible_segment_indexes.empty())
- {
- for (uint32_t i=0; i<inaccessible_segment_indexes.size(); ++i)
- {
- const uint32_t seg_idx = inaccessible_segment_indexes[i];
- SectionSP section_sp(section_list->FindSectionByName(info.segments[seg_idx].name));
-
- if (section_sp)
- {
- static ConstString g_pagezero_section_name("__PAGEZERO");
- if (g_pagezero_section_name == section_sp->GetName())
- {
- // __PAGEZERO never slides...
- const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr;
- const lldb::addr_t vmsize = info.segments[seg_idx].vmsize;
- Process::LoadRange pagezero_range (vmaddr, vmsize);
- m_process->AddInvalidMemoryRegion(pagezero_range);
- }
- }
- }
- }
- }
- }
- }
- // We might have an in memory image that was loaded as soon as it was created
- if (info.load_stop_id == m_process->GetStopID())
- changed = true;
- else if (changed)
- {
- // Update the stop ID when this library was updated
- info.load_stop_id = m_process->GetStopID();
- }
- return changed;
-}
-
-//----------------------------------------------------------------------
-// Update the load addresses for all segments in MODULE using the
-// updated INFO that is passed in.
-//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, DYLDImageInfo& info)
-{
- bool changed = false;
- if (module)
- {
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file)
- {
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- const size_t num_segments = info.segments.size();
- for (size_t i=0; i<num_segments; ++i)
- {
- SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
- if (section_sp)
- {
- const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide;
- if (m_process->GetTarget().SetSectionUnloaded (section_sp, old_section_load_addr))
- changed = true;
- }
- else
- {
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: unable to find and unload segment named '%s' in '%s' in macosx dynamic loader plug-in.\n",
- info.segments[i].name.AsCString("<invalid>"),
- image_object_file->GetFileSpec().GetPath().c_str());
- }
- }
- }
- }
- }
- return changed;
-}
-
-
-//----------------------------------------------------------------------
// Static callback function that gets called when our DYLD notification
// breakpoint gets hit. We update all of our image infos and then
// let our super class DynamicLoader class decide if we should stop
@@ -683,7 +451,7 @@ DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton,
bool
DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// the all image infos is already valid for this process stop ID
if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
@@ -801,181 +569,16 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
}
-// This method is an amalgamation of code from
-// ReadMachHeader()
-// ParseLoadCommands()
-// UpdateImageInfosHeaderAndLoadCommands()
-// but written to extract everything from the JSON packet from debugserver, instead of using memory reads.
-
-bool
-DynamicLoaderMacOSXDYLD::AddModulesUsingInfosFromDebugserver (StructuredData::ObjectSP image_details, DYLDImageInfo::collection &image_infos)
-{
- StructuredData::ObjectSP images_sp = image_details->GetAsDictionary()->GetValueForKey("images");
- if (images_sp.get() == nullptr)
- return false;
-
- image_infos.resize (images_sp->GetAsArray()->GetSize());
-
- uint32_t exe_idx = UINT32_MAX;
-
- for (size_t i = 0; i < image_infos.size(); i++)
- {
- StructuredData::ObjectSP image_sp = images_sp->GetAsArray()->GetItemAtIndex(i);
- if (image_sp.get() == nullptr || image_sp->GetAsDictionary() == nullptr)
- return false;
- StructuredData::Dictionary *image = image_sp->GetAsDictionary();
- if (image->HasKey("load_address") == false
- || image->HasKey("pathname") == false
- || image->HasKey("mod_date") == false
- || image->HasKey("mach_header") == false
- || image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr
- || image->HasKey("segments") == false
- || image->GetValueForKey("segments")->GetAsArray() == nullptr
- || image->HasKey("uuid") == false )
- {
- return false;
- }
- image_infos[i].address = image->GetValueForKey("load_address")->GetAsInteger()->GetValue();
- image_infos[i].mod_date = image->GetValueForKey("mod_date")->GetAsInteger()->GetValue();
- image_infos[i].file_spec.SetFile(image->GetValueForKey("pathname")->GetAsString()->GetValue().c_str(), false);
-
- StructuredData::Dictionary *mh = image->GetValueForKey("mach_header")->GetAsDictionary();
- image_infos[i].header.magic = mh->GetValueForKey("magic")->GetAsInteger()->GetValue();
- image_infos[i].header.cputype = mh->GetValueForKey("cputype")->GetAsInteger()->GetValue();
- image_infos[i].header.cpusubtype = mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue();
- image_infos[i].header.filetype = mh->GetValueForKey("filetype")->GetAsInteger()->GetValue();
-
- // Fields that aren't used by DynamicLoaderMacOSXDYLD so debugserver doesn't currently send them
- // in the reply.
-
- if (mh->HasKey("flags"))
- image_infos[i].header.flags = mh->GetValueForKey("flags")->GetAsInteger()->GetValue();
- else
- image_infos[i].header.flags = 0;
-
- if (mh->HasKey("ncmds"))
- image_infos[i].header.ncmds = mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue();
- else
- image_infos[i].header.ncmds = 0;
-
- if (mh->HasKey("sizeofcmds"))
- image_infos[i].header.sizeofcmds = mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue();
- else
- image_infos[i].header.sizeofcmds = 0;
-
- if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE)
- exe_idx = i;
-
- StructuredData::Array *segments = image->GetValueForKey("segments")->GetAsArray();
- uint32_t segcount = segments->GetSize();
- for (size_t j = 0; j < segcount; j++)
- {
- Segment segment;
- StructuredData::Dictionary *seg = segments->GetItemAtIndex(j)->GetAsDictionary();
- segment.name = ConstString(seg->GetValueForKey("name")->GetAsString()->GetValue().c_str());
- segment.vmaddr = seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue();
- segment.vmsize = seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue();
- segment.fileoff = seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue();
- segment.filesize = seg->GetValueForKey("filesize")->GetAsInteger()->GetValue();
- segment.maxprot = seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue();
-
- // Fields that aren't used by DynamicLoaderMacOSXDYLD so debugserver doesn't currently send them
- // in the reply.
-
- if (seg->HasKey("initprot"))
- segment.initprot = seg->GetValueForKey("initprot")->GetAsInteger()->GetValue();
- else
- segment.initprot = 0;
-
- if (seg->HasKey("flags"))
- segment.flags = seg->GetValueForKey("flags")->GetAsInteger()->GetValue();
- else
- segment.flags = 0;
-
- if (seg->HasKey("nsects"))
- segment.nsects = seg->GetValueForKey("nsects")->GetAsInteger()->GetValue();
- else
- segment.nsects = 0;
-
- image_infos[i].segments.push_back (segment);
- }
-
- image_infos[i].uuid.SetFromCString (image->GetValueForKey("uuid")->GetAsString()->GetValue().c_str());
-
- // All sections listed in the dyld image info structure will all
- // either be fixed up already, or they will all be off by a single
- // slide amount that is determined by finding the first segment
- // that is at file offset zero which also has bytes (a file size
- // that is greater than zero) in the object file.
-
- // Determine the slide amount (if any)
- const size_t num_sections = image_infos[i].segments.size();
- for (size_t k = 0; k < num_sections; ++k)
- {
- // Iterate through the object file sections to find the
- // first section that starts of file offset zero and that
- // has bytes in the file...
- if ((image_infos[i].segments[k].fileoff == 0 && image_infos[i].segments[k].filesize > 0)
- || (image_infos[i].segments[k].name == ConstString("__TEXT")))
- {
- image_infos[i].slide = image_infos[i].address - image_infos[i].segments[k].vmaddr;
- // We have found the slide amount, so we can exit
- // this for loop.
- break;
- }
- }
- }
-
- Target &target = m_process->GetTarget();
-
- if (exe_idx < image_infos.size())
- {
- const bool can_create = true;
- ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], can_create, NULL));
-
- if (exe_module_sp)
- {
- UpdateImageLoadAddress (exe_module_sp.get(), image_infos[exe_idx]);
-
- if (exe_module_sp.get() != target.GetExecutableModulePointer())
- {
- // Don't load dependent images since we are in dyld where we will know
- // and find out about all images that are loaded. Also when setting the
- // executable module, it will clear the targets module list, and if we
- // have an in memory dyld module, it will get removed from the list
- // so we will need to add it back after setting the executable module,
- // so we first try and see if we already have a weak pointer to the
- // dyld module, make it into a shared pointer, then add the executable,
- // then re-add it back to make sure it is always in the list.
- ModuleSP dyld_module_sp(m_dyld_module_wp.lock());
-
- const bool get_dependent_images = false;
- m_process->GetTarget().SetExecutableModule (exe_module_sp,
- get_dependent_images);
-
- if (dyld_module_sp)
- {
- if(target.GetImages().AppendIfNeeded (dyld_module_sp))
- {
- // Also add it to the section list.
- UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
- }
- }
- }
- }
- }
- return true;
-}
-
bool
DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
{
- DYLDImageInfo::collection image_infos;
+ ImageInfo::collection image_infos;
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
if (log)
log->Printf ("Adding %d modules.\n", image_infos_count);
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
return true;
@@ -987,8 +590,9 @@ DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_in
&& image_infos_json_sp->GetAsDictionary()->GetValueForKey("images")->GetAsArray()->GetSize() == image_infos_count)
{
bool return_value = false;
- if (AddModulesUsingInfosFromDebugserver (image_infos_json_sp, image_infos))
+ if (JSONImageInformationIntoImageInfo (image_infos_json_sp, image_infos))
{
+ AddExecutableModuleIfInImageInfos (image_infos);
return_value = AddModulesUsingImageInfos (image_infos);
}
m_dyld_image_infos_stop_id = m_process->GetStopID();
@@ -1004,101 +608,14 @@ DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_in
return return_value;
}
-// Adds the modules in image_infos to m_dyld_image_infos.
-// NB don't call this passing in m_dyld_image_infos.
-
-bool
-DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos)
-{
- // Now add these images to the main list.
- ModuleList loaded_module_list;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- Target &target = m_process->GetTarget();
- ModuleList& target_images = target.GetImages();
-
- for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
- {
- if (log)
- {
- log->Printf ("Adding new image at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
- image_infos[idx].PutToLog (log);
- }
-
- m_dyld_image_infos.push_back(image_infos[idx]);
-
- ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], true, NULL));
-
- if (image_module_sp)
- {
- ObjectFile *objfile = image_module_sp->GetObjectFile ();
- if (objfile)
- {
- SectionList *sections = objfile->GetSectionList();
- if (sections)
- {
- ConstString commpage_dbstr("__commpage");
- Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
- if (commpage_section)
- {
- ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ());
- module_spec.GetObjectName() = commpage_dbstr;
- ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec));
- if (!commpage_image_module_sp)
- {
- module_spec.SetObjectOffset (objfile->GetFileOffset() + commpage_section->GetFileOffset());
- module_spec.SetObjectSize (objfile->GetByteSize());
- commpage_image_module_sp = target.GetSharedModule (module_spec);
- if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
- {
- commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
- image_infos[idx].address);
- // Always load a memory image right away in the target in case
- // we end up trying to read the symbol table from memory... The
- // __LINKEDIT will need to be mapped so we can figure out where
- // the symbol table bits are...
- bool changed = false;
- UpdateImageLoadAddress (commpage_image_module_sp.get(), image_infos[idx]);
- target.GetImages().Append(commpage_image_module_sp);
- if (changed)
- {
- image_infos[idx].load_stop_id = m_process->GetStopID();
- loaded_module_list.AppendIfNeeded (commpage_image_module_sp);
- }
- }
- }
- }
- }
- }
-
- // UpdateImageLoadAddress will return true if any segments
- // change load address. We need to check this so we don't
- // mention that all loaded shared libraries are newly loaded
- // each time we hit out dyld breakpoint since dyld will list all
- // shared libraries each time.
- if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
- {
- target_images.AppendIfNeeded(image_module_sp);
- loaded_module_list.AppendIfNeeded (image_module_sp);
- }
- }
- }
-
- if (loaded_module_list.GetSize() > 0)
- {
- if (log)
- loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad");
- m_process->GetTarget().ModulesDidLoad (loaded_module_list);
- }
- return true;
-}
-
bool
DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
{
- DYLDImageInfo::collection image_infos;
+ ImageInfo::collection image_infos;
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
return true;
@@ -1129,7 +646,7 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image
// Also copy over the uuid from the old entry to the removed entry so we can
// use it to lookup the module in the module list.
- DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
+ ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
{
if (image_infos[idx].address == (*pos).address)
@@ -1139,12 +656,12 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image
// Add the module from this image_info to the "unloaded_module_list". We'll remove them all at
// one go later on.
- ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], false, NULL));
+ ModuleSP unload_image_module_sp (FindTargetModuleForImageInfo (image_infos[idx], false, NULL));
if (unload_image_module_sp.get())
{
// When we unload, be sure to use the image info from the old list,
// since that has sections correctly filled in.
- UnloadImageLoadAddress (unload_image_module_sp.get(), *pos);
+ UnloadModuleSections (unload_image_module_sp.get(), *pos);
unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
}
else
@@ -1188,9 +705,10 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image
bool
DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr,
uint32_t image_infos_count,
- DYLDImageInfo::collection &image_infos)
+ ImageInfo::collection &image_infos)
{
- const ByteOrder endian = m_dyld.GetByteOrder();
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ const ByteOrder endian = GetByteOrderFromMagic (m_dyld.header.magic);
const uint32_t addr_size = m_dyld.GetAddressByteSize();
image_infos.resize(image_infos_count);
@@ -1240,7 +758,8 @@ DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
if (m_process->GetStopID() == m_dyld_image_infos_stop_id
|| m_dyld_image_infos.size() != 0)
return false;
@@ -1275,7 +794,7 @@ DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
Target &target = m_process->GetTarget();
const ModuleList &target_modules = target.GetImages();
ModuleList not_loaded_modules;
- Mutex::Locker modules_locker(target_modules.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
size_t num_modules = target_modules.GetSize();
for (size_t i = 0; i < num_modules; i++)
@@ -1381,7 +900,7 @@ DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_he
// Parse the load commands for an image
//----------------------------------------------------------------------
uint32_t
-DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
+DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, ImageInfo& dylib_info, FileSpec *lc_id_dylinker)
{
lldb::offset_t offset = 0;
uint32_t cmd_idx;
@@ -1478,7 +997,7 @@ DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImage
//----------------------------------------------------------------------
void
-DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos,
+DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
uint32_t infos_count,
bool update_executable)
{
@@ -1505,7 +1024,7 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::co
if (exe_idx < image_infos.size())
{
const bool can_create = true;
- ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], can_create, NULL));
+ ModuleSP exe_module_sp (FindTargetModuleForImageInfo (image_infos[exe_idx], can_create, NULL));
if (exe_module_sp)
{
@@ -1521,7 +1040,7 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::co
// so we first try and see if we already have a weak pointer to the
// dyld module, make it into a shared pointer, then add the executable,
// then re-add it back to make sure it is always in the list.
- ModuleSP dyld_module_sp(m_dyld_module_wp.lock());
+ ModuleSP dyld_module_sp(GetDYLDModule ());
const bool get_dependent_images = false;
m_process->GetTarget().SetExecutableModule (exe_module_sp,
@@ -1531,6 +1050,8 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::co
{
if(target.GetImages().AppendIfNeeded (dyld_module_sp))
{
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+
// Also add it to the section list.
UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
}
@@ -1540,133 +1061,6 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::co
}
}
-//----------------------------------------------------------------------
-// On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch
-// functions written in hand-written assembly, and also have hand-written unwind
-// information in the eh_frame section. Normally we prefer analyzing the
-// assembly instructions of a currently executing frame to unwind from that frame --
-// but on hand-written functions this profiling can fail. We should use the
-// eh_frame instructions for these functions all the time.
-//
-// As an aside, it would be better if the eh_frame entries had a flag (or were
-// extensible so they could have an Apple-specific flag) which indicates that
-// the instructions are asynchronous -- accurate at every instruction, instead
-// of our normal default assumption that they are not.
-//----------------------------------------------------------------------
-
-bool
-DynamicLoaderMacOSXDYLD::AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
-{
- ModuleSP module_sp;
- if (sym_ctx.symbol)
- {
- module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
- }
- if (module_sp.get() == NULL && sym_ctx.function)
- {
- module_sp = sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
- }
- if (module_sp.get() == NULL)
- return false;
-
- ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
- if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary (module_sp))
- {
- return true;
- }
-
- return false;
-}
-
-
-
-//----------------------------------------------------------------------
-// Dump a Segment to the file handle provided.
-//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const
-{
- if (log)
- {
- if (slide == 0)
- log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
- name.AsCString(""),
- vmaddr + slide,
- vmaddr + slide + vmsize);
- else
- log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") slide = 0x%" PRIx64,
- name.AsCString(""),
- vmaddr + slide,
- vmaddr + slide + vmsize,
- slide);
- }
-}
-
-const DynamicLoaderMacOSXDYLD::Segment *
-DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const
-{
- const size_t num_segments = segments.size();
- for (size_t i=0; i<num_segments; ++i)
- {
- if (segments[i].name == name)
- return &segments[i];
- }
- return NULL;
-}
-
-
-//----------------------------------------------------------------------
-// Dump an image info structure to the file handle provided.
-//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const
-{
- if (log == NULL)
- return;
- const uint8_t *u = (const uint8_t *)uuid.GetBytes();
-
- if (address == LLDB_INVALID_ADDRESS)
- {
- if (u)
- {
- log->Printf("\t modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s' (UNLOADED)",
- mod_date,
- u[ 0], u[ 1], u[ 2], u[ 3],
- u[ 4], u[ 5], u[ 6], u[ 7],
- u[ 8], u[ 9], u[10], u[11],
- u[12], u[13], u[14], u[15],
- file_spec.GetPath().c_str());
- }
- else
- log->Printf("\t modtime=0x%8.8" PRIx64 " path='%s' (UNLOADED)",
- mod_date,
- file_spec.GetPath().c_str());
- }
- else
- {
- if (u)
- {
- log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s'",
- address,
- mod_date,
- u[ 0], u[ 1], u[ 2], u[ 3],
- u[ 4], u[ 5], u[ 6], u[ 7],
- u[ 8], u[ 9], u[10], u[11],
- u[12], u[13], u[14], u[15],
- file_spec.GetPath().c_str());
- }
- else
- {
- log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " path='%s'",
- address,
- mod_date,
- file_spec.GetPath().c_str());
-
- }
- for (uint32_t i=0; i<segments.size(); ++i)
- segments[i].PutToLog(log, slide);
- }
-}
//----------------------------------------------------------------------
// Dump the _dyld_all_image_infos members and all current image infos
@@ -1678,7 +1072,8 @@ DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const
if (log == NULL)
return;
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64 ", notify=0x%8.8" PRIx64 " }",
m_dyld_all_image_infos.version,
m_dyld_all_image_infos.dylib_info_count,
@@ -1694,15 +1089,6 @@ DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const
}
}
-void
-DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process)
-{
- DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
- Clear(true);
- m_process = process;
- m_process->GetTarget().ClearAllLoadedSections();
-}
-
bool
DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
{
@@ -1722,6 +1108,8 @@ DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
ModuleSP dyld_module_sp = m_dyld_module_wp.lock();
if (dyld_module_sp)
{
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+
UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld);
resolved = m_process->GetTarget().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr);
}
@@ -1739,229 +1127,6 @@ DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
return m_break_id != LLDB_INVALID_BREAK_ID;
}
-//----------------------------------------------------------------------
-// Member function that gets called when the process state changes.
-//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state)
-{
- DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state));
- switch (state)
- {
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
- case eStateInvalid:
- case eStateUnloaded:
- case eStateExited:
- case eStateDetached:
- Clear(false);
- break;
-
- case eStateStopped:
- // Keep trying find dyld and set our notification breakpoint each time
- // we stop until we succeed
- if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
- {
- if (NeedToLocateDYLD ())
- LocateDYLD ();
-
- SetNotificationBreakpoint ();
- }
- break;
-
- case eStateRunning:
- case eStateStepping:
- case eStateCrashed:
- case eStateSuspended:
- break;
- }
-}
-
-ThreadPlanSP
-DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
-{
- ThreadPlanSP thread_plan_sp;
- StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
- const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
- Symbol *current_symbol = current_context.symbol;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- TargetSP target_sp (thread.CalculateTarget());
-
- if (current_symbol != NULL)
- {
- std::vector<Address> addresses;
-
- if (current_symbol->IsTrampoline())
- {
- const ConstString &trampoline_name = current_symbol->GetMangled().GetName(current_symbol->GetLanguage(), Mangled::ePreferMangled);
-
- if (trampoline_name)
- {
- const ModuleList &images = target_sp->GetImages();
-
- SymbolContextList code_symbols;
- images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, code_symbols);
- size_t num_code_symbols = code_symbols.GetSize();
-
- if (num_code_symbols > 0)
- {
- for (uint32_t i = 0; i < num_code_symbols; i++)
- {
- SymbolContext context;
- AddressRange addr_range;
- if (code_symbols.GetContextAtIndex(i, context))
- {
- context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
- addresses.push_back(addr_range.GetBaseAddress());
- if (log)
- {
- addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
-
- log->Printf ("Found a trampoline target symbol at 0x%" PRIx64 ".", load_addr);
- }
- }
- }
- }
-
- SymbolContextList reexported_symbols;
- images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeReExported, reexported_symbols);
- size_t num_reexported_symbols = reexported_symbols.GetSize();
- if (num_reexported_symbols > 0)
- {
- for (uint32_t i = 0; i < num_reexported_symbols; i++)
- {
- SymbolContext context;
- if (reexported_symbols.GetContextAtIndex(i, context))
- {
- if (context.symbol)
- {
- Symbol *actual_symbol = context.symbol->ResolveReExportedSymbol(*target_sp.get());
- if (actual_symbol)
- {
- const Address actual_symbol_addr = actual_symbol->GetAddress();
- if (actual_symbol_addr.IsValid())
- {
- addresses.push_back(actual_symbol_addr);
- if (log)
- {
- lldb::addr_t load_addr = actual_symbol_addr.GetLoadAddress(target_sp.get());
- log->Printf ("Found a re-exported symbol: %s at 0x%" PRIx64 ".",
- actual_symbol->GetName().GetCString(), load_addr);
- }
- }
- }
- }
- }
- }
- }
-
- SymbolContextList indirect_symbols;
- images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver, indirect_symbols);
- size_t num_indirect_symbols = indirect_symbols.GetSize();
- if (num_indirect_symbols > 0)
- {
- for (uint32_t i = 0; i < num_indirect_symbols; i++)
- {
- SymbolContext context;
- AddressRange addr_range;
- if (indirect_symbols.GetContextAtIndex(i, context))
- {
- context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
- addresses.push_back(addr_range.GetBaseAddress());
- if (log)
- {
- addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
-
- log->Printf ("Found an indirect target symbol at 0x%" PRIx64 ".", load_addr);
- }
- }
- }
- }
- }
- }
- else if (current_symbol->GetType() == eSymbolTypeReExported)
- {
- // I am not sure we could ever end up stopped AT a re-exported symbol. But just in case:
-
- const Symbol *actual_symbol = current_symbol->ResolveReExportedSymbol(*(target_sp.get()));
- if (actual_symbol)
- {
- Address target_addr(actual_symbol->GetAddress());
- if (target_addr.IsValid())
- {
- if (log)
- log->Printf ("Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64 ".",
- current_symbol->GetName().GetCString(),
- actual_symbol->GetName().GetCString(),
- target_addr.GetLoadAddress(target_sp.get()));
- addresses.push_back (target_addr.GetLoadAddress(target_sp.get()));
-
- }
- }
- }
-
- if (addresses.size() > 0)
- {
- // First check whether any of the addresses point to Indirect symbols, and if they do, resolve them:
- std::vector<lldb::addr_t> load_addrs;
- for (Address address : addresses)
- {
- Symbol *symbol = address.CalculateSymbolContextSymbol();
- if (symbol && symbol->IsIndirect())
- {
- Error error;
- Address symbol_address = symbol->GetAddress();
- addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(&symbol_address, error);
- if (error.Success())
- {
- load_addrs.push_back(resolved_addr);
- if (log)
- log->Printf("ResolveIndirectFunction found resolved target for %s at 0x%" PRIx64 ".",
- symbol->GetName().GetCString(), resolved_addr);
- }
- }
- else
- {
- load_addrs.push_back(address.GetLoadAddress(target_sp.get()));
- }
-
- }
- thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, load_addrs, stop_others));
- }
- }
- else
- {
- if (log)
- log->Printf ("Could not find symbol for step through.");
- }
-
- return thread_plan_sp;
-}
-
-size_t
-DynamicLoaderMacOSXDYLD::FindEquivalentSymbols (lldb_private::Symbol *original_symbol,
- lldb_private::ModuleList &images,
- lldb_private::SymbolContextList &equivalent_symbols)
-{
- const ConstString &trampoline_name = original_symbol->GetMangled().GetName(original_symbol->GetLanguage(), Mangled::ePreferMangled);
- if (!trampoline_name)
- return 0;
-
- size_t initial_size = equivalent_symbols.GetSize();
-
- static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$";
- std::string equivalent_regex_buf("^");
- equivalent_regex_buf.append (trampoline_name.GetCString());
- equivalent_regex_buf.append (resolver_name_regex);
-
- RegularExpression equivalent_name_regex (equivalent_regex_buf.c_str());
- const bool append = true;
- images.FindSymbolsMatchingRegExAndType (equivalent_name_regex, eSymbolTypeCode, equivalent_symbols, append);
-
- return equivalent_symbols.GetSize() - initial_size;
-}
-
Error
DynamicLoaderMacOSXDYLD::CanLoadImage ()
{
@@ -2029,6 +1194,8 @@ DynamicLoaderMacOSXDYLD::GetPluginVersion()
uint32_t
DynamicLoaderMacOSXDYLD::AddrByteSize()
{
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+
switch (m_dyld.header.magic)
{
case llvm::MachO::MH_MAGIC:
@@ -2046,7 +1213,7 @@ DynamicLoaderMacOSXDYLD::AddrByteSize()
}
lldb::ByteOrder
-DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic (uint32_t magic)
+DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(uint32_t magic)
{
switch (magic)
{
@@ -2066,10 +1233,3 @@ DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic (uint32_t magic)
}
return lldb::eByteOrderInvalid;
}
-
-lldb::ByteOrder
-DynamicLoaderMacOSXDYLD::DYLDImageInfo::GetByteOrder()
-{
- return DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header.magic);
-}
-
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
index 8fd60d0b6ac7..637bd8640d24 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <vector>
+#include <mutex>
// Other libraries and framework includes
// Project includes
@@ -20,16 +21,17 @@
#include "lldb/Host/FileSpec.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/UUID.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/SafeMachO.h"
-class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoader
+#include "DynamicLoaderDarwin.h"
+
+class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoaderDarwin
{
public:
DynamicLoaderMacOSXDYLD(lldb_private::Process *process);
- ~DynamicLoaderMacOSXDYLD() override;
+ virtual ~DynamicLoaderMacOSXDYLD() override;
//------------------------------------------------------------------
// Static Functions
@@ -55,24 +57,9 @@ public:
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
- void
- DidAttach() override;
-
- void
- DidLaunch() override;
-
bool
ProcessDidExec() override;
- lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
-
- size_t
- FindEquivalentSymbols(lldb_private::Symbol *original_symbol,
- lldb_private::ModuleList &module_list,
- lldb_private::SymbolContextList &equivalent_symbols) override;
-
lldb_private::Error
CanLoadImage() override;
@@ -85,28 +72,21 @@ public:
uint32_t
GetPluginVersion() override;
- bool
- AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
-
protected:
void
- PrivateInitialize (lldb_private::Process *process);
+ PutToLog(lldb_private::Log *log) const;
void
- PrivateProcessStateChanged (lldb_private::Process *process,
- lldb::StateType state);
+ DoInitialImageFetch () override;
bool
- LocateDYLD ();
+ NeedToDoInitialImageFetch () override;
bool
- DidSetNotificationBreakpoint () const;
-
- void
- Clear (bool clear_process);
+ DidSetNotificationBreakpoint () override;
void
- PutToLog (lldb_private::Log *log) const;
+ DoClear () override;
bool
ReadDYLDInfoFromMemoryAndSetNotificationCallback (lldb::addr_t addr);
@@ -120,141 +100,15 @@ protected:
uint32_t
AddrByteSize();
- static lldb::ByteOrder
- GetByteOrderFromMagic (uint32_t magic);
-
bool
ReadMachHeader (lldb::addr_t addr,
llvm::MachO::mach_header *header,
lldb_private::DataExtractor *load_command_data);
- class Segment
- {
- public:
- Segment() :
- name(),
- vmaddr(LLDB_INVALID_ADDRESS),
- vmsize(0),
- fileoff(0),
- filesize(0),
- maxprot(0),
- initprot(0),
- nsects(0),
- flags(0)
- {
- }
-
- lldb_private::ConstString name;
- lldb::addr_t vmaddr;
- lldb::addr_t vmsize;
- lldb::addr_t fileoff;
- lldb::addr_t filesize;
- uint32_t maxprot;
- uint32_t initprot;
- uint32_t nsects;
- uint32_t flags;
-
- bool
- operator==(const Segment& rhs) const
- {
- return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
- }
-
- void
- PutToLog (lldb_private::Log *log,
- lldb::addr_t slide) const;
-
- };
-
- struct DYLDImageInfo
- {
- lldb::addr_t address; // Address of mach header for this dylib
- lldb::addr_t slide; // The amount to slide all segments by if there is a global slide.
- lldb::addr_t mod_date; // Modification date for this dylib
- lldb_private::FileSpec file_spec; // Resolved path for this dylib
- lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
- llvm::MachO::mach_header header; // The mach header for this image
- std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior)
- uint32_t load_stop_id; // The process stop ID that the sections for this image were loaded
-
- DYLDImageInfo() :
- address(LLDB_INVALID_ADDRESS),
- slide(0),
- mod_date(0),
- file_spec(),
- uuid(),
- header(),
- segments(),
- load_stop_id(0)
- {
- }
-
- void
- Clear(bool load_cmd_data_only)
- {
- if (!load_cmd_data_only)
- {
- address = LLDB_INVALID_ADDRESS;
- slide = 0;
- mod_date = 0;
- file_spec.Clear();
- ::memset (&header, 0, sizeof(header));
- }
- uuid.Clear();
- segments.clear();
- load_stop_id = 0;
- }
-
- bool
- operator == (const DYLDImageInfo& rhs) const
- {
- return address == rhs.address
- && slide == rhs.slide
- && mod_date == rhs.mod_date
- && file_spec == rhs.file_spec
- && uuid == rhs.uuid
- && memcmp(&header, &rhs.header, sizeof(header)) == 0
- && segments == rhs.segments;
- }
-
- bool
- UUIDValid() const
- {
- return uuid.IsValid();
- }
-
- uint32_t
- GetAddressByteSize ()
- {
- if (header.cputype)
- {
- if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
- return 8;
- else
- return 4;
- }
- return 0;
- }
-
- lldb::ByteOrder
- GetByteOrder();
-
- lldb_private::ArchSpec
- GetArchitecture () const
- {
- return lldb_private::ArchSpec (lldb_private::eArchTypeMachO, header.cputype, header.cpusubtype);
- }
-
- const Segment *
- FindSegment (const lldb_private::ConstString &name) const;
-
- void
- PutToLog (lldb_private::Log *log) const;
-
- typedef std::vector<DYLDImageInfo> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
- };
+ uint32_t
+ ParseLoadCommands (const lldb_private::DataExtractor& data,
+ ImageInfo& dylib_info,
+ lldb_private::FileSpec *lc_id_dylinker);
struct DYLDAllImageInfos
{
@@ -296,38 +150,14 @@ protected:
}
};
- void
- RegisterNotificationCallbacks();
-
- void
- UnregisterNotificationCallbacks();
-
- uint32_t
- ParseLoadCommands (const lldb_private::DataExtractor& data,
- DYLDImageInfo& dylib_info,
- lldb_private::FileSpec *lc_id_dylinker);
-
- bool
- UpdateImageLoadAddress(lldb_private::Module *module,
- DYLDImageInfo& info);
-
- bool
- UnloadImageLoadAddress (lldb_private::Module *module,
- DYLDImageInfo& info);
-
- lldb::ModuleSP
- FindTargetModuleForDYLDImageInfo (DYLDImageInfo &image_info,
- bool can_create,
- bool *did_create_ptr);
-
- DYLDImageInfo *
- GetImageInfo (lldb_private::Module *module);
+ static lldb::ByteOrder
+ GetByteOrderFromMagic(uint32_t magic);
bool
- NeedToLocateDYLD () const;
+ SetNotificationBreakpoint () override;
- bool
- SetNotificationBreakpoint ();
+ void
+ ClearNotificationBreakpoint () override;
// There is a little tricky bit where you might initially attach while dyld is updating
// the all_image_infos, and you can't read the infos, so you have to continue and pick it
@@ -344,38 +174,26 @@ protected:
ReadAllImageInfosStructure ();
bool
- AddModulesUsingInfosFromDebugserver (lldb_private::StructuredData::ObjectSP image_details, DYLDImageInfo::collection &image_infos);
-
- bool
AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
bool
- AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos);
-
- bool
RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
void
- UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos,
+ UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
uint32_t infos_count,
bool update_executable);
bool
ReadImageInfos (lldb::addr_t image_infos_addr,
uint32_t image_infos_count,
- DYLDImageInfo::collection &image_infos);
-
+ ImageInfo::collection &image_infos);
- DYLDImageInfo m_dyld; // Info about the current dyld being used
- lldb::ModuleWP m_dyld_module_wp;
lldb::addr_t m_dyld_all_image_infos_addr;
DYLDAllImageInfos m_dyld_all_image_infos;
uint32_t m_dyld_all_image_infos_stop_id;
lldb::user_id_t m_break_id;
- DYLDImageInfo::collection m_dyld_image_infos; // Current shared libraries information
- uint32_t m_dyld_image_infos_stop_id; // The process stop ID that "m_dyld_image_infos" is valid for
- mutable lldb_private::Mutex m_mutex;
- lldb_private::Process::Notifications m_notification_callbacks;
+ mutable std::recursive_mutex m_mutex;
bool m_process_image_addr_is_all_images_infos;
private:
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/Makefile b/source/Plugins/DynamicLoader/MacOSX-DYLD/Makefile
deleted file mode 100644
index ffac3b457179..000000000000
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Disassembler/llvm/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginDynamicLoaderMacOSXDYLD
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 6ba7b470d743..6515c02f37e0 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -599,9 +599,10 @@ DynamicLoaderPOSIXDYLD::GetEntryPoint()
}
lldb::addr_t
-DynamicLoaderPOSIXDYLD::GetThreadLocalData (const lldb::ModuleSP module, const lldb::ThreadSP thread)
+DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp, const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr)
{
- auto it = m_loaded_modules.find (module);
+ auto it = m_loaded_modules.find (module_sp);
if (it == m_loaded_modules.end())
return LLDB_INVALID_ADDRESS;
@@ -634,14 +635,16 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData (const lldb::ModuleSP module, const l
addr_t dtv_slot = dtv + metadata.dtv_slot_size*modid;
addr_t tls_block = ReadPointer (dtv_slot + metadata.tls_offset);
- Module *mod = module.get();
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",
- mod->GetObjectName().AsCString(""), link_map, tp, (int64_t)modid, tls_block);
+ module_sp->GetObjectName().AsCString(""), link_map, tp, (int64_t)modid, tls_block);
- return tls_block;
+ if (tls_block == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+ else
+ return tls_block + tls_file_addr;
}
void
@@ -656,7 +659,7 @@ DynamicLoaderPOSIXDYLD::ResolveExecutableModule (lldb::ModuleSP &module_sp)
const auto platform_sp = target.GetPlatform ();
ProcessInstanceInfo process_info;
- if (!platform_sp->GetProcessInfo (m_process->GetID (), process_info))
+ if (!m_process->GetProcessInfo(process_info))
{
if (log)
log->Printf ("DynamicLoaderPOSIXDYLD::%s - failed to get process info for pid %" PRIu64,
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
index cb97bbf43ba9..890808c5179c 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
@@ -61,7 +61,7 @@ public:
CanLoadImage() override;
lldb::addr_t
- GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread) override;
+ GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override;
//------------------------------------------------------------------
// PluginInterface protocol
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/Makefile b/source/Plugins/DynamicLoader/POSIX-DYLD/Makefile
deleted file mode 100644
index 1c56366015d6..000000000000
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/DynamicLoader/POSIX-DYLD/Makefile ----*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginDynamicLoaderPosixDYLD
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
index 86cf45013a4d..daa21adf3a95 100644
--- a/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
+++ b/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
@@ -102,8 +102,8 @@ DynamicLoaderStatic::LoadAllImagesAtFileAddresses ()
// Disable JIT for static dynamic loader targets
m_process->SetCanJIT(false);
- Mutex::Locker mutex_locker(module_list.GetMutex());
-
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
+
const size_t num_modules = module_list.GetSize();
for (uint32_t idx = 0; idx < num_modules; ++idx)
{
diff --git a/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h b/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
index a7fdf4d22165..67694c96025c 100644
--- a/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
+++ b/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
@@ -17,7 +17,6 @@
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Core/UUID.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/Process.h"
class DynamicLoaderStatic : public lldb_private::DynamicLoader
diff --git a/source/Plugins/DynamicLoader/Static/Makefile b/source/Plugins/DynamicLoader/Static/Makefile
deleted file mode 100644
index 63972dfc5512..000000000000
--- a/source/Plugins/DynamicLoader/Static/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/DynamicLoader/Static/Makefile --------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginDynamicLoaderStatic
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/Makefile b/source/Plugins/DynamicLoader/Windows-DYLD/Makefile
deleted file mode 100644
index bf62aee30b2b..000000000000
--- a/source/Plugins/DynamicLoader/Windows-DYLD/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/DynamicLoader/Windows-DYLD/Makefile --*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginDynamicLoaderWindowsDYLD
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp b/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
index 976310610f51..0b8199481158 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
@@ -11,6 +11,7 @@
#include "lldb/Core/Log.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompilerType.h"
#include "llvm/Support/raw_ostream.h"
@@ -83,7 +84,7 @@ ASTDumper::ASTDumper (lldb::opaque_compiler_type_t type)
ASTDumper::ASTDumper (const CompilerType &compiler_type)
{
- m_dump = ClangASTContext::GetQualType(compiler_type).getAsString();
+ m_dump = ClangUtil::GetQualType(compiler_type).getAsString();
}
diff --git a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index 02505bde240c..f1231572e263 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -11,6 +11,11 @@
#include "ClangPersistentVariables.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangASTImporter.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "stdlib.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
@@ -23,22 +28,18 @@
#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
-#include "lldb/Target/Target.h"
using namespace llvm;
using namespace clang;
using namespace lldb_private;
-ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough,
- Target &target) :
- m_ast_context (NULL),
- m_passthrough (passthrough),
- m_passthrough_sema (NULL),
- m_target (target),
- m_sema (NULL)
+ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough, bool top_level, Target &target)
+ : m_ast_context(NULL),
+ m_passthrough(passthrough),
+ m_passthrough_sema(NULL),
+ m_target(target),
+ m_sema(NULL),
+ m_top_level(top_level)
{
if (!m_passthrough)
return;
@@ -76,6 +77,10 @@ ASTResultSynthesizer::TransformTopLevelDecl(Decl* D)
log->Printf("TransformTopLevelDecl(<complex>)");
}
+ if (m_top_level)
+ {
+ RecordPersistentDecl(named_decl);
+ }
}
if (LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D))
@@ -89,22 +94,23 @@ ASTResultSynthesizer::TransformTopLevelDecl(Decl* D)
TransformTopLevelDecl(*decl_iterator);
}
}
- else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
+ else if (!m_top_level)
{
- if (m_ast_context &&
- !method_decl->getSelector().getAsString().compare("$__lldb_expr:"))
+ if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
{
- RecordPersistentTypes(method_decl);
- SynthesizeObjCMethodResult(method_decl);
+ if (m_ast_context && !method_decl->getSelector().getAsString().compare("$__lldb_expr:"))
+ {
+ RecordPersistentTypes(method_decl);
+ SynthesizeObjCMethodResult(method_decl);
+ }
}
- }
- else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D))
- {
- if (m_ast_context &&
- !function_decl->getNameInfo().getAsString().compare("$__lldb_expr"))
+ else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D))
{
- RecordPersistentTypes(function_decl);
- SynthesizeFunctionResult(function_decl);
+ if (m_ast_context && !function_decl->getNameInfo().getAsString().compare("$__lldb_expr"))
+ {
+ RecordPersistentTypes(function_decl);
+ SynthesizeFunctionResult(function_decl);
+ }
}
}
}
@@ -365,8 +371,10 @@ ASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body,
return false;
ExprResult address_of_expr = m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr);
-
- m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true, false);
+ if (address_of_expr.get())
+ m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true, false);
+ else
+ return false;
}
else
{
@@ -457,14 +465,66 @@ ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D)
ConstString name_cs(name.str().c_str());
if (log)
- log->Printf ("Recording persistent type %s\n", name_cs.GetCString());
+ log->Printf("Recording persistent type %s\n", name_cs.GetCString());
- Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(m_target.GetScratchClangASTContext()->getASTContext(),
- m_ast_context,
- D);
+ m_decls.push_back(D);
+}
- if (TypeDecl *TypeDecl_scratch = dyn_cast<TypeDecl>(D_scratch))
- llvm::cast<ClangPersistentVariables>(m_target.GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))->RegisterPersistentType(name_cs, TypeDecl_scratch);
+void
+ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D)
+{
+ lldbassert(m_top_level);
+
+ if (!D->getIdentifier())
+ return;
+
+ StringRef name = D->getName();
+
+ if (name.size() == 0)
+ return;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ ConstString name_cs(name.str().c_str());
+
+ if (log)
+ log->Printf("Recording persistent decl %s\n", name_cs.GetCString());
+
+ m_decls.push_back(D);
+}
+
+void
+ASTResultSynthesizer::CommitPersistentDecls()
+{
+ for (clang::NamedDecl *decl : m_decls)
+ {
+ StringRef name = decl->getName();
+ ConstString name_cs(name.str().c_str());
+
+ Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(
+ m_target.GetScratchClangASTContext()->getASTContext(), m_ast_context, decl);
+
+ if (!D_scratch)
+ {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ {
+ std::string s;
+ llvm::raw_string_ostream ss(s);
+ decl->dump(ss);
+ ss.flush();
+
+ log->Printf("Couldn't commit persistent decl: %s\n", s.c_str());
+ }
+
+ continue;
+ }
+
+ if (NamedDecl *NamedDecl_scratch = dyn_cast<NamedDecl>(D_scratch))
+ llvm::cast<ClangPersistentVariables>(m_target.GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))
+ ->RegisterPersistentDecl(name_cs, NamedDecl_scratch);
+ }
}
void
diff --git a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
index 9f7bbe05b082..4556713e9933 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
+++ b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
@@ -41,13 +41,16 @@ public:
/// pass to the next step in the chain after processing. Passthrough is
/// the next ASTConsumer, or NULL if none is required.
///
+ /// @param[in] top_level
+ /// If true, register all top-level Decls and don't try to handle the
+ /// main function.
+ ///
/// @param[in] target
/// The target, which contains the persistent variable store and the
/// AST importer.
//----------------------------------------------------------------------
- ASTResultSynthesizer(clang::ASTConsumer *passthrough,
- Target &target);
-
+ ASTResultSynthesizer(clang::ASTConsumer *passthrough, bool top_level, Target &target);
+
//----------------------------------------------------------------------
/// Destructor
//----------------------------------------------------------------------
@@ -106,11 +109,18 @@ public:
/// casts it to an Action for actual use.
//----------------------------------------------------------------------
void InitializeSema(clang::Sema &S) override;
-
+
//----------------------------------------------------------------------
/// Reset the Sema to NULL now that transformations are done
//----------------------------------------------------------------------
- void ForgetSema() override;
+ void
+ ForgetSema() override;
+
+ //----------------------------------------------------------------------
+ /// The parse has succeeded, so record its persistent decls
+ //----------------------------------------------------------------------
+ void
+ CommitPersistentDecls();
private:
//----------------------------------------------------------------------
@@ -171,13 +181,30 @@ private:
/// @param[in] Body
/// The body of the function.
//----------------------------------------------------------------------
- void MaybeRecordPersistentType(clang::TypeDecl *D);
-
- clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
- clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
- clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
- Target &m_target; ///< The target, which contains the persistent variable store and the
- clang::Sema *m_sema; ///< The Sema to use.
+ void
+ MaybeRecordPersistentType(clang::TypeDecl *D);
+
+ //----------------------------------------------------------------------
+ /// Given a NamedDecl, register it as a pointer type in the target's scratch
+ /// AST context.
+ ///
+ /// @param[in] Body
+ /// The body of the function.
+ //----------------------------------------------------------------------
+ void
+ RecordPersistentDecl(clang::NamedDecl *D);
+
+ clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
+ clang::ASTConsumer
+ *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
+ clang::SemaConsumer
+ *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
+
+ std::vector<clang::NamedDecl *> m_decls; ///< Persistent declarations to register assuming the expression succeeds.
+
+ Target &m_target; ///< The target, which contains the persistent variable store and the
+ clang::Sema *m_sema; ///< The Sema to use.
+ bool m_top_level;
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index d2ea4390560a..def0d42d32dd 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -12,18 +12,20 @@
#include "ASTDumper.h"
#include "ClangModulesDeclVendor.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/RecordLayout.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
#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/ObjCLanguageRuntime.h"
#include "lldb/Target/Target.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
#include <vector>
@@ -273,10 +275,10 @@ ClangASTSource::CompleteType (TagDecl *tag_decl)
CompilerType clang_type (type->GetFullCompilerType ());
- if (!clang_type)
+ if (!ClangUtil::IsClangType(clang_type))
continue;
- const TagType *tag_type = ClangASTContext::GetQualType(clang_type)->getAs<TagType>();
+ const TagType *tag_type = ClangUtil::GetQualType(clang_type)->getAs<TagType>();
if (!tag_type)
continue;
@@ -299,7 +301,8 @@ ClangASTSource::CompleteType (TagDecl *tag_decl)
const ModuleList &module_list = m_target->GetImages();
bool exact_match = false;
- module_list.FindTypes (null_sc, name, exact_match, UINT32_MAX, types);
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ module_list.FindTypes (null_sc, name, exact_match, UINT32_MAX, searched_symbol_files, types);
for (uint32_t ti = 0, te = types.GetSize();
ti != te && !found;
@@ -312,10 +315,10 @@ ClangASTSource::CompleteType (TagDecl *tag_decl)
CompilerType clang_type (type->GetFullCompilerType ());
- if (!clang_type)
+ if (!ClangUtil::IsClangType(clang_type))
continue;
- const TagType *tag_type = ClangASTContext::GetQualType(clang_type)->getAs<TagType>();
+ const TagType *tag_type = ClangUtil::GetQualType(clang_type)->getAs<TagType>();
if (!tag_type)
continue;
@@ -705,7 +708,7 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
else
{
const ModuleList &target_images = m_target->GetImages();
- Mutex::Locker modules_locker (target_images.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
{
@@ -740,16 +743,17 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
do
{
+ if (context.m_found.type)
+ break;
+
TypeList types;
SymbolContext null_sc;
const bool exact_match = false;
-
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
if (module_sp && namespace_decl)
module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types);
else
- m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, types);
-
- bool found_a_type = false;
+ m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, searched_symbol_files, types);
if (size_t num_types = types.GetSize())
{
@@ -782,12 +786,12 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
context.AddTypeDecl(copied_clang_type);
- found_a_type = true;
+ context.m_found.type = true;
break;
}
}
- if (!found_a_type)
+ if (!context.m_found.type)
{
// Try the modules next.
@@ -832,13 +836,13 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
context.AddNamedDecl(copied_named_decl);
- found_a_type = true;
+ context.m_found.type = true;
}
}
} while (0);
}
- if (!found_a_type)
+ if (!context.m_found.type)
{
do
{
@@ -1378,7 +1382,7 @@ FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id,
StringRef name(name_str.c_str());
IdentifierInfo &name_identifier(origin_iface_decl->getASTContext().Idents.get(name));
- DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier));
+ DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier, ObjCPropertyQueryKind::OBJC_PR_query_instance));
bool found = false;
@@ -1823,7 +1827,7 @@ ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespac
else
{
const ModuleList &target_images = m_target->GetImages();
- Mutex::Locker modules_locker(target_images.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
CompilerDeclContext null_namespace_decl;
@@ -1903,7 +1907,8 @@ ClangASTSource::GuardedCopyType (const CompilerType &src_type)
SetImportInProgress(true);
- QualType copied_qual_type = m_ast_importer_sp->CopyType (m_ast_context, src_ast->getASTContext(), ClangASTContext::GetQualType(src_type));
+ QualType copied_qual_type =
+ m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(), ClangUtil::GetQualType(src_type));
SetImportInProgress(false);
@@ -1931,14 +1936,8 @@ NameSearchContext::AddVarDecl(const CompilerType &type)
clang::ASTContext *ast = lldb_ast->getASTContext();
- clang::NamedDecl *Decl = VarDecl::Create(*ast,
- const_cast<DeclContext*>(m_decl_context),
- SourceLocation(),
- SourceLocation(),
- ii,
- ClangASTContext::GetQualType(type),
- 0,
- SC_Static);
+ clang::NamedDecl *Decl = VarDecl::Create(*ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
+ SourceLocation(), ii, ClangUtil::GetQualType(type), 0, SC_Static);
m_decls.push_back(Decl);
return Decl;
@@ -1961,7 +1960,7 @@ NameSearchContext::AddFunDecl (const CompilerType &type, bool extern_c)
m_function_types.insert(type);
- QualType qual_type (ClangASTContext::GetQualType(type));
+ QualType qual_type(ClangUtil::GetQualType(type));
clang::ASTContext *ast = lldb_ast->getASTContext();
@@ -2055,9 +2054,9 @@ NameSearchContext::AddGenericFunDecl()
clang::NamedDecl *
NameSearchContext::AddTypeDecl(const CompilerType &clang_type)
{
- if (clang_type)
+ if (ClangUtil::IsClangType(clang_type))
{
- QualType qual_type = ClangASTContext::GetQualType(clang_type);
+ QualType qual_type = ClangUtil::GetQualType(clang_type);
if (const TypedefType *typedef_type = llvm::dyn_cast<TypedefType>(qual_type))
{
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
index bb6384721f51..13791d7e627f 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -430,6 +430,8 @@ struct NameSearchContext {
bool variable : 1;
bool function_with_type_info : 1;
bool function : 1;
+ bool local_vars_nsp : 1;
+ bool type : 1;
} m_found;
//------------------------------------------------------------------
diff --git a/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h b/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
new file mode 100644
index 000000000000..8273bca105cc
--- /dev/null
+++ b/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
@@ -0,0 +1,60 @@
+//===-- ClangDiagnostic.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_ClangDiagnostic_h
+#define lldb_ClangDiagnostic_h
+
+#include <vector>
+
+#include "clang/Basic/Diagnostic.h"
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-types.h"
+
+#include "lldb/Expression/DiagnosticManager.h"
+
+namespace lldb_private
+{
+
+
+class ClangDiagnostic : public Diagnostic
+{
+public:
+ typedef std::vector<clang::FixItHint> FixItList;
+
+ static inline bool classof(const ClangDiagnostic *) { return true; }
+ static inline bool classof(const Diagnostic *diag) {
+ return diag->getKind() == eDiagnosticOriginClang;
+ }
+
+ ClangDiagnostic(const char *message, DiagnosticSeverity severity, uint32_t compiler_id) :
+ Diagnostic(message, severity, eDiagnosticOriginClang, compiler_id)
+ {
+ }
+
+ virtual ~ClangDiagnostic() = default;
+
+ bool HasFixIts () const override { return !m_fixit_vec.empty(); }
+
+ void
+ AddFixitHint (const clang::FixItHint &fixit)
+ {
+ m_fixit_vec.push_back(fixit);
+ }
+
+ const FixItList &
+ FixIts() const
+ {
+ return m_fixit_vec;
+ }
+ FixItList m_fixit_vec;
+};
+
+} // namespace lldb_private
+#endif /* lldb_ClangDiagnostic_h */
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index f4d6b195c7f0..7aeff6e964fe 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -57,6 +57,11 @@ using namespace lldb;
using namespace lldb_private;
using namespace clang;
+namespace
+{
+ const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";
+} // anonymous namespace
+
ClangExpressionDeclMap::ClangExpressionDeclMap (bool keep_result_in_memory,
Materializer::PersistentVariableDelegate *result_delegate,
ExecutionContext &exe_ctx) :
@@ -510,248 +515,6 @@ ClangExpressionDeclMap::GetFunctionInfo
return true;
}
-static void
-FindCodeSymbolInContext
-(
- const ConstString &name,
- SymbolContext &sym_ctx,
- uint32_t name_type_mask,
- SymbolContextList &sc_list
-)
-{
- sc_list.Clear();
- SymbolContextList temp_sc_list;
- if (sym_ctx.module_sp)
- sym_ctx.module_sp->FindFunctions(name,
- NULL,
- name_type_mask,
- true, // include_symbols
- false, // include_inlines
- true, // append
- temp_sc_list);
- if (temp_sc_list.GetSize() == 0)
- {
- if (sym_ctx.target_sp)
- sym_ctx.target_sp->GetImages().FindFunctions(name,
- name_type_mask,
- true, // include_symbols
- false, // include_inlines
- true, // append
- temp_sc_list);
- }
-
- SymbolContextList internal_symbol_sc_list;
- unsigned temp_sc_list_size = temp_sc_list.GetSize();
- for (unsigned i = 0; i < temp_sc_list_size; i++)
- {
- SymbolContext sc;
- temp_sc_list.GetContextAtIndex(i, sc);
- if (sc.function)
- {
- sc_list.Append(sc);
- }
- else if (sc.symbol)
- {
- if (sc.symbol->IsExternal())
- {
- sc_list.Append(sc);
- }
- else
- {
- internal_symbol_sc_list.Append(sc);
- }
- }
- }
-
- // If we had internal symbols and we didn't find any external symbols or
- // functions in debug info, then fallback to the internal symbols
- if (sc_list.GetSize() == 0 && internal_symbol_sc_list.GetSize())
- {
- sc_list = internal_symbol_sc_list;
- }
-}
-
-ConstString
-FindBestAlternateMangledName
-(
- const ConstString &demangled,
- const LanguageType &lang_type,
- SymbolContext &sym_ctx
-)
-{
- CPlusPlusLanguage::MethodName cpp_name(demangled);
- std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();
-
- if (!scope_qualified_name.size())
- return ConstString();
-
- if (!sym_ctx.module_sp)
- return ConstString();
-
- SymbolVendor *sym_vendor = sym_ctx.module_sp->GetSymbolVendor();
- if (!sym_vendor)
- return ConstString();
-
- lldb_private::SymbolFile *sym_file = sym_vendor->GetSymbolFile();
- if (!sym_file)
- return ConstString();
-
- std::vector<ConstString> alternates;
- sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);
-
- std::vector<ConstString> param_and_qual_matches;
- std::vector<ConstString> param_matches;
- for (size_t i = 0; i < alternates.size(); i++)
- {
- ConstString alternate_mangled_name = alternates[i];
- Mangled mangled(alternate_mangled_name, true);
- ConstString demangled = mangled.GetDemangledName(lang_type);
-
- CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
- if (!cpp_name.IsValid())
- continue;
-
- if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments())
- {
- if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
- param_and_qual_matches.push_back(alternate_mangled_name);
- else
- param_matches.push_back(alternate_mangled_name);
- }
- }
-
- if (param_and_qual_matches.size())
- return param_and_qual_matches[0]; // It is assumed that there will be only one!
- else if (param_matches.size())
- return param_matches[0]; // Return one of them as a best match
- else
- return ConstString();
-}
-
-bool
-ClangExpressionDeclMap::GetFunctionAddress
-(
- const ConstString &name,
- uint64_t &func_addr
-)
-{
- assert (m_parser_vars.get());
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
- Target *target = exe_ctx.GetTargetPtr();
- // Back out in all cases where we're not fully initialized
- if (target == NULL)
- return false;
- if (!m_parser_vars->m_sym_ctx.target_sp)
- return false;
-
- SymbolContextList sc_list;
-
- FindCodeSymbolInContext(name, m_parser_vars->m_sym_ctx, eFunctionNameTypeAuto, sc_list);
-
- uint32_t sc_list_size = sc_list.GetSize();
-
- if (sc_list_size == 0)
- {
- SymbolContext &sc = m_parser_vars->m_sym_ctx;
- if (sc.comp_unit)
- {
- LanguageType lang_type = sc.comp_unit->GetLanguage();
- if (Language::LanguageIsCPlusPlus(lang_type) &&
- CPlusPlusLanguage::IsCPPMangledName(name.AsCString()))
- {
- Mangled mangled(name, true);
- ConstString demangled = mangled.GetDemangledName(lang_type);
-
- if (demangled)
- {
- ConstString best_alternate_mangled_name = FindBestAlternateMangledName(demangled, lang_type, sc);
- if (best_alternate_mangled_name)
- {
- FindCodeSymbolInContext(
- best_alternate_mangled_name, m_parser_vars->m_sym_ctx, eFunctionNameTypeAuto, sc_list);
- sc_list_size = sc_list.GetSize();
- }
-
- if (sc_list_size == 0)
- {
- FindCodeSymbolInContext(
- demangled, m_parser_vars->m_sym_ctx, eFunctionNameTypeFull, sc_list);
- sc_list_size = sc_list.GetSize();
- }
- }
- }
- }
- }
-
- if (sc_list_size == 0)
- {
- // We occasionally get debug information in which a const function is reported
- // as non-const, so the mangled name is wrong. This is a hack to compensate.
-
- if (!strncmp(name.GetCString(), "_ZN", 3) &&
- strncmp(name.GetCString(), "_ZNK", 4))
- {
- std::string fixed_scratch("_ZNK");
- fixed_scratch.append(name.GetCString() + 3);
- ConstString fixed_name(fixed_scratch.c_str());
-
- if (log)
- log->Printf("Failed to find symbols given non-const name %s; trying %s", name.GetCString(), fixed_name.GetCString());
-
- FindCodeSymbolInContext(
- fixed_name, m_parser_vars->m_sym_ctx, eFunctionNameTypeAuto, sc_list);
- sc_list_size = sc_list.GetSize();
- }
- }
-
- lldb::addr_t intern_callable_load_addr = LLDB_INVALID_ADDRESS;
-
- for (uint32_t i=0; i<sc_list_size; ++i)
- {
- SymbolContext sym_ctx;
- sc_list.GetContextAtIndex(i, sym_ctx);
-
-
- lldb::addr_t callable_load_addr = LLDB_INVALID_ADDRESS;
-
- if (sym_ctx.function)
- {
- const Address func_so_addr = sym_ctx.function->GetAddressRange().GetBaseAddress();
- if (func_so_addr.IsValid())
- {
- callable_load_addr = func_so_addr.GetCallableLoadAddress(target, false);
- }
- }
- else if (sym_ctx.symbol)
- {
- if (sym_ctx.symbol->IsExternal())
- callable_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target);
- else
- {
- if (intern_callable_load_addr == LLDB_INVALID_ADDRESS)
- intern_callable_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target);
- }
- }
-
- if (callable_load_addr != LLDB_INVALID_ADDRESS)
- {
- func_addr = callable_load_addr;
- return true;
- }
- }
-
- // See if we found an internal symbol
- if (intern_callable_load_addr != LLDB_INVALID_ADDRESS)
- {
- func_addr = intern_callable_load_addr;
- return true;
- }
-
- return false;
-}
-
addr_t
ClangExpressionDeclMap::GetSymbolAddress (Target &target,
Process *process,
@@ -1004,6 +767,24 @@ ClangExpressionDeclMap::FindGlobalVariable
return VariableSP();
}
+ClangASTContext *
+ClangExpressionDeclMap::GetClangASTContext ()
+{
+ StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
+ if (frame == nullptr)
+ return nullptr;
+
+ SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
+ if (sym_ctx.block == nullptr)
+ return nullptr;
+
+ CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
+ if (!frame_decl_context)
+ return nullptr;
+
+ return llvm::dyn_cast_or_null<ClangASTContext>(frame_decl_context.GetTypeSystem());
+}
+
// Interface for ClangASTSource
void
@@ -1039,6 +820,13 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context)
if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
{
+ if (namespace_context->getName().str() == std::string(g_lldb_local_vars_namespace_cstr))
+ {
+ CompilerDeclContext compiler_decl_ctx(GetClangASTContext(), const_cast<void *>(static_cast<const void *>(context.m_decl_context)));
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx, current_id);
+ return;
+ }
+
ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context);
if (log && log->GetVerbose())
@@ -1078,7 +866,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context)
current_id);
}
- if (!context.m_found.variable)
+ if (!context.m_found.variable && !context.m_found.local_vars_nsp)
ClangASTSource::FindExternalVisibleDecls(context);
}
@@ -1089,6 +877,17 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
unsigned int current_id)
{
assert (m_ast_context);
+
+ std::function<void (clang::FunctionDecl *)> MaybeRegisterFunctionBody =
+ [this](clang::FunctionDecl *copied_function_decl)
+ {
+ if (copied_function_decl->getBody() && m_parser_vars->m_code_gen)
+ {
+ DeclGroupRef decl_group_ref(copied_function_decl);
+ m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);
+ }
+ };
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
@@ -1114,6 +913,52 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
SymbolContext sym_ctx;
if (frame != nullptr)
sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
+
+ // Try the persistent decls, which take precedence over all else.
+ if (!namespace_decl)
+ {
+ do
+ {
+ if (!target)
+ break;
+
+ ClangASTContext *scratch_clang_ast_context = target->GetScratchClangASTContext();
+
+ if (!scratch_clang_ast_context)
+ break;
+
+ ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
+
+ if (!scratch_ast_context)
+ break;
+
+ NamedDecl *persistent_decl = m_parser_vars->m_persistent_vars->GetPersistentDecl(name);
+
+ if (!persistent_decl)
+ break;
+
+ Decl *parser_persistent_decl = m_ast_importer_sp->CopyDecl(m_ast_context, scratch_ast_context, persistent_decl);
+
+ if (!parser_persistent_decl)
+ break;
+
+ NamedDecl *parser_named_decl = dyn_cast<NamedDecl>(parser_persistent_decl);
+
+ if (!parser_named_decl)
+ break;
+
+ if (clang::FunctionDecl *parser_function_decl = llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl))
+ {
+ MaybeRegisterFunctionBody(parser_function_decl);
+ }
+
+ if (log)
+ log->Printf(" CEDM::FEVD[%u] Found persistent decl %s", current_id, name.GetCString());
+
+ context.AddNamedDecl(parser_named_decl);
+ } while (0);
+ }
+
if (name_unique_cstr[0] == '$' && !namespace_decl)
{
static ConstString g_lldb_class_name ("$__lldb_class");
@@ -1335,45 +1180,36 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
return;
}
- // any other $__lldb names should be weeded out now
- if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1))
- return;
-
- do
+ if (name == ConstString(g_lldb_local_vars_namespace_cstr))
{
- if (!target)
- break;
-
- ClangASTContext *scratch_clang_ast_context = target->GetScratchClangASTContext();
-
- if (!scratch_clang_ast_context)
- break;
-
- ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
-
- if (!scratch_ast_context)
- break;
-
- TypeDecl *ptype_type_decl = m_parser_vars->m_persistent_vars->GetPersistentType(name);
-
- if (!ptype_type_decl)
- break;
-
- Decl *parser_ptype_decl = m_ast_importer_sp->CopyDecl(m_ast_context, scratch_ast_context, ptype_type_decl);
+ CompilerDeclContext frame_decl_context = sym_ctx.block != nullptr ?
+ sym_ctx.block->GetDeclContext() :
+ CompilerDeclContext();
- if (!parser_ptype_decl)
- break;
-
- TypeDecl *parser_ptype_type_decl = dyn_cast<TypeDecl>(parser_ptype_decl);
+ if (frame_decl_context)
+ {
+ ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(frame_decl_context.GetTypeSystem());
- if (!parser_ptype_type_decl)
- break;
+ if (ast)
+ {
+ clang::NamespaceDecl *namespace_decl = ClangASTContext::GetUniqueNamespaceDeclaration(
+ m_ast_context, name_unique_cstr, nullptr);
+ if (namespace_decl)
+ {
+ context.AddNamedDecl(namespace_decl);
+ clang::DeclContext *clang_decl_ctx = clang::Decl::castToDeclContext(namespace_decl);
+ clang_decl_ctx->setHasExternalVisibleStorage(true);
+ context.m_found.local_vars_nsp = true;
+ }
+ }
+ }
- if (log)
- log->Printf(" CEDM::FEVD[%u] Found persistent type %s", current_id, name.GetCString());
+ return;
+ }
- context.AddNamedDecl(parser_ptype_type_decl);
- } while (0);
+ // any other $__lldb names should be weeded out now
+ if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1))
+ return;
ExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariable(name));
@@ -1403,24 +1239,37 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
ValueObjectSP valobj;
VariableSP var;
- if (frame && !namespace_decl)
+ bool local_var_lookup = !namespace_decl ||
+ (namespace_decl.GetName() == ConstString(g_lldb_local_vars_namespace_cstr));
+ if (frame && local_var_lookup)
{
CompilerDeclContext compiler_decl_context = sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext() : CompilerDeclContext();
if (compiler_decl_context)
{
- // Make sure that the variables are parsed so that we have the declarations
+ // Make sure that the variables are parsed so that we have the declarations.
VariableListSP vars = frame->GetInScopeVariableList(true);
for (size_t i = 0; i < vars->GetSize(); i++)
vars->GetVariableAtIndex(i)->GetDecl();
- // Search for declarations matching the name
- std::vector<CompilerDecl> found_decls = compiler_decl_context.FindDeclByName(name);
+ // Search for declarations matching the name. Do not include imported decls
+ // in the search if we are looking for decls in the artificial namespace
+ // $__lldb_local_vars.
+ std::vector<CompilerDecl> found_decls = compiler_decl_context.FindDeclByName(name, namespace_decl.IsValid());
bool variable_found = false;
for (CompilerDecl decl : found_decls)
{
- var = decl.GetAsVariable();
+ for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi)
+ {
+ VariableSP candidate_var = vars->GetVariableAtIndex(vi);
+ if (candidate_var->GetDecl() == decl)
+ {
+ var = candidate_var;
+ break;
+ }
+ }
+
if (var)
{
variable_found = true;
@@ -1663,9 +1512,12 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
{
if (llvm::isa<clang::FunctionDecl>(decl))
{
- clang::NamedDecl *copied_decl = llvm::cast<FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, &decl->getASTContext(), decl));
- context.AddNamedDecl(copied_decl);
- context.m_found.function_with_type_info = true;
+ clang::NamedDecl *copied_decl = llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, &decl->getASTContext(), decl));
+ if (copied_decl)
+ {
+ context.AddNamedDecl(copied_decl);
+ context.m_found.function_with_type_info = true;
+ }
}
}
}
@@ -1726,11 +1578,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
break;
}
- if (copied_function_decl->getBody() && m_parser_vars->m_code_gen)
- {
- DeclGroupRef decl_group_ref(copied_function_decl);
- m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);
- }
+ MaybeRegisterFunctionBody(copied_function_decl);
context.AddNamedDecl(copied_function_decl);
@@ -2208,6 +2056,54 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
if (function)
{
Type *function_type = function->GetType();
+
+ const lldb::LanguageType comp_unit_language = function->GetCompileUnit()->GetLanguage();
+ const bool extern_c = Language::LanguageIsC(comp_unit_language) ||
+ (Language::LanguageIsObjC(comp_unit_language) &&
+ !Language::LanguageIsCPlusPlus(comp_unit_language));
+
+ if (!extern_c)
+ {
+ TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
+ if (ClangASTContext *src_ast = llvm::dyn_cast<ClangASTContext>(type_system))
+ {
+ clang::DeclContext *src_decl_context = (clang::DeclContext*)function->GetDeclContext().GetOpaqueDeclContext();
+ clang::FunctionDecl *src_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);
+
+ if (src_function_decl)
+ {
+ if (clang::FunctionDecl *copied_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, src_ast->getASTContext(), src_function_decl)))
+ {
+ if (log)
+ {
+ ASTDumper ast_dumper((clang::Decl*)copied_function_decl);
+
+ StreamString ss;
+
+ function->DumpSymbolContext(&ss);
+
+ log->Printf(" CEDM::FEVD[%u] Imported decl for function %s (description %s), returned %s",
+ current_id,
+ copied_function_decl->getName().str().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());
+ }
+ }
+ }
+ }
+ }
if (!function_type)
{
@@ -2230,7 +2126,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
CompilerType copied_function_type = GuardedCopyType(function_clang_type);
if (copied_function_type)
{
- function_decl = context.AddFunDecl(copied_function_type);
+ function_decl = context.AddFunDecl(copied_function_type, extern_c);
if (!function_decl)
{
@@ -2329,10 +2225,10 @@ ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
{
CompilerType copied_clang_type = GuardedCopyType(ut);
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
if (!copied_clang_type)
{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
if (log)
log->Printf("ClangExpressionDeclMap::AddThisType - Couldn't import the type");
@@ -2349,7 +2245,7 @@ ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
&void_ptr_clang_type,
1,
false,
- copied_clang_type.GetTypeQualifiers());
+ 0);
const bool is_virtual = false;
const bool is_static = false;
@@ -2358,7 +2254,7 @@ ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
const bool is_attr_used = true;
const bool is_artificial = false;
- ClangASTContext::GetASTContext(m_ast_context)->
+ CXXMethodDecl *method_decl = ClangASTContext::GetASTContext(m_ast_context)->
AddMethodToCXXRecordType (copied_clang_type.GetOpaqueQualType(),
"$__lldb_expr",
method_type,
@@ -2369,6 +2265,16 @@ ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
is_explicit,
is_attr_used,
is_artificial);
+
+ if (log)
+ {
+ 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());
+ }
}
if (!copied_clang_type.IsValid())
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index b3f890c7acc7..537db71cfeb4 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -265,25 +265,6 @@ public:
uint64_t &ptr);
//------------------------------------------------------------------
- /// [Used by IRForTarget] Get the address of a function given nothing
- /// but its name. Some functions are needed but didn't get Decls made
- /// during parsing -- specifically, sel_registerName is never called
- /// in the generated IR but we need to call it nonetheless.
- ///
- /// @param[in] name
- /// The name of the function.
- ///
- /// @param[out] ptr
- /// The absolute address of the function in the target.
- ///
- /// @return
- /// True if the address could be retrieved; false otherwise.
- //------------------------------------------------------------------
- bool
- GetFunctionAddress (const ConstString &name,
- uint64_t &ptr);
-
- //------------------------------------------------------------------
/// [Used by IRForTarget] Get the address of a symbol given nothing
/// but its name.
///
@@ -707,6 +688,9 @@ private:
AddThisType(NameSearchContext &context,
TypeFromUser &type,
unsigned int current_id);
+
+ ClangASTContext *
+ GetClangASTContext();
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
index bb620def691f..bcd30ec4af2e 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
@@ -67,11 +67,14 @@ public:
/// the ASTs to after transformation.
//------------------------------------------------------------------
virtual clang::ASTConsumer *
- ASTTransformer (clang::ASTConsumer *passthrough) = 0;
-
+ ASTTransformer(clang::ASTConsumer *passthrough) = 0;
-protected:
+ virtual void
+ CommitPersistentDecls()
+ {
+ }
+protected:
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 72c33fec8105..d1a3c0dea825 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -11,13 +11,18 @@
// C++ Includes
// Other libraries and framework includes
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ExternalASTSource.h"
+#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/Version.h"
+#include "clang/Basic/Version.h"
#include "clang/CodeGen/CodeGenAction.h"
#include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Edit/Commit.h"
+#include "clang/Edit/EditsReceiver.h"
+#include "clang/Edit/EditedSource.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendActions.h"
@@ -28,6 +33,7 @@
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Rewrite/Frontend/FrontendActions.h"
+#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
@@ -37,7 +43,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/TargetSelect.h"
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wglobal-constructors"
#include "llvm/ExecutionEngine/MCJIT.h"
+#pragma clang diagnostic pop
+
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ErrorHandling.h"
@@ -48,6 +58,7 @@
// Project includes
#include "ClangExpressionParser.h"
+#include "ClangDiagnostic.h"
#include "ClangASTSource.h"
#include "ClangExpressionHelper.h"
@@ -65,17 +76,21 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Expression/IRExecutionUnit.h"
+#include "lldb/Core/StringList.h"
#include "lldb/Expression/IRDynamicChecks.h"
+#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Host/File.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Language.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadPlanCallFunction.h"
+#include "lldb/Utility/LLDBAssert.h"
using namespace clang;
using namespace llvm;
@@ -85,21 +100,6 @@ using namespace lldb_private;
// Utility Methods for Clang
//===----------------------------------------------------------------------===//
-std::string GetBuiltinIncludePath(const char *Argv0) {
- SmallString<128> P(llvm::sys::fs::getMainExecutable(
- Argv0, (void *)(intptr_t) GetBuiltinIncludePath));
-
- if (!P.empty()) {
- llvm::sys::path::remove_filename(P); // Remove /clang from foo/bin/clang
- llvm::sys::path::remove_filename(P); // Remove /bin from foo/bin
-
- // Get foo/lib/clang/<version>/include
- llvm::sys::path::append(P, "lib", "clang", CLANG_VERSION_STRING,
- "include");
- }
-
- return P.str();
-}
class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks
{
@@ -154,6 +154,100 @@ public:
}
};
+class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer
+{
+public:
+ ClangDiagnosticManagerAdapter() : m_passthrough(new clang::TextDiagnosticBuffer) {}
+
+ ClangDiagnosticManagerAdapter(const std::shared_ptr<clang::TextDiagnosticBuffer> &passthrough)
+ : m_passthrough(passthrough)
+ {
+ }
+
+ void
+ ResetManager(DiagnosticManager *manager = nullptr)
+ {
+ m_manager = manager;
+ }
+
+ void
+ HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info)
+ {
+ 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);
+ }
+ }
+ }
+ }
+
+ m_passthrough->HandleDiagnostic(DiagLevel, Info);
+ }
+
+ void
+ FlushDiagnostics(DiagnosticsEngine &Diags)
+ {
+ m_passthrough->FlushDiagnostics(Diags);
+ }
+
+ DiagnosticConsumer *
+ clone(DiagnosticsEngine &Diags) const
+ {
+ return new ClangDiagnosticManagerAdapter(m_passthrough);
+ }
+
+ clang::TextDiagnosticBuffer *
+ GetPassthrough()
+ {
+ return m_passthrough.get();
+ }
+
+private:
+ DiagnosticManager *m_manager = nullptr;
+ std::shared_ptr<clang::TextDiagnosticBuffer> m_passthrough;
+};
+
//===----------------------------------------------------------------------===//
// Implementation of ClangExpressionParser
//===----------------------------------------------------------------------===//
@@ -166,37 +260,78 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_code_generator (),
m_pp_callbacks(nullptr)
{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ // We can't compile expressions without a target. So if the exe_scope is null or doesn't have a target,
+ // then we just need to get out of here. I'll lldb_assert and not make any of the compiler objects since
+ // I can't return errors directly from the constructor. Further calls will check if the compiler was made and
+ // bag out if it wasn't.
+
+ if (!exe_scope)
+ {
+ lldb_assert(exe_scope, "Can't make an expression parser with a null scope.", __FUNCTION__, __FILE__, __LINE__);
+ return;
+ }
+
+ lldb::TargetSP target_sp;
+ target_sp = exe_scope->CalculateTarget();
+ if (!target_sp)
+ {
+ lldb_assert(exe_scope, "Can't make an expression parser with a null target.", __FUNCTION__, __FILE__, __LINE__);
+ return;
+ }
+
// 1. Create a new compiler instance.
m_compiler.reset(new CompilerInstance());
+ lldb::LanguageType frame_lang = expr.Language(); // defaults to lldb::eLanguageTypeUnknown
+ bool overridden_target_opts = false;
+ lldb_private::LanguageRuntime *lang_rt = nullptr;
- // 2. Install the target.
+ std::string abi;
+ ArchSpec target_arch;
+ target_arch = target_sp->GetArchitecture();
- lldb::TargetSP target_sp;
- if (exe_scope)
- target_sp = exe_scope->CalculateTarget();
+ const auto target_machine = target_arch.GetMachine();
+
+ // If the expression is being evaluated in the context of an existing
+ // stack frame, we introspect to see if the language runtime is available.
+
+ lldb::StackFrameSP frame_sp = exe_scope->CalculateStackFrame();
+ lldb::ProcessSP process_sp = exe_scope->CalculateProcess();
+
+ // Make sure the user hasn't provided a preferred execution language
+ // with `expression --language X -- ...`
+ if (frame_sp && frame_lang == lldb::eLanguageTypeUnknown)
+ frame_lang = frame_sp->GetLanguage();
+
+ 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));
+ }
- // TODO: figure out what to really do when we don't have a valid target.
- // Sometimes this will be ok to just use the host target triple (when we
- // evaluate say "2+3", but other expressions like breakpoint conditions
- // and other things that _are_ target specific really shouldn't just be
- // using the host triple. This needs to be fixed in a better way.
- if (target_sp && target_sp->GetArchitecture().IsValid())
+ // 2. Configure the compiler with a set of default options that are appropriate
+ // for most situations.
+ if (target_arch.IsValid())
{
- std::string triple = target_sp->GetArchitecture().GetTriple().str();
+ 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());
}
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 evaluate say "2+3", but other
+ // expressions like breakpoint conditions and other things that _are_ target specific really shouldn't just be
+ // using 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());
}
-
- if (target_sp->GetArchitecture().GetMachine() == llvm::Triple::x86 ||
- target_sp->GetArchitecture().GetMachine() == llvm::Triple::x86_64)
- {
- m_compiler->getTargetOpts().Features.push_back("+sse");
- m_compiler->getTargetOpts().Features.push_back("+sse2");
- }
-
+ // Now add some special fixes for known architectures:
// Any arm32 iOS environment, but not on arm64
if (m_compiler->getTargetOpts().Triple.find("arm64") == std::string::npos &&
m_compiler->getTargetOpts().Triple.find("arm") != std::string::npos &&
@@ -204,17 +339,60 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
{
m_compiler->getTargetOpts().ABI = "apcs-gnu";
}
+ // Supported subsets of x86
+ if (target_machine == llvm::Triple::x86 ||
+ target_machine == llvm::Triple::x86_64)
+ {
+ m_compiler->getTargetOpts().Features.push_back("+sse");
+ m_compiler->getTargetOpts().Features.push_back("+sse2");
+ }
- m_compiler->createDiagnostics();
+ // Set the target CPU to generate code for.
+ // This will be empty for any CPU that doesn't really need to make a special CPU string.
+ m_compiler->getTargetOpts().CPU = target_arch.GetClangTargetCPU();
- // Create the target instance.
- m_compiler->setTarget(TargetInfo::CreateTargetInfo(
- m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts));
+ // Set the target ABI
+ abi = GetClangTargetABI(target_arch);
+ if (!abi.empty())
+ m_compiler->getTargetOpts().ABI = abi;
- assert (m_compiler->hasTarget());
+ // 3. Now allow the runtime to provide custom configuration options for the target.
+ // In this case, a specialized language runtime is available and we can query it for extra options.
+ // For 99% of use cases, this will not be needed and should be provided when basic platform detection is not enough.
+ if (lang_rt)
+ overridden_target_opts = lang_rt->GetOverrideExprOptions(m_compiler->getTargetOpts());
+
+ if (overridden_target_opts)
+ if (log)
+ {
+ log->Debug("Using overridden target options for the expression evaluation");
+
+ auto opts = m_compiler->getTargetOpts();
+ log->Debug("Triple: '%s'", opts.Triple.c_str());
+ log->Debug("CPU: '%s'", opts.CPU.c_str());
+ log->Debug("FPMath: '%s'", opts.FPMath.c_str());
+ log->Debug("ABI: '%s'", opts.ABI.c_str());
+ log->Debug("LinkerVersion: '%s'", opts.LinkerVersion.c_str());
+ StringList::LogDump(log, opts.FeaturesAsWritten, "FeaturesAsWritten");
+ StringList::LogDump(log, opts.Features, "Features");
+ StringList::LogDump(log, opts.Reciprocals, "Reciprocals");
+ }
+
+ // 4. Create and install the target on the compiler.
+ m_compiler->createDiagnostics();
+ 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());
+ }
+ m_compiler->setTarget(target_info);
- // 3. Set options.
+ assert (m_compiler->hasTarget());
+ // 5. Set language options.
lldb::LanguageType language = expr.Language();
switch (language)
@@ -242,7 +420,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
case lldb::eLanguageTypeC_plus_plus_14:
m_compiler->getLangOpts().CPlusPlus11 = true;
m_compiler->getHeaderSearchOpts().UseLibcxx = true;
- // fall thru ...
+ LLVM_FALLTHROUGH;
case lldb::eLanguageTypeC_plus_plus_03:
m_compiler->getLangOpts().CPlusPlus = true;
// FIXME: the following language option is a temporary workaround,
@@ -277,10 +455,6 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
// information.
m_compiler->getLangOpts().SpellChecking = false;
- lldb::ProcessSP process_sp;
- if (exe_scope)
- process_sp = exe_scope->CalculateProcess();
-
if (process_sp && m_compiler->getLangOpts().ObjC1)
{
if (process_sp->GetObjCLanguageRuntime())
@@ -305,9 +479,9 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_compiler->getCodeGenOpts().DisableFPElim = true;
m_compiler->getCodeGenOpts().OmitLeafFramePointer = false;
if (generate_debug_info)
- m_compiler->getCodeGenOpts().setDebugInfo(CodeGenOptions::FullDebugInfo);
+ m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo);
else
- m_compiler->getCodeGenOpts().setDebugInfo(CodeGenOptions::NoDebugInfo);
+ m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::NoDebugInfo);
// Disable some warnings.
m_compiler->getDiagnostics().setSeverityForGroup(clang::diag::Flavor::WarningOrError,
@@ -321,11 +495,11 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
// created. This complexity should be lifted elsewhere.
m_compiler->getTarget().adjust(m_compiler->getLangOpts());
- // 4. Set up the diagnostic buffer for reporting errors
+ // 6. Set up the diagnostic buffer for reporting errors
- m_compiler->getDiagnostics().setClient(new clang::TextDiagnosticBuffer);
+ m_compiler->getDiagnostics().setClient(new ClangDiagnosticManagerAdapter);
- // 5. Set up the source management objects inside the compiler
+ // 7. Set up the source management objects inside the compiler
clang::FileSystemOptions file_system_options;
m_file_manager.reset(new clang::FileManager(file_system_options));
@@ -344,7 +518,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
}
- // 6. Most of this we get from the CompilerInstance, but we
+ // 8. Most of this we get from the CompilerInstance, but we
// also want to give the context an ExternalASTSource.
m_selector_table.reset(new SelectorTable());
m_builtin_context.reset(new Builtin::Context());
@@ -387,37 +561,38 @@ ClangExpressionParser::~ClangExpressionParser()
}
unsigned
-ClangExpressionParser::Parse (Stream &stream)
+ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager)
{
- TextDiagnosticBuffer *diag_buf = static_cast<TextDiagnosticBuffer*>(m_compiler->getDiagnostics().getClient());
+ ClangDiagnosticManagerAdapter *adapter =
+ static_cast<ClangDiagnosticManagerAdapter *>(m_compiler->getDiagnostics().getClient());
+ clang::TextDiagnosticBuffer *diag_buf = adapter->GetPassthrough();
+ diag_buf->FlushDiagnostics(m_compiler->getDiagnostics());
- diag_buf->FlushDiagnostics (m_compiler->getDiagnostics());
+ adapter->ResetManager(&diagnostic_manager);
const char *expr_text = m_expr.Text();
- clang::SourceManager &SourceMgr = m_compiler->getSourceManager();
+ clang::SourceManager &source_mgr = m_compiler->getSourceManager();
bool created_main_file = false;
- if (m_compiler->getCodeGenOpts().getDebugInfo() == CodeGenOptions::FullDebugInfo)
+ if (m_compiler->getCodeGenOpts().getDebugInfo() == codegenoptions::FullDebugInfo)
{
- std::string temp_source_path;
-
int temp_fd = -1;
llvm::SmallString<PATH_MAX> result_path;
FileSpec tmpdir_file_spec;
if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
{
tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr");
- temp_source_path = tmpdir_file_spec.GetPath();
+ std::string temp_source_path = tmpdir_file_spec.GetPath();
llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path);
}
else
{
llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path);
}
-
+
if (temp_fd != -1)
{
- lldb_private::File file (temp_fd, true);
+ lldb_private::File file(temp_fd, 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())
@@ -425,9 +600,8 @@ ClangExpressionParser::Parse (Stream &stream)
if (bytes_written == expr_text_len)
{
file.Close();
- SourceMgr.setMainFileID(SourceMgr.createFileID(
- m_file_manager->getFile(result_path),
- SourceLocation(), SrcMgr::C_User));
+ source_mgr.setMainFileID(source_mgr.createFileID(m_file_manager->getFile(result_path),
+ SourceLocation(), SrcMgr::C_User));
created_main_file = true;
}
}
@@ -437,7 +611,7 @@ ClangExpressionParser::Parse (Stream &stream)
if (!created_main_file)
{
std::unique_ptr<MemoryBuffer> memory_buffer = MemoryBuffer::getMemBufferCopy(expr_text, __FUNCTION__);
- SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(memory_buffer)));
+ source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
}
diag_buf->BeginSourceFile(m_compiler->getLangOpts(), &m_compiler->getPreprocessor());
@@ -462,58 +636,147 @@ ClangExpressionParser::Parse (Stream &stream)
diag_buf->EndSourceFile();
- TextDiagnosticBuffer::const_iterator diag_iterator;
+ unsigned num_errors = diag_buf->getNumErrors();
- int num_errors = 0;
-
if (m_pp_callbacks && m_pp_callbacks->hasErrors())
{
num_errors++;
-
- stream.PutCString(m_pp_callbacks->getErrorString().c_str());
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "while importing modules:");
+ diagnostic_manager.AppendMessageToDiagnostic(m_pp_callbacks->getErrorString().c_str());
}
- for (diag_iterator = diag_buf->warn_begin();
- diag_iterator != diag_buf->warn_end();
- ++diag_iterator)
- stream.Printf("warning: %s\n", (*diag_iterator).second.c_str());
+ if (!num_errors)
+ {
+ if (type_system_helper->DeclMap() && !type_system_helper->DeclMap()->ResolveUnknownTypes())
+ {
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't infer the type of a variable");
+ num_errors++;
+ }
+ }
- for (diag_iterator = diag_buf->err_begin();
- diag_iterator != diag_buf->err_end();
- ++diag_iterator)
+ if (!num_errors)
{
- num_errors++;
- stream.Printf("error: %s\n", (*diag_iterator).second.c_str());
+ type_system_helper->CommitPersistentDecls();
}
- for (diag_iterator = diag_buf->note_begin();
- diag_iterator != diag_buf->note_end();
- ++diag_iterator)
- stream.Printf("note: %s\n", (*diag_iterator).second.c_str());
+ adapter->ResetManager();
- if (!num_errors)
+ return num_errors;
+}
+
+std::string
+ClangExpressionParser::GetClangTargetABI (const ArchSpec &target_arch)
+{
+ std::string abi;
+
+ if(target_arch.IsMIPS())
{
- if (type_system_helper->DeclMap() && !type_system_helper->DeclMap()->ResolveUnknownTypes())
+ switch (target_arch.GetFlags () & ArchSpec::eMIPSABI_mask)
+ {
+ case ArchSpec::eMIPSABI_N64:
+ abi = "n64"; break;
+ case ArchSpec::eMIPSABI_N32:
+ abi = "n32"; break;
+ case ArchSpec::eMIPSABI_O32:
+ abi = "o32"; break;
+ default:
+ break;
+ }
+ }
+ return abi;
+}
+
+bool
+ClangExpressionParser::RewriteExpression(DiagnosticManager &diagnostic_manager)
+{
+ clang::SourceManager &source_manager = m_compiler->getSourceManager();
+ clang::edit::EditedSource editor(source_manager, m_compiler->getLangOpts(), nullptr);
+ clang::edit::Commit commit(editor);
+ clang::Rewriter rewriter(source_manager, m_compiler->getLangOpts());
+
+ class RewritesReceiver : public edit::EditsReceiver {
+ Rewriter &rewrite;
+
+ public:
+ RewritesReceiver(Rewriter &in_rewrite) : rewrite(in_rewrite) { }
+
+ void insert(SourceLocation loc, StringRef text) override {
+ rewrite.InsertText(loc, text);
+ }
+ void replace(CharSourceRange range, StringRef text) override {
+ rewrite.ReplaceText(range.getBegin(), rewrite.getRangeSize(range), text);
+ }
+ };
+
+ RewritesReceiver rewrites_receiver(rewriter);
+
+ const DiagnosticList &diagnostics = diagnostic_manager.Diagnostics();
+ size_t num_diags = diagnostics.size();
+ if (num_diags == 0)
+ return false;
+
+ for (const Diagnostic *diag : diagnostic_manager.Diagnostics())
+ {
+ const ClangDiagnostic *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag);
+ if (diagnostic && diagnostic->HasFixIts())
{
- stream.Printf("error: Couldn't infer the type of a variable\n");
- num_errors++;
+ for (const FixItHint &fixit : diagnostic->FixIts())
+ {
+ // This is cobbed from clang::Rewrite::FixItRewriter.
+ if (fixit.CodeToInsert.empty())
+ {
+ if (fixit.InsertFromRange.isValid())
+ {
+ commit.insertFromRange(fixit.RemoveRange.getBegin(),
+ fixit.InsertFromRange, /*afterToken=*/false,
+ fixit.BeforePreviousInsertions);
+ }
+ else
+ commit.remove(fixit.RemoveRange);
+ }
+ else
+ {
+ if (fixit.RemoveRange.isTokenRange() ||
+ fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd())
+ commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
+ else
+ commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
+ /*afterToken=*/false, fixit.BeforePreviousInsertions);
+ }
+ }
}
}
+
+ // FIXME - do we want to try to propagate specific errors here?
+ if (!commit.isCommitable())
+ return false;
+ else if (!editor.commit(commit))
+ return false;
+
+ // Now play all the edits, and stash the result in the diagnostic manager.
+ editor.applyRewrites(rewrites_receiver);
+ RewriteBuffer &main_file_buffer = rewriter.getEditBuffer(source_manager.getMainFileID());
- return num_errors;
+ std::string fixed_expression;
+ llvm::raw_string_ostream out_stream(fixed_expression);
+
+ main_file_buffer.write(out_stream);
+ out_stream.flush();
+ diagnostic_manager.SetFixedExpression(fixed_expression);
+
+ return true;
}
static bool FindFunctionInModule (ConstString &mangled_name,
llvm::Module *module,
const char *orig_name)
{
- for (llvm::Module::iterator fi = module->getFunctionList().begin(), fe = module->getFunctionList().end();
- fi != fe;
- ++fi)
+ for (const auto &func : module->getFunctionList())
{
- if (fi->getName().str().find(orig_name) != std::string::npos)
+ const StringRef &name = func.getName();
+ if (name.find(orig_name) != StringRef::npos)
{
- mangled_name.SetCString(fi->getName().str().c_str());
+ mangled_name.SetString(name);
return true;
}
}
@@ -521,7 +784,7 @@ static bool FindFunctionInModule (ConstString &mangled_name,
return false;
}
-Error
+lldb_private::Error
ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
lldb::addr_t &func_end,
lldb::IRExecutionUnitSP &execution_unit_sp,
@@ -533,7 +796,7 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
func_end = LLDB_INVALID_ADDRESS;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- Error err;
+ lldb_private::Error err;
std::unique_ptr<llvm::Module> llvm_module_ap (m_code_generator->ReleaseModule());
@@ -544,26 +807,65 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
return err;
}
- // Find the actual name of the function (it's often mangled somehow)
-
ConstString function_name;
- if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName()))
+ if (execution_policy != eExecutionPolicyTopLevel)
{
- err.SetErrorToGenericError();
- err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
- return err;
+ // Find the actual name of the function (it's often mangled somehow)
+
+ if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName()))
+ {
+ err.SetErrorToGenericError();
+ err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
+ return err;
+ }
+ else
+ {
+ if (log)
+ log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
+ }
}
- else
+
+ SymbolContext sc;
+
+ if (lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP())
+ {
+ sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything);
+ }
+ else if (lldb::TargetSP target_sp = exe_ctx.GetTargetSP())
+ {
+ sc.target_sp = target_sp;
+ }
+
+ LLVMUserExpression::IRPasses custom_passes;
{
+ auto lang = m_expr.Language();
if (log)
- log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
+ log->Printf("%s - Currrent expression language is %s\n", __FUNCTION__,
+ Language::GetNameForLanguageType(lang));
+
+ if (lang != lldb::eLanguageTypeUnknown)
+ {
+ auto runtime = exe_ctx.GetProcessSP()->GetLanguageRuntime(lang);
+ if (runtime)
+ runtime->GetIRPasses(custom_passes);
+ }
+ }
+
+ if (custom_passes.EarlyPasses)
+ {
+ if (log)
+ log->Printf("%s - Running Early IR Passes from LanguageRuntime on expression module '%s'", __FUNCTION__,
+ m_expr.FunctionName());
+
+ custom_passes.EarlyPasses->run(*llvm_module_ap);
}
execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here
llvm_module_ap, // handed off here
function_name,
exe_ctx.GetTargetSP(),
+ sc,
m_compiler->getTargetOpts().Features));
ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
@@ -576,20 +878,28 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
if (target)
error_stream = target->GetDebugger().GetErrorFile().get();
- IRForTarget ir_for_target(decl_map,
- m_expr.NeedsVariableResolution(),
- *execution_unit_sp,
- error_stream,
+ IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), *execution_unit_sp, error_stream,
function_name.AsCString());
bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule());
- Error interpret_error;
Process *process = exe_ctx.GetProcessPtr();
- bool interpret_function_calls = !process ? false : process->CanInterpretFunctionCalls();
- can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error, interpret_function_calls);
+ if (execution_policy != eExecutionPolicyAlways && execution_policy != eExecutionPolicyTopLevel)
+ {
+ lldb_private::Error interpret_error;
+
+ bool interpret_function_calls = !process ? false : process->CanInterpretFunctionCalls();
+ can_interpret =
+ IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(),
+ interpret_error, interpret_function_calls);
+ if (!can_interpret && execution_policy == eExecutionPolicyNever)
+ {
+ err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString());
+ return err;
+ }
+ }
if (!ir_can_run)
{
@@ -597,19 +907,21 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
return err;
}
- if (!can_interpret && execution_policy == eExecutionPolicyNever)
+ if (!process && execution_policy == eExecutionPolicyAlways)
{
- err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString());
+ err.SetErrorString("Expression needed to run in the target, but the target can't be run");
return err;
}
- if (!process && execution_policy == eExecutionPolicyAlways)
+ if (!process && execution_policy == eExecutionPolicyTopLevel)
{
- err.SetErrorString("Expression needed to run in the target, but the target can't be run");
+ err.SetErrorString(
+ "Top-level code needs to be inserted into a runnable target, but the target can't be run");
return err;
}
- if (execution_policy == eExecutionPolicyAlways || !can_interpret)
+ if (execution_policy == eExecutionPolicyAlways ||
+ (execution_policy != eExecutionPolicyTopLevel && !can_interpret))
{
if (m_expr.NeedsValidation() && process)
{
@@ -617,14 +929,14 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
{
DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
- StreamString install_errors;
+ DiagnosticManager install_diagnostics;
- if (!dynamic_checkers->Install(install_errors, exe_ctx))
+ if (!dynamic_checkers->Install(install_diagnostics, exe_ctx))
{
- if (install_errors.GetString().empty())
- err.SetErrorString ("couldn't install checkers, unknown error");
+ if (install_diagnostics.Diagnostics().size())
+ err.SetErrorString("couldn't install checkers, unknown error");
else
- err.SetErrorString (install_errors.GetString().c_str());
+ err.SetErrorString(install_diagnostics.GetString().c_str());
return err;
}
@@ -637,14 +949,28 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString());
- if (!ir_dynamic_checks.runOnModule(*execution_unit_sp->GetModule()))
+ llvm::Module *module = execution_unit_sp->GetModule();
+ if (!module || !ir_dynamic_checks.runOnModule(*module))
{
err.SetErrorToGenericError();
err.SetErrorString("Couldn't add dynamic checks to the expression");
return err;
}
+
+ if (custom_passes.LatePasses)
+ {
+ if (log)
+ log->Printf("%s - Running Late IR Passes from LanguageRuntime on expression module '%s'",
+ __FUNCTION__, m_expr.FunctionName());
+
+ custom_passes.LatePasses->run(*module);
+ }
}
+ }
+ if (execution_policy == eExecutionPolicyAlways || execution_policy == eExecutionPolicyTopLevel ||
+ !can_interpret)
+ {
execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
}
}
@@ -655,3 +981,51 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
return err;
}
+
+lldb_private::Error
+ClangExpressionParser::RunStaticInitializers (lldb::IRExecutionUnitSP &execution_unit_sp,
+ ExecutionContext &exe_ctx)
+{
+ lldb_private::Error err;
+
+ lldbassert(execution_unit_sp.get());
+ lldbassert(exe_ctx.HasThreadScope());
+
+ if (!execution_unit_sp.get())
+ {
+ err.SetErrorString ("can't run static initializers for a NULL execution unit");
+ return err;
+ }
+
+ if (!exe_ctx.HasThreadScope())
+ {
+ err.SetErrorString ("can't run static initializers without a thread");
+ return err;
+ }
+
+ std::vector<lldb::addr_t> static_initializers;
+
+ execution_unit_sp->GetStaticInitializers(static_initializers);
+
+ for (lldb::addr_t static_initializer : static_initializers)
+ {
+ EvaluateExpressionOptions options;
+
+ lldb::ThreadPlanSP call_static_initializer(new ThreadPlanCallFunction(exe_ctx.GetThreadRef(),
+ Address(static_initializer),
+ CompilerType(),
+ llvm::ArrayRef<lldb::addr_t>(),
+ options));
+
+ DiagnosticManager execution_errors;
+ lldb::ExpressionResults results = exe_ctx.GetThreadRef().GetProcess()->RunThreadPlan(exe_ctx, call_static_initializer, options, execution_errors);
+
+ if (results != lldb::eExpressionCompleted)
+ {
+ err.SetErrorStringWithFormat ("couldn't run static initializer: %s", execution_errors.GetString().c_str());
+ return err;
+ }
+ }
+
+ return err;
+}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index 3c055380b839..34c0212b73a4 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -10,11 +10,12 @@
#ifndef liblldb_ClangExpressionParser_h_
#define liblldb_ClangExpressionParser_h_
-#include "lldb/lldb-public.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Error.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionParser.h"
+#include "lldb/lldb-public.h"
#include <string>
#include <vector>
@@ -63,16 +64,19 @@ public:
/// Parse a single expression and convert it to IR using Clang. Don't
/// wrap the expression in anything at all.
///
- /// @param[in] stream
- /// The stream to print errors to.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @return
/// The number of errors encountered during parsing. 0 means
/// success.
//------------------------------------------------------------------
unsigned
- Parse (Stream &stream) override;
+ Parse(DiagnosticManager &diagnostic_manager) override;
+ bool
+ RewriteExpression(DiagnosticManager &diagnostic_manager) override;
+
//------------------------------------------------------------------
/// Ready an already-parsed expression for execution, possibly
/// evaluating it statically.
@@ -98,7 +102,7 @@ public:
///
/// @param[out] const_result
/// If the result of the expression is constant, and the
- /// expression has no side effects, this is set to the result of the
+ /// expression has no side effects, this is set to the result of the
/// expression.
///
/// @param[in] execution_policy
@@ -117,7 +121,35 @@ public:
ExecutionContext &exe_ctx,
bool &can_interpret,
lldb_private::ExecutionPolicy execution_policy) override;
-
+
+ //------------------------------------------------------------------
+ /// Run all static initializers for an execution unit.
+ ///
+ /// @param[in] execution_unit_sp
+ /// The execution unit.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when running them. Thread can't be null.
+ ///
+ /// @return
+ /// The error code indicating the
+ //------------------------------------------------------------------
+ Error
+ RunStaticInitializers (lldb::IRExecutionUnitSP &execution_unit_sp,
+ ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Returns a string representing current ABI.
+ ///
+ /// @param[in] target_arch
+ /// The target architecture.
+ ///
+ /// @return
+ /// A string representing target ABI for the current architecture.
+ //-------------------------------------------------------------------
+ std::string
+ GetClangTargetABI (const ArchSpec &target_arch);
+
private:
std::unique_ptr<llvm::LLVMContext> m_llvm_context; ///< The LLVM context to generate IR into
std::unique_ptr<clang::FileManager> m_file_manager; ///< The Clang file manager object used by the compiler
diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index 0d0d7475a00e..02c0ad5013ec 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -74,10 +74,15 @@ ClangFunctionCaller::~ClangFunctionCaller()
}
unsigned
-ClangFunctionCaller::CompileFunction (Stream &errors)
+
+ClangFunctionCaller::CompileFunction (lldb::ThreadSP thread_to_use_sp,
+ DiagnosticManager &diagnostic_manager)
{
if (m_compiled)
return 0;
+
+ // Compilation might call code, make sure to keep on the thread the caller indicated.
+ ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(thread_to_use_sp);
// FIXME: How does clang tell us there's no return value? We need to handle that case.
unsigned num_errors = 0;
@@ -143,8 +148,9 @@ ClangFunctionCaller::CompileFunction (Stream &errors)
type_name = clang_qual_type.GetTypeName().AsCString("");
}
else
- {
- errors.Printf("Could not determine type of input value %" PRIu64 ".", (uint64_t)i);
+ {
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "Could not determine type of input value %" PRIu64 ".", (uint64_t)i);
return 1;
}
}
@@ -195,15 +201,15 @@ ClangFunctionCaller::CompileFunction (Stream &errors)
{
const bool generate_debug_info = true;
m_parser.reset(new ClangExpressionParser(jit_process_sp.get(), *this, generate_debug_info));
-
- num_errors = m_parser->Parse (errors);
+
+ num_errors = m_parser->Parse(diagnostic_manager);
}
else
{
- errors.Printf("no process - unable to inject function");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "no process - unable to inject function");
num_errors = 1;
}
-
+
m_compiled = (num_errors == 0);
if (!m_compiled)
diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
index 3e30f818a932..468b9c1c76dc 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
@@ -137,17 +137,23 @@ public:
//------------------------------------------------------------------
/// Compile the wrapper function
///
- /// @param[in] errors
- /// The stream to print parser errors to.
+ /// @param[in] thread_to_use_sp
+ /// Compilation might end up calling functions. Pass in the thread you
+ /// want the compilation to use. If you pass in an empty ThreadSP it will
+ /// use the currently selected thread.
+ ///
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report parser errors to.
///
/// @return
/// The number of errors.
//------------------------------------------------------------------
unsigned
- CompileFunction (Stream &errors) override;
-
+ CompileFunction (lldb::ThreadSP thread_to_use_sp,
+ DiagnosticManager &diagnostic_manager) override;
+
ExpressionTypeSystemHelper *
- GetTypeSystemHelper () override
+ GetTypeSystemHelper() override
{
return &m_type_system_helper;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index 05d8a320a5a4..63a3a85bacb4 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -585,6 +585,7 @@ ClangModulesDeclVendorImpl::ForEachMacro(const ClangModulesDeclVendor::ModuleVec
break;
case clang::tok::TokenKind::raw_identifier:
macro_expansion.append(ti->getRawIdentifier().str());
+ break;
default:
macro_expansion.append(ti->getName());
break;
@@ -627,7 +628,9 @@ ClangModulesDeclVendor::Create(Target &target)
std::vector<std::string> compiler_invocation_arguments =
{
+ "clang",
"-fmodules",
+ "-fimplicit-module-maps",
"-fcxx-modules",
"-fsyntax-only",
"-femit-all-decls",
diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
index 9bf9d435d7ea..d1478e49bff5 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
@@ -14,6 +14,8 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Value.h"
+#include "clang/AST/Decl.h"
+
#include "llvm/ADT/StringMap.h"
using namespace lldb;
@@ -66,18 +68,26 @@ ClangPersistentVariables::GetNextPersistentVariableName ()
}
void
-ClangPersistentVariables::RegisterPersistentType (const ConstString &name,
- clang::TypeDecl *type_decl)
+ClangPersistentVariables::RegisterPersistentDecl (const ConstString &name,
+ clang::NamedDecl *decl)
{
- m_persistent_types.insert(std::pair<const char*, clang::TypeDecl*>(name.GetCString(), type_decl));
+ m_persistent_decls.insert(std::pair<const char*, clang::NamedDecl*>(name.GetCString(), decl));
+
+ if (clang::EnumDecl *enum_decl = llvm::dyn_cast<clang::EnumDecl>(decl))
+ {
+ for (clang::EnumConstantDecl *enumerator_decl : enum_decl->enumerators())
+ {
+ m_persistent_decls.insert(std::pair<const char*, clang::NamedDecl*>(ConstString(enumerator_decl->getNameAsString()).GetCString(), enumerator_decl));
+ }
+ }
}
-clang::TypeDecl *
-ClangPersistentVariables::GetPersistentType (const ConstString &name)
+clang::NamedDecl *
+ClangPersistentVariables::GetPersistentDecl (const ConstString &name)
{
- PersistentTypeMap::const_iterator i = m_persistent_types.find(name.GetCString());
+ PersistentDeclMap::const_iterator i = m_persistent_decls.find(name.GetCString());
- if (i == m_persistent_types.end())
+ if (i == m_persistent_decls.end())
return NULL;
else
return i->second;
diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
index 0e03d013d049..2928976592d8 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -70,15 +70,12 @@ public:
void
RemovePersistentVariable (lldb::ExpressionVariableSP variable) override;
- lldb::addr_t
- LookupSymbol (const ConstString &name) override { return LLDB_INVALID_ADDRESS; }
-
void
- RegisterPersistentType (const ConstString &name,
- clang::TypeDecl *tag_decl);
+ RegisterPersistentDecl (const ConstString &name,
+ clang::NamedDecl *decl);
- clang::TypeDecl *
- GetPersistentType (const ConstString &name);
+ clang::NamedDecl *
+ GetPersistentDecl (const ConstString &name);
void
AddHandLoadedClangModule(ClangModulesDeclVendor::ModuleID module)
@@ -94,8 +91,8 @@ public:
private:
uint32_t m_next_persistent_variable_id; ///< The counter used by GetNextResultName().
- typedef llvm::DenseMap<const char *, clang::TypeDecl *> PersistentTypeMap;
- PersistentTypeMap m_persistent_types; ///< The persistent types declared by the user.
+ typedef llvm::DenseMap<const char *, clang::NamedDecl *> PersistentDeclMap;
+ PersistentDeclMap m_persistent_decls; ///< Persistent entities declared by the user.
ClangModulesDeclVendor::ModuleVector m_hand_loaded_clang_modules; ///< These are Clang modules we hand-loaded; these are the highest-
///< priority source for macros.
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 11f7f84ff5f1..52d49aecec9a 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -23,8 +23,10 @@
#include "ClangExpressionParser.h"
#include "ClangModulesDeclVendor.h"
#include "ClangPersistentVariables.h"
+#include "ClangDiagnostic.h"
#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
@@ -55,28 +57,25 @@
using namespace lldb_private;
-ClangUserExpression::ClangUserExpression (ExecutionContextScope &exe_scope,
- const char *expr,
- const char *expr_prefix,
- lldb::LanguageType language,
- ResultType desired_type,
- const EvaluateExpressionOptions &options) :
- LLVMUserExpression (exe_scope, expr, expr_prefix, language, desired_type, options),
- m_type_system_helper(*m_target_wp.lock().get())
+ClangUserExpression::ClangUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
+ lldb::LanguageType language, ResultType desired_type,
+ const EvaluateExpressionOptions &options)
+ : LLVMUserExpression(exe_scope, expr, expr_prefix, language, desired_type, options),
+ m_type_system_helper(*m_target_wp.lock().get(), options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
{
switch (m_language)
{
- case lldb::eLanguageTypeC_plus_plus:
- m_allow_cxx = true;
- break;
- case lldb::eLanguageTypeObjC:
- m_allow_objc = true;
- break;
- case lldb::eLanguageTypeObjC_plus_plus:
- default:
- m_allow_cxx = true;
- m_allow_objc = true;
- break;
+ case lldb::eLanguageTypeC_plus_plus:
+ m_allow_cxx = true;
+ break;
+ case lldb::eLanguageTypeObjC:
+ m_allow_objc = true;
+ break;
+ case lldb::eLanguageTypeObjC_plus_plus:
+ default:
+ m_allow_cxx = true;
+ m_allow_objc = true;
+ break;
}
}
@@ -326,11 +325,9 @@ ApplyObjcCastHack(std::string &expr)
}
bool
-ClangUserExpression::Parse (Stream &error_stream,
- ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy,
- bool keep_result_in_memory,
- bool generate_debug_info)
+ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
+ bool generate_debug_info)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
@@ -346,13 +343,13 @@ ClangUserExpression::Parse (Stream &error_stream,
}
else
{
- error_stream.PutCString ("error: couldn't start parsing (no persistent data)");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't start parsing (no persistent data)");
return false;
}
}
else
{
- error_stream.PutCString ("error: couldn't start parsing (no target)");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "error: couldn't start parsing (no target)");
return false;
}
@@ -360,11 +357,9 @@ ClangUserExpression::Parse (Stream &error_stream,
if (!err.Success())
{
- error_stream.Printf("warning: %s\n", err.AsCString());
+ diagnostic_manager.PutCString(eDiagnosticSeverityWarning, err.AsCString());
}
- StreamString m_transformed_stream;
-
////////////////////////////////////
// Generate the expression
//
@@ -404,22 +399,30 @@ ClangUserExpression::Parse (Stream &error_stream,
}
}
}
-
- std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str()));
-
- lldb::LanguageType lang_type;
- if (m_in_cplusplus_method)
- lang_type = lldb::eLanguageTypeC_plus_plus;
- else if (m_in_objectivec_method)
- lang_type = lldb::eLanguageTypeObjC;
- else
- lang_type = lldb::eLanguageTypeC;
+ lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown;
- if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_in_static_method, exe_ctx))
+ if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
{
- error_stream.PutCString ("error: couldn't construct expression body");
- return false;
+ m_transformed_text = m_expr_text;
+ }
+ else
+ {
+ std::unique_ptr<ExpressionSourceCode> source_code(
+ ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str()));
+
+ if (m_in_cplusplus_method)
+ lang_type = lldb::eLanguageTypeC_plus_plus;
+ else if (m_in_objectivec_method)
+ lang_type = lldb::eLanguageTypeObjC;
+ else
+ lang_type = lldb::eLanguageTypeC;
+
+ if (!source_code->GetText(m_transformed_text, lang_type, m_in_static_method, exe_ctx))
+ {
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't construct expression body");
+ return false;
+ }
}
if (log)
@@ -433,7 +436,7 @@ ClangUserExpression::Parse (Stream &error_stream,
if (!target)
{
- error_stream.PutCString ("error: invalid target\n");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
return false;
}
@@ -467,26 +470,47 @@ ClangUserExpression::Parse (Stream &error_stream,
if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get()))
{
- error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "current process state is unsuitable for expression parsing");
ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
return false;
}
+ if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
+ {
+ DeclMap()->SetLookupsEnabled(true);
+ }
+
Process *process = exe_ctx.GetProcessPtr();
ExecutionContextScope *exe_scope = process;
if (!exe_scope)
exe_scope = exe_ctx.GetTargetPtr();
+ // We use a shared pointer here so we can use the original parser - if it succeeds
+ // or the rewrite parser we might make if it fails. But the parser_sp will never be empty.
+
ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
- unsigned num_errors = parser.Parse (error_stream);
+ unsigned num_errors = parser.Parse(diagnostic_manager);
+ // Check here for FixItHints. If there are any try to apply the fixits and set the fixed text in m_fixed_text
+ // before returning an error.
if (num_errors)
{
- error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
+ if (diagnostic_manager.HasFixIts())
+ {
+ if (parser.RewriteExpression(diagnostic_manager))
+ {
+ size_t fixed_start;
+ size_t fixed_end;
+ const std::string &fixed_expression = diagnostic_manager.GetFixedExpression();
+ if (ExpressionSourceCode::GetOriginalBodyBounds(fixed_expression, lang_type, fixed_start, fixed_end))
+ m_fixed_text = fixed_expression.substr(fixed_start, fixed_end - fixed_start);
+ }
+ }
ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
@@ -497,16 +521,70 @@ ClangUserExpression::Parse (Stream &error_stream,
// Prepare the output of the parser for execution, evaluating it statically if possible
//
- Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
- m_jit_end_addr,
- m_execution_unit_sp,
- exe_ctx,
- m_can_interpret,
- execution_policy);
+ {
+ Error jit_error = parser.PrepareForExecution(m_jit_start_addr,
+ m_jit_end_addr,
+ m_execution_unit_sp,
+ exe_ctx,
+ m_can_interpret,
+ execution_policy);
+
+ if (!jit_error.Success())
+ {
+ const char *error_cstr = jit_error.AsCString();
+ if (error_cstr && error_cstr[0])
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
+ else
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
+ return false;
+ }
+ }
+
+ if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel)
+ {
+ Error static_init_error = parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx);
+
+ if (!static_init_error.Success())
+ {
+ const char *error_cstr = static_init_error.AsCString();
+ if (error_cstr && error_cstr[0])
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "couldn't run static initializers: %s\n",
+ error_cstr);
+ else
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't run static initializers\n");
+ return false;
+ }
+ }
+
+ if (m_execution_unit_sp)
+ {
+ bool register_execution_unit = false;
+
+ if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
+ {
+ register_execution_unit = true;
+ }
+
+ // If there is more than one external function in the execution
+ // unit, it needs to keep living even if it's not top level, because
+ // the result could refer to that function.
+
+ if (m_execution_unit_sp->GetJittedFunctions().size() > 1)
+ {
+ register_execution_unit = true;
+ }
+
+ if (register_execution_unit)
+ {
+ llvm::cast<PersistentExpressionState>(
+ exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(m_language))
+ ->RegisterExecutionUnit(m_execution_unit_sp);
+ }
+ }
if (generate_debug_info)
{
- lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
+ lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
if (jit_module_sp)
{
@@ -517,52 +595,23 @@ ClangUserExpression::Parse (Stream &error_stream,
m_jit_module_wp = jit_module_sp;
target->GetImages().Append(jit_module_sp);
}
-// lldb_private::ObjectFile *jit_obj_file = jit_module_sp->GetObjectFile();
-// StreamFile strm (stdout, false);
-// if (jit_obj_file)
-// {
-// jit_obj_file->GetSectionList();
-// jit_obj_file->GetSymtab();
-// jit_obj_file->Dump(&strm);
-// }
-// lldb_private::SymbolVendor *jit_sym_vendor = jit_module_sp->GetSymbolVendor();
-// if (jit_sym_vendor)
-// {
-// lldb_private::SymbolContextList sc_list;
-// jit_sym_vendor->FindFunctions(const_func_name, NULL, lldb::eFunctionNameTypeFull, true, false, sc_list);
-// sc_list.Dump(&strm, target);
-// jit_sym_vendor->Dump(&strm);
-// }
}
- ResetDeclMap(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any ClangASTImporter::Minions.
+ ResetDeclMap(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any
+ // ClangASTImporter::Minions.
- if (jit_error.Success())
- {
- if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
- m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
- return true;
- }
- else
- {
- const char *error_cstr = jit_error.AsCString();
- if (error_cstr && error_cstr[0])
- error_stream.Printf ("error: %s\n", error_cstr);
- else
- error_stream.Printf ("error: expression can't be interpreted or run\n");
- return false;
- }
+ if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
+ m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
+ return true;
}
bool
-ClangUserExpression::AddArguments (ExecutionContext &exe_ctx,
- std::vector<lldb::addr_t> &args,
- lldb::addr_t struct_address,
- Stream &error_stream)
+ClangUserExpression::AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
+ lldb::addr_t struct_address, DiagnosticManager &diagnostic_manager)
{
lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
- lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
-
+ lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
+
if (m_needs_object_ptr)
{
lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
@@ -581,7 +630,7 @@ ClangUserExpression::AddArguments (ExecutionContext &exe_ctx,
}
else
{
- error_stream.Printf("Need object pointer but don't know the language\n");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "need object pointer but don't know the language");
return false;
}
@@ -591,7 +640,7 @@ ClangUserExpression::AddArguments (ExecutionContext &exe_ctx,
if (!object_ptr_error.Success())
{
- error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
+ exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf("warning: `%s' is not accessible (subsituting 0)\n", object_name.AsCString());
object_ptr = 0;
}
@@ -603,12 +652,14 @@ ClangUserExpression::AddArguments (ExecutionContext &exe_ctx,
if (!object_ptr_error.Success())
{
- error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
+ diagnostic_manager.Printf(eDiagnosticSeverityWarning,
+ "couldn't get cmd pointer (substituting NULL): %s",
+ object_ptr_error.AsCString());
cmd_ptr = 0;
}
}
- if (object_ptr)
- args.push_back(object_ptr);
+
+ args.push_back(object_ptr);
if (m_in_objectivec_method)
args.push_back(cmd_ptr);
@@ -635,14 +686,22 @@ ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &e
}
clang::ASTConsumer *
-ClangUserExpression::ClangUserExpressionHelper::ASTTransformer (clang::ASTConsumer *passthrough)
+ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(clang::ASTConsumer *passthrough)
{
- m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough,
- m_target));
+ m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough, m_top_level, m_target));
return m_result_synthesizer_up.get();
}
+void
+ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls()
+{
+ if (m_result_synthesizer_up.get())
+ {
+ m_result_synthesizer_up->CommitPersistentDecls();
+ }
+}
+
ClangUserExpression::ResultDelegate::ResultDelegate()
{
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index f2bfe31dce09..6077588b0244 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -51,13 +51,10 @@ public:
class ClangUserExpressionHelper : public ClangExpressionHelper
{
public:
- ClangUserExpressionHelper (Target &target) :
- m_target(target)
- {
- }
-
+ ClangUserExpressionHelper(Target &target, bool top_level) : m_target(target), m_top_level(top_level) {}
+
~ClangUserExpressionHelper() override = default;
-
+
//------------------------------------------------------------------
/// Return the object that the parser should use when resolving external
/// values. May be NULL if everything should be self-contained.
@@ -88,11 +85,16 @@ public:
clang::ASTConsumer *
ASTTransformer(clang::ASTConsumer *passthrough) override;
+ void
+ CommitPersistentDecls() override;
+
private:
- Target &m_target;
+ Target &m_target;
std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
- std::unique_ptr<ASTStructExtractor> m_struct_extractor_up; ///< The class that generates the argument struct layout.
+ std::unique_ptr<ASTStructExtractor>
+ m_struct_extractor_up; ///< The class that generates the argument struct layout.
std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
+ bool m_top_level;
};
//------------------------------------------------------------------
@@ -126,8 +128,8 @@ public:
//------------------------------------------------------------------
/// Parse the expression
///
- /// @param[in] error_stream
- /// A stream to print parse errors and warnings to.
+ /// @param[in] diagnostic_manager
+ /// A diagnostic manager to report parse errors and warnings to.
///
/// @param[in] exe_ctx
/// The execution context to use when looking up entities that
@@ -145,11 +147,9 @@ public:
/// True on success (no errors); false otherwise.
//------------------------------------------------------------------
bool
- Parse (Stream &error_stream,
- ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy,
- bool keep_result_in_memory,
- bool generate_debug_info) override;
+ Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
+ bool generate_debug_info) override;
ExpressionTypeSystemHelper *
GetTypeSystemHelper () override
@@ -188,13 +188,11 @@ private:
lldb_private::Error &err) override;
bool
- AddArguments (ExecutionContext &exe_ctx,
- std::vector<lldb::addr_t> &args,
- lldb::addr_t struct_address,
- Stream &error_stream) override;
-
- ClangUserExpressionHelper m_type_system_helper;
-
+ AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args, lldb::addr_t struct_address,
+ DiagnosticManager &diagnostic_manager) override;
+
+ ClangUserExpressionHelper m_type_system_helper;
+
class ResultDelegate : public Materializer::PersistentVariableDelegate
{
public:
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index fe044c17ac78..727e4b3329b3 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -55,8 +55,8 @@ ClangUtilityFunction::~ClangUtilityFunction ()
//------------------------------------------------------------------
/// Install the utility function into a process
///
-/// @param[in] error_stream
-/// A stream to print parse errors and warnings to.
+/// @param[in] diagnostic_manager
+/// A diagnostic manager to report errors and warnings to.
///
/// @param[in] exe_ctx
/// The execution context to install the utility function to.
@@ -65,35 +65,34 @@ ClangUtilityFunction::~ClangUtilityFunction ()
/// True on success (no errors); false otherwise.
//------------------------------------------------------------------
bool
-ClangUtilityFunction::Install (Stream &error_stream,
- ExecutionContext &exe_ctx)
+ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx)
{
if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
{
- error_stream.PutCString("error: already installed\n");
+ diagnostic_manager.PutCString(eDiagnosticSeverityWarning, "already installed");
return false;
}
-
+
////////////////////////////////////
// Set up the target and compiler
//
Target *target = exe_ctx.GetTargetPtr();
-
+
if (!target)
{
- error_stream.PutCString ("error: invalid target\n");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
return false;
}
-
+
Process *process = exe_ctx.GetProcessPtr();
-
+
if (!process)
{
- error_stream.PutCString ("error: invalid process\n");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid process");
return false;
}
-
+
//////////////////////////
// Parse the expression
//
@@ -101,24 +100,23 @@ ClangUtilityFunction::Install (Stream &error_stream,
bool keep_result_in_memory = false;
ResetDeclMap(exe_ctx, keep_result_in_memory);
-
+
if (!DeclMap()->WillParse(exe_ctx, NULL))
{
- error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "current process state is unsuitable for expression parsing");
return false;
}
-
+
const bool generate_debug_info = true;
ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this, generate_debug_info);
-
- unsigned num_errors = parser.Parse (error_stream);
-
+
+ unsigned num_errors = parser.Parse(diagnostic_manager);
+
if (num_errors)
{
- error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
-
ResetDeclMap();
-
+
return false;
}
@@ -175,9 +173,13 @@ ClangUtilityFunction::Install (Stream &error_stream,
{
const char *error_cstr = jit_error.AsCString();
if (error_cstr && error_cstr[0])
- error_stream.Printf ("error: %s\n", error_cstr);
+ {
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
+ }
else
- error_stream.Printf ("error: expression can't be interpreted or run\n");
+ {
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
+ }
return false;
}
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
index 74839717946b..d4ed37eee049 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
@@ -124,12 +124,12 @@ public:
{
m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
}
-
+
bool
- Install (Stream &error_stream, ExecutionContext &exe_ctx) override;
-
+ Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) override;
+
private:
- ClangUtilityFunctionHelper m_type_system_helper; ///< The map to use when parsing and materializing the expression.
+ ClangUtilityFunctionHelper m_type_system_helper; ///< The map to use when parsing and materializing the expression.
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index 509c594280a0..12ba7e3c2ac0 100644
--- a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -25,16 +25,17 @@
#include "clang/AST/ASTContext.h"
-#include "lldb/Core/dwarf.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Core/dwarf.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompilerType.h"
#include <map>
@@ -43,13 +44,6 @@ using namespace llvm;
static char ID;
-IRForTarget::StaticDataAllocator::StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit) :
- m_execution_unit(execution_unit),
- m_stream_string(lldb_private::Stream::eBinary, execution_unit.GetAddressByteSize(), execution_unit.GetByteOrder()),
- m_allocation(LLDB_INVALID_ADDRESS)
-{
-}
-
IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) :
m_maker(maker),
m_values()
@@ -72,28 +66,6 @@ IRForTarget::FunctionValueCache::GetValue(llvm::Function *function)
return m_values[function];
}
-lldb::addr_t
-IRForTarget::StaticDataAllocator::Allocate()
-{
- lldb_private::Error err;
-
- if (m_allocation != LLDB_INVALID_ADDRESS)
- {
- m_execution_unit.FreeNow(m_allocation);
- m_allocation = LLDB_INVALID_ADDRESS;
- }
-
- m_allocation = m_execution_unit.WriteNow((const uint8_t*)m_stream_string.GetData(), m_stream_string.GetSize(), err);
-
- return m_allocation;
-}
-
-lldb::TargetSP
-IRForTarget::StaticDataAllocator::GetTarget()
-{
- return m_execution_unit.GetTarget();
-}
-
static llvm::Value *
FindEntryInstruction (llvm::Function *function)
{
@@ -113,11 +85,11 @@ IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map,
m_func_name(func_name),
m_module(NULL),
m_decl_map(decl_map),
- m_data_allocator(execution_unit),
m_CFStringCreateWithBytes(NULL),
m_sel_registerName(NULL),
m_intptr_ty(NULL),
m_error_stream(error_stream),
+ m_execution_unit(execution_unit),
m_result_store(NULL),
m_result_is_pointer(false),
m_reloc_placeholder(NULL),
@@ -163,213 +135,9 @@ IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function)
{
llvm_function.setLinkage(GlobalValue::ExternalLinkage);
- std::string name = llvm_function.getName().str();
-
- return true;
-}
-
-IRForTarget::LookupResult
-IRForTarget::GetFunctionAddress (llvm::Function *fun,
- uint64_t &fun_addr,
- lldb_private::ConstString &name,
- Constant **&value_ptr)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- fun_addr = LLDB_INVALID_ADDRESS;
- name.Clear();
- value_ptr = NULL;
-
- if (fun->isIntrinsic())
- {
- Intrinsic::ID intrinsic_id = (Intrinsic::ID)fun->getIntrinsicID();
-
- switch (intrinsic_id)
- {
- default:
- if (log)
- log->Printf("Unresolved intrinsic \"%s\"", Intrinsic::getName(intrinsic_id).c_str());
-
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Call to unhandled compiler intrinsic '%s'\n", Intrinsic::getName(intrinsic_id).c_str());
-
- return LookupResult::Fail;
- case Intrinsic::memcpy:
- {
- static lldb_private::ConstString g_memcpy_str ("memcpy");
- name = g_memcpy_str;
- }
- break;
- case Intrinsic::memset:
- {
- static lldb_private::ConstString g_memset_str ("memset");
- name = g_memset_str;
- }
- break;
- case Intrinsic::dbg_declare:
- case Intrinsic::dbg_value:
- return LookupResult::Ignore;
- }
-
- if (log && name)
- log->Printf("Resolved intrinsic name \"%s\"", name.GetCString());
- }
- else
- {
- name.SetCStringWithLength (fun->getName().data(), fun->getName().size());
- }
-
- // Find the address of the function.
-
- clang::NamedDecl *fun_decl = DeclForGlobal (fun);
-
- if (fun_decl)
- {
- if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr))
- {
- std::vector<lldb_private::ConstString> alternates;
- bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr);
-
- if (!found_it)
- {
- lldb_private::Mangled mangled_name(name);
- if (m_error_stream)
- {
- if (mangled_name.GetMangledName())
- m_error_stream->Printf("error: call to a function '%s' ('%s') that is not present in the target\n",
- mangled_name.GetName(lldb::eLanguageTypeObjC_plus_plus).GetCString(),
- mangled_name.GetMangledName().GetCString());
- else
- m_error_stream->Printf("error: call to a function '%s' that is not present in the target\n",
- mangled_name.GetName(lldb::eLanguageTypeObjC_plus_plus).GetCString());
- }
- return LookupResult::Fail;
- }
- }
- }
- else
- {
- if (!m_decl_map->GetFunctionAddress (name, fun_addr))
- {
- if (log)
- log->Printf ("Metadataless function \"%s\" had no address", name.GetCString());
-
- if (m_error_stream)
- m_error_stream->Printf("Error [IRForTarget]: Call to a symbol-only function '%s' that is not present in the target\n", name.GetCString());
-
- return LookupResult::Fail;
- }
- }
-
- if (log)
- log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), fun_addr);
-
- return LookupResult::Success;
-}
-
-llvm::Constant *
-IRForTarget::BuildFunctionPointer (llvm::Type *type,
- uint64_t ptr)
-{
- PointerType *fun_ptr_ty = PointerType::getUnqual(type);
- Constant *fun_addr_int = ConstantInt::get(m_intptr_ty, ptr, false);
- return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
-}
-
-void
-IRForTarget::RegisterFunctionMetadata(LLVMContext &context,
- llvm::Value *function_ptr,
- const char *name)
-{
- for (llvm::User *user : function_ptr->users())
- {
- if (Instruction *user_inst = dyn_cast<Instruction>(user))
- {
- MDString* md_name = MDString::get(context, StringRef(name));
-
- MDNode *metadata = MDNode::get(context, md_name);
-
- user_inst->setMetadata("lldb.call.realName", metadata);
- }
- else
- {
- RegisterFunctionMetadata (context, user, name);
- }
- }
-}
-
-bool
-IRForTarget::ResolveFunctionPointers(llvm::Module &llvm_module)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- for (llvm::Module::iterator fi = llvm_module.begin();
- fi != llvm_module.end();
- ++fi)
- {
- Function *fun = &*fi;
-
- bool is_decl = fun->isDeclaration();
-
- if (log)
- log->Printf("Examining %s function %s", (is_decl ? "declaration" : "non-declaration"), fun->getName().str().c_str());
-
- if (!is_decl)
- continue;
-
- if (fun->use_empty())
- continue; // ignore
-
- uint64_t addr = LLDB_INVALID_ADDRESS;
- lldb_private::ConstString name;
- Constant **value_ptr = NULL;
-
- LookupResult result = GetFunctionAddress(fun,
- addr,
- name,
- value_ptr);
-
- switch (result)
- {
- case LookupResult::Fail:
- return false; // GetFunctionAddress reports its own errors
-
- case LookupResult::Ignore:
- break; // Nothing to do
-
- case LookupResult::Success:
- {
- Constant *value = BuildFunctionPointer(fun->getFunctionType(), addr);
-
- RegisterFunctionMetadata (llvm_module.getContext(), fun, name.AsCString());
-
- if (value_ptr)
- *value_ptr = value;
-
- // If we are replacing a function with the nobuiltin attribute, it may
- // be called with the builtin attribute on call sites. Remove any such
- // attributes since it's illegal to have a builtin call to something
- // other than a nobuiltin function.
- if (fun->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
- llvm::Attribute builtin = llvm::Attribute::get(fun->getContext(), llvm::Attribute::Builtin);
-
- for (auto u : fun->users()) {
- if (auto call = dyn_cast<CallInst>(u)) {
- call->removeAttribute(AttributeSet::FunctionIndex, builtin);
- }
- }
- }
-
- fun->replaceAllUsesWith(value);
- }
- break;
- }
- }
-
return true;
}
-
clang::NamedDecl *
IRForTarget::DeclForGlobal (const GlobalValue *global_val, Module *module)
{
@@ -572,7 +340,7 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
}
- lldb::TargetSP target_sp (m_data_allocator.GetTarget());
+ lldb::TargetSP target_sp (m_execution_unit.GetTarget());
lldb_private::ExecutionContext exe_ctx (target_sp, true);
if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0)
{
@@ -704,7 +472,8 @@ IRForTarget::RewriteObjCConstString (llvm::GlobalVariable *ns_str,
static lldb_private::ConstString g_CFStringCreateWithBytes_str ("CFStringCreateWithBytes");
- if (!m_decl_map->GetFunctionAddress (g_CFStringCreateWithBytes_str, CFStringCreateWithBytes_addr))
+ CFStringCreateWithBytes_addr = m_execution_unit.FindSymbol (g_CFStringCreateWithBytes_str);
+ if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS)
{
if (log)
log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
@@ -1093,7 +862,8 @@ IRForTarget::RewriteObjCSelector (Instruction* selector_load)
lldb::addr_t sel_registerName_addr;
static lldb_private::ConstString g_sel_registerName_str ("sel_registerName");
- if (!m_decl_map->GetFunctionAddress (g_sel_registerName_str, sel_registerName_addr))
+ sel_registerName_addr = m_execution_unit.FindSymbol (g_sel_registerName_str);
+ if (sel_registerName_addr == LLDB_INVALID_ADDRESS)
return false;
if (log)
@@ -1335,7 +1105,13 @@ IRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer)
if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer))
{
- memcpy (data, int_initializer->getValue().getRawData(), m_target_data->getTypeStoreSize(initializer_type));
+ 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::Error get_data_error;
+ if (!scalar.GetAsMemoryData(data, constant_size, lldb_private::endian::InlHostByteOrder(), get_data_error))
+ return false;
+
return true;
}
else if (ConstantDataArray *array_initializer = dyn_cast<ConstantDataArray>(initializer))
@@ -1388,48 +1164,6 @@ IRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer)
return false;
}
-bool
-IRForTarget::MaterializeInternalVariable (GlobalVariable *global_variable)
-{
- if (GlobalVariable::isExternalLinkage(global_variable->getLinkage()))
- return false;
-
- if (global_variable == m_reloc_placeholder)
- return true;
-
- uint64_t offset = m_data_allocator.GetStream().GetSize();
-
- llvm::Type *variable_type = global_variable->getType();
-
- Constant *initializer = global_variable->getInitializer();
-
- llvm::Type *initializer_type = initializer->getType();
-
- size_t size = m_target_data->getTypeAllocSize(initializer_type);
- size_t align = m_target_data->getPrefTypeAlignment(initializer_type);
-
- const size_t mask = (align - 1);
- uint64_t aligned_offset = (offset + mask) & ~mask;
- m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
- offset = aligned_offset;
-
- lldb_private::DataBufferHeap data(size, '\0');
-
- if (initializer)
- if (!MaterializeInitializer(data.GetBytes(), initializer))
- return false;
-
- m_data_allocator.GetStream().Write(data.GetBytes(), data.GetByteSize());
-
- Constant *new_pointer = BuildRelocation(variable_type, offset);
-
- global_variable->replaceAllUsesWith(new_pointer);
-
- global_variable->eraseFromParent();
-
- return true;
-}
-
// This function does not report errors; its callers are responsible.
bool
IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
@@ -1455,7 +1189,7 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
else if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(llvm_value_ptr))
{
if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
- return MaterializeInternalVariable(global_variable);
+ return true;
clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
@@ -1508,11 +1242,8 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
if (log)
{
log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRIu64 "]",
- name.c_str(),
- lldb_private::ClangASTContext::GetQualType(compiler_type).getAsString().c_str(),
- PrintType(value_type).c_str(),
- value_size,
- value_alignment);
+ name.c_str(), lldb_private::ClangUtil::GetQualType(compiler_type).getAsString().c_str(),
+ PrintType(value_type).c_str(), value_size, value_alignment);
}
@@ -1524,10 +1255,8 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
{
if (!global_variable->hasExternalLinkage())
return true;
- else if (HandleSymbol (global_variable))
- return true;
else
- return false;
+ return true;
}
}
else if (dyn_cast<llvm::Function>(llvm_value_ptr))
@@ -1783,231 +1512,6 @@ IRForTarget::ResolveExternals (Function &llvm_function)
return true;
}
-bool
-IRForTarget::ReplaceStrings ()
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- typedef std::map <GlobalVariable *, size_t> OffsetsTy;
-
- OffsetsTy offsets;
-
- for (GlobalVariable &gv : m_module->globals())
- {
- if (!gv.hasInitializer())
- continue;
-
- Constant *gc = gv.getInitializer();
-
- std::string str;
-
- if (gc->isNullValue())
- {
- Type *gc_type = gc->getType();
-
- ArrayType *gc_array_type = dyn_cast<ArrayType>(gc_type);
-
- if (!gc_array_type)
- continue;
-
- Type *gc_element_type = gc_array_type->getElementType();
-
- IntegerType *gc_integer_type = dyn_cast<IntegerType>(gc_element_type);
-
- if (gc_integer_type->getBitWidth() != 8)
- continue;
-
- str = "";
- }
- else
- {
- ConstantDataArray *gc_array = dyn_cast<ConstantDataArray>(gc);
-
- if (!gc_array)
- continue;
-
- if (!gc_array->isCString())
- continue;
-
- if (log)
- log->Printf("Found a GlobalVariable with string initializer %s", PrintValue(gc).c_str());
-
- str = gc_array->getAsString();
- }
-
- offsets[&gv] = m_data_allocator.GetStream().GetSize();
-
- m_data_allocator.GetStream().Write(str.c_str(), str.length() + 1);
- }
-
- Type *char_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
-
- for (OffsetsTy::iterator oi = offsets.begin(), oe = offsets.end();
- oi != oe;
- ++oi)
- {
- GlobalVariable *gv = oi->first;
- size_t offset = oi->second;
-
- Constant *new_initializer = BuildRelocation(char_ptr_ty, offset);
-
- if (log)
- log->Printf("Replacing GV %s with %s", PrintValue(gv).c_str(), PrintValue(new_initializer).c_str());
-
- for (llvm::User *u : gv->users())
- {
- if (log)
- log->Printf("Found use %s", PrintValue(u).c_str());
-
- ConstantExpr *const_expr = dyn_cast<ConstantExpr>(u);
- StoreInst *store_inst = dyn_cast<StoreInst>(u);
-
- if (const_expr)
- {
- if (const_expr->getOpcode() != Instruction::GetElementPtr)
- {
- if (log)
- log->Printf("Use (%s) of string variable is not a GetElementPtr constant", PrintValue(const_expr).c_str());
-
- return false;
- }
-
- Constant *bit_cast = ConstantExpr::getBitCast(new_initializer, const_expr->getOperand(0)->getType());
- Constant *new_gep = const_expr->getWithOperandReplaced(0, bit_cast);
-
- const_expr->replaceAllUsesWith(new_gep);
- }
- else if (store_inst)
- {
- Constant *bit_cast = ConstantExpr::getBitCast(new_initializer, store_inst->getValueOperand()->getType());
-
- store_inst->setOperand(0, bit_cast);
- }
- else
- {
- if (log)
- log->Printf("Use (%s) of string variable is neither a constant nor a store", PrintValue(const_expr).c_str());
-
- return false;
- }
- }
-
- gv->eraseFromParent();
- }
-
- return true;
-}
-
-bool
-IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- typedef SmallVector <Value*, 2> ConstantList;
- typedef SmallVector <llvm::Instruction*, 2> UserList;
- typedef ConstantList::iterator ConstantIterator;
- typedef UserList::iterator UserIterator;
-
- ConstantList static_constants;
- UserList static_users;
-
- for (BasicBlock::iterator ii = basic_block.begin(), ie = basic_block.end();
- ii != ie;
- ++ii)
- {
- llvm::Instruction &inst = *ii;
-
- for (Value *operand_val : inst.operand_values())
- {
- ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val);
-
- if (operand_constant_fp/* && operand_constant_fp->getType()->isX86_FP80Ty()*/)
- {
- static_constants.push_back(operand_val);
- static_users.push_back(&*ii);
- }
- }
- }
-
- ConstantIterator constant_iter;
- UserIterator user_iter;
-
- for (constant_iter = static_constants.begin(), user_iter = static_users.begin();
- constant_iter != static_constants.end();
- ++constant_iter, ++user_iter)
- {
- Value *operand_val = *constant_iter;
- llvm::Instruction *inst = *user_iter;
-
- ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val);
-
- if (operand_constant_fp)
- {
- Type *operand_type = operand_constant_fp->getType();
-
- APFloat operand_apfloat = operand_constant_fp->getValueAPF();
- APInt operand_apint = operand_apfloat.bitcastToAPInt();
-
- const uint8_t* operand_raw_data = (const uint8_t*)operand_apint.getRawData();
- size_t operand_data_size = operand_apint.getBitWidth() / 8;
-
- if (log)
- {
- std::string s;
- raw_string_ostream ss(s);
- for (size_t index = 0;
- index < operand_data_size;
- ++index)
- {
- ss << (uint32_t)operand_raw_data[index];
- ss << " ";
- }
- ss.flush();
-
- log->Printf("Found ConstantFP with size %" PRIu64 " and raw data %s", (uint64_t)operand_data_size, s.c_str());
- }
-
- lldb_private::DataBufferHeap data(operand_data_size, 0);
-
- if (lldb_private::endian::InlHostByteOrder() != m_data_allocator.GetStream().GetByteOrder())
- {
- uint8_t *data_bytes = data.GetBytes();
-
- for (size_t index = 0;
- index < operand_data_size;
- ++index)
- {
- data_bytes[index] = operand_raw_data[operand_data_size - (1 + index)];
- }
- }
- else
- {
- memcpy(data.GetBytes(), operand_raw_data, operand_data_size);
- }
-
- uint64_t offset = m_data_allocator.GetStream().GetSize();
-
- size_t align = m_target_data->getPrefTypeAlignment(operand_type);
-
- const size_t mask = (align - 1);
- uint64_t aligned_offset = (offset + mask) & ~mask;
- m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
-
- m_data_allocator.GetStream().Write(data.GetBytes(), operand_data_size);
-
- llvm::Type *fp_ptr_ty = operand_constant_fp->getType()->getPointerTo();
-
- Constant *new_pointer = BuildRelocation(fp_ptr_ty, aligned_offset);
-
- llvm::LoadInst *fp_load = new llvm::LoadInst(new_pointer, "fp_load", inst);
-
- operand_constant_fp->replaceAllUsesWith(fp_load);
- }
- }
-
- return true;
-}
-
static bool isGuardVariableRef(Value *V)
{
Constant *Old = NULL;
@@ -2437,79 +1941,6 @@ IRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset)
}
bool
-IRForTarget::CompleteDataAllocation ()
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- if (!m_data_allocator.GetStream().GetSize())
- return true;
-
- lldb::addr_t allocation = m_data_allocator.Allocate();
-
- if (log)
- {
- if (allocation)
- log->Printf("Allocated static data at 0x%llx", (unsigned long long)allocation);
- else
- log->Printf("Failed to allocate static data");
- }
-
- if (!allocation || allocation == LLDB_INVALID_ADDRESS)
- return false;
-
- Constant *relocated_addr = ConstantInt::get(m_intptr_ty, (uint64_t)allocation);
- Constant *relocated_bitcast = ConstantExpr::getIntToPtr(relocated_addr, llvm::Type::getInt8PtrTy(m_module->getContext()));
-
- m_reloc_placeholder->replaceAllUsesWith(relocated_bitcast);
-
- m_reloc_placeholder->eraseFromParent();
-
- return true;
-}
-
-bool
-IRForTarget::StripAllGVs (Module &llvm_module)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- std::vector<GlobalVariable *> global_vars;
- std::set<GlobalVariable *>erased_vars;
-
- bool erased = true;
-
- while (erased)
- {
- erased = false;
-
- for (GlobalVariable &global_var : llvm_module.globals())
- {
- global_var.removeDeadConstantUsers();
-
- if (global_var.use_empty())
- {
- if (log)
- log->Printf("Did remove %s",
- PrintValue(&global_var).c_str());
- global_var.eraseFromParent();
- erased = true;
- break;
- }
- }
- }
-
- for (GlobalVariable &global_var : llvm_module.globals())
- {
- GlobalValue::user_iterator ui = global_var.user_begin();
-
- if (log)
- log->Printf("Couldn't remove %s because of %s",
- PrintValue(&global_var).c_str(),
- PrintValue(*ui).c_str());
- }
-
- return true;
-}
-
-bool
IRForTarget::runOnModule (Module &llvm_module)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
@@ -2530,25 +1961,29 @@ IRForTarget::runOnModule (Module &llvm_module)
log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
}
- Function* main_function = m_module->getFunction(StringRef(m_func_name.c_str()));
+ Function *const main_function = m_func_name.IsEmpty() ? nullptr : m_module->getFunction(m_func_name.GetStringRef());
- if (!main_function)
+ if (!m_func_name.IsEmpty() && !main_function)
{
if (log)
- log->Printf("Couldn't find \"%s()\" in the module", m_func_name.c_str());
+ log->Printf("Couldn't find \"%s()\" in the module", m_func_name.AsCString());
if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Couldn't find wrapper '%s' in the module", m_func_name.c_str());
+ m_error_stream->Printf("Internal error [IRForTarget]: Couldn't find wrapper '%s' in the module",
+ m_func_name.AsCString());
return false;
}
- if (!FixFunctionLinkage (*main_function))
+ if (main_function)
{
- if (log)
- log->Printf("Couldn't fix the linkage for the function");
+ if (!FixFunctionLinkage(*main_function))
+ {
+ if (log)
+ log->Printf("Couldn't fix the linkage for the function");
- return false;
+ return false;
+ }
}
llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
@@ -2567,14 +2002,17 @@ IRForTarget::runOnModule (Module &llvm_module)
// Replace $__lldb_expr_result with a persistent variable
//
- if (!CreateResultVariable(*main_function))
+ if (main_function)
{
- if (log)
- log->Printf("CreateResultVariable() failed");
+ if (!CreateResultVariable(*main_function))
+ {
+ if (log)
+ log->Printf("CreateResultVariable() failed");
- // CreateResultVariable() reports its own errors, so we don't do so here
+ // CreateResultVariable() reports its own errors, so we don't do so here
- return false;
+ return false;
+ }
}
if (log && log->GetVerbose())
@@ -2650,20 +2088,6 @@ IRForTarget::runOnModule (Module &llvm_module)
return false;
}
- ///////////////////////////////
- // Resolve function pointers
- //
-
- if (!ResolveFunctionPointers(llvm_module))
- {
- if (log)
- log->Printf("ResolveFunctionPointers() failed");
-
- // ResolveFunctionPointers() 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)
@@ -2705,14 +2129,6 @@ IRForTarget::runOnModule (Module &llvm_module)
return false;
}
-
- if (!ReplaceStaticLiterals(*bbi))
- {
- if (log)
- log->Printf("ReplaceStaticLiterals() failed");
-
- return false;
- }
}
}
@@ -2720,46 +2136,27 @@ IRForTarget::runOnModule (Module &llvm_module)
// Run function-level passes that only make sense on the main function
//
- if (!ResolveExternals(*main_function))
- {
- if (log)
- log->Printf("ResolveExternals() failed");
-
- // ResolveExternals() reports its own errors, so we don't do so here
-
- return false;
- }
-
- if (!ReplaceVariables(*main_function))
+ if (main_function)
{
- if (log)
- log->Printf("ReplaceVariables() failed");
-
- // ReplaceVariables() reports its own errors, so we don't do so here
-
- return false;
- }
+ if (!ResolveExternals(*main_function))
+ {
+ if (log)
+ log->Printf("ResolveExternals() failed");
- if (!ReplaceStrings())
- {
- if (log)
- log->Printf("ReplaceStrings() failed");
+ // ResolveExternals() reports its own errors, so we don't do so here
- return false;
- }
+ return false;
+ }
- if (!CompleteDataAllocation())
- {
- if (log)
- log->Printf("CompleteDataAllocation() failed");
+ if (!ReplaceVariables(*main_function))
+ {
+ if (log)
+ log->Printf("ReplaceVariables() failed");
- return false;
- }
+ // ReplaceVariables() reports its own errors, so we don't do so here
- if (!StripAllGVs(llvm_module))
- {
- if (log)
- log->Printf("StripAllGVs() failed");
+ return false;
+ }
}
if (log && log->GetVerbose())
diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/source/Plugins/ExpressionParser/Clang/IRForTarget.h
index fb4abcc103de..0f95f67babfd 100644
--- a/source/Plugins/ExpressionParser/Clang/IRForTarget.h
+++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.h
@@ -214,40 +214,6 @@ private:
llvm::Constant **&value_ptr);
//------------------------------------------------------------------
- /// Build a function pointer given a type and a raw pointer.
- ///
- /// @param[in] type
- /// The type of the function pointer to be built.
- ///
- /// @param[in] ptr
- /// The value of the pointer.
- ///
- /// @return
- /// The pointer.
- //------------------------------------------------------------------
- llvm::Constant *
- BuildFunctionPointer (llvm::Type *type,
- uint64_t ptr);
-
- void
- RegisterFunctionMetadata (llvm::LLVMContext &context,
- llvm::Value *function_ptr,
- const char *name);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] llvm_function
- /// The function currently being processed.
- ///
- /// @return
- /// True if the function has side effects (or if this cannot
- /// be determined); false otherwise.
- //------------------------------------------------------------------
- bool
- ResolveFunctionPointers (llvm::Module &llvm_module);
-
- //------------------------------------------------------------------
/// A function-level pass to take the generated global value
/// $__lldb_expr_result and make it into a persistent variable.
/// Also see ASTResultSynthesizer.
@@ -565,38 +531,6 @@ private:
RemoveGuards (llvm::BasicBlock &basic_block);
//------------------------------------------------------------------
- /// A module-level pass to allocate all string literals in a separate
- /// allocation and redirect references to them.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- ReplaceStrings ();
-
- //------------------------------------------------------------------
- /// A basic block-level pass to find all literals that will be
- /// allocated as statics by the JIT (in contrast to the Strings,
- /// which already are statics) and synthesize loads for them.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] basic_block
- /// The basic block currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- ReplaceStaticLiterals (llvm::BasicBlock &basic_block);
-
- //------------------------------------------------------------------
/// A function-level pass to make all external variable references
/// point at the correct offsets from the void* passed into the
/// function. ClangExpressionDeclMap::DoStructLayout() must be called
@@ -612,73 +546,45 @@ private:
/// @return
/// True on success; false otherwise
//------------------------------------------------------------------
- bool
- ReplaceVariables (llvm::Function &llvm_function);
-
- //------------------------------------------------------------------
- /// A module-level pass to remove all global variables from the
- /// module since it no longer should export or import any symbols.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] llvm_module
- /// The module currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
bool
- StripAllGVs (llvm::Module &llvm_module);
-
- class StaticDataAllocator {
- public:
- StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit);
- lldb_private::StreamString &GetStream()
- {
- return m_stream_string;
- }
- lldb::addr_t Allocate();
+ ReplaceVariables(llvm::Function &llvm_function);
- lldb::TargetSP
- GetTarget();
- private:
- lldb_private::IRExecutionUnit &m_execution_unit;
- lldb_private::StreamString m_stream_string;
- lldb::addr_t m_allocation;
- };
-
/// Flags
- bool m_resolve_vars; ///< True if external variable references and persistent variable references should be resolved
- std::string m_func_name; ///< The name of the function to translate
- lldb_private::ConstString m_result_name; ///< The name of the result variable ($0, $1, ...)
- lldb_private::TypeFromParser m_result_type; ///< The type of the result variable.
- llvm::Module *m_module; ///< The module being processed, or NULL if that has not been determined yet.
- std::unique_ptr<llvm::DataLayout> m_target_data; ///< The target data for the module being processed, or NULL if there is no module.
- lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The DeclMap containing the Decls
- StaticDataAllocator m_data_allocator; ///< The allocator to use for constant strings
- llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function CFStringCreateWithBytes, cast to the appropriate function pointer type
- llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate function pointer type
- llvm::IntegerType *m_intptr_ty; ///< The type of an integer large enough to hold a pointer.
- lldb_private::Stream *m_error_stream; ///< If non-NULL, the stream on which errors should be printed
-
- llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that writes to the result variable. If m_has_side_effects is true, this is NULL.
- bool m_result_is_pointer; ///< True if the function's result in the AST is a pointer (see comments in ASTResultSynthesizer::SynthesizeBodyResult)
-
- llvm::GlobalVariable *m_reloc_placeholder; ///< A placeholder that will be replaced by a pointer to the final location of the static allocation.
-
- //------------------------------------------------------------------
- /// UnfoldConstant operates on a constant [Old] which has just been
- /// replaced with a value [New]. We assume that new_value has
- /// been properly placed early in the function, in front of the
- /// first instruction in the entry basic block
- /// [FirstEntryInstruction].
- ///
- /// UnfoldConstant reads through the uses of Old and replaces Old
- /// in those uses with New. Where those uses are constants, the
- /// function generates new instructions to compute the result of the
- /// new, non-constant expression and places them before
+ bool m_resolve_vars; ///< True if external variable references and persistent variable references should be resolved
+ lldb_private::ConstString m_func_name; ///< The name of the function to translate
+ lldb_private::ConstString m_result_name; ///< The name of the result variable ($0, $1, ...)
+ lldb_private::TypeFromParser m_result_type; ///< The type of the result variable.
+ llvm::Module *m_module; ///< The module being processed, or NULL if that has not been determined yet.
+ std::unique_ptr<llvm::DataLayout>
+ m_target_data; ///< The target data for the module being processed, or NULL if there is no module.
+ lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The DeclMap containing the Decls
+ llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function CFStringCreateWithBytes, cast to the
+ ///appropriate function pointer type
+ llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate
+ ///function pointer type
+ llvm::IntegerType *m_intptr_ty; ///< The type of an integer large enough to hold a pointer.
+ lldb_private::Stream *m_error_stream; ///< If non-NULL, the stream on which errors should be printed
+ lldb_private::IRExecutionUnit &m_execution_unit; ///< The execution unit containing the IR being created.
+
+ llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that writes to the result variable. If
+ ///m_has_side_effects is true, this is NULL.
+ bool m_result_is_pointer; ///< True if the function's result in the AST is a pointer (see comments in
+ ///ASTResultSynthesizer::SynthesizeBodyResult)
+
+ llvm::GlobalVariable *m_reloc_placeholder; ///< A placeholder that will be replaced by a pointer to the final
+ ///location of the static allocation.
+
+ //------------------------------------------------------------------
+ /// UnfoldConstant operates on a constant [Old] which has just been
+ /// replaced with a value [New]. We assume that new_value has
+ /// been properly placed early in the function, in front of the
+ /// first instruction in the entry basic block
+ /// [FirstEntryInstruction].
+ ///
+ /// UnfoldConstant reads through the uses of Old and replaces Old
+ /// in those uses with New. Where those uses are constants, the
+ /// function generates new instructions to compute the result of the
+ /// new, non-constant expression and places them before
/// FirstEntryInstruction. These instructions replace the constant
/// uses, so UnfoldConstant calls itself recursively for those.
///
@@ -688,7 +594,7 @@ private:
/// @return
/// True on success; false otherwise
//------------------------------------------------------------------
-
+
class FunctionValueCache {
public:
typedef std::function <llvm::Value *(llvm::Function *)> Maker;
diff --git a/source/Plugins/ExpressionParser/Clang/Makefile b/source/Plugins/ExpressionParser/Clang/Makefile
deleted file mode 100644
index eb592daabb48..000000000000
--- a/source/Plugins/ExpressionParser/Clang/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ExpressionParser/Clang ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginExpressionParserClang
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ExpressionParser/Go/GoAST.h b/source/Plugins/ExpressionParser/Go/GoAST.h
index 6d51240eab5c..89836a38acb0 100644
--- a/source/Plugins/ExpressionParser/Go/GoAST.h
+++ b/source/Plugins/ExpressionParser/Go/GoAST.h
@@ -2764,6 +2764,7 @@ R GoASTExpr::Visit(V* v) const
return v->VisitUnaryExpr(llvm::cast<const GoASTUnaryExpr>(this));
default:
assert(false && "Invalid kind");
+ return R();
}
}
diff --git a/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp b/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
index 3f12a2b6255b..f69c3e23457d 100644
--- a/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
+++ b/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
@@ -26,7 +26,6 @@
// Project includes
#include "GoUserExpression.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataEncoder.h"
@@ -37,9 +36,11 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectRegister.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionVariable.h"
-#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/GoASTContext.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
@@ -48,6 +49,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanCallUserExpression.h"
+#include "lldb/lldb-private.h"
#include "Plugins/ExpressionParser/Go/GoAST.h"
#include "Plugins/ExpressionParser/Go/GoParser.h"
@@ -229,7 +231,8 @@ LookupType(TargetSP target, ConstString name)
return CompilerType();
SymbolContext sc;
TypeList type_list;
- uint32_t num_matches = target->GetImages().FindTypes(sc, name, false, 2, type_list);
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ uint32_t num_matches = target->GetImages().FindTypes(sc, name, false, 2, searched_symbol_files, type_list);
if (num_matches > 0)
{
return type_list.GetTypeAtIndex(0)->GetFullCompilerType();
@@ -245,8 +248,9 @@ GoUserExpression::GoUserExpression(ExecutionContextScope &exe_scope, const char
}
bool
-GoUserExpression::Parse(Stream &error_stream, ExecutionContext &exe_ctx, lldb_private::ExecutionPolicy execution_policy,
- bool keep_result_in_memory, bool generate_debug_info)
+GoUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
+ bool generate_debug_info)
{
InstallContext(exe_ctx);
m_interpreter.reset(new GoInterpreter(exe_ctx, GetUserText()));
@@ -254,15 +258,16 @@ GoUserExpression::Parse(Stream &error_stream, ExecutionContext &exe_ctx, lldb_pr
return true;
const char *error_cstr = m_interpreter->error().AsCString();
if (error_cstr && error_cstr[0])
- error_stream.Printf("error: %s\n", error_cstr);
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
else
- error_stream.Printf("error: expression can't be interpreted or run\n");
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "expression can't be interpreted or run");
return false;
}
lldb::ExpressionResults
-GoUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options,
- lldb::UserExpressionSP &shared_ptr_to_me, lldb::ExpressionVariableSP &result)
+GoUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me,
+ lldb::ExpressionVariableSP &result)
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
@@ -279,7 +284,7 @@ GoUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, const
if (log)
log->Printf("== [GoUserExpression::Evaluate] Expression may not run, but is not constant ==");
- error_stream.Printf("expression needed to run but couldn't");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression needed to run but couldn't");
return execution_results;
}
@@ -294,9 +299,9 @@ GoUserExpression::Execute(Stream &error_stream, ExecutionContext &exe_ctx, const
{
const char *error_cstr = err.AsCString();
if (error_cstr && error_cstr[0])
- error_stream.Printf("error: %s\n", error_cstr);
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
else
- error_stream.Printf("error: expression can't be interpreted or run\n");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
return lldb::eExpressionDiscarded;
}
result.reset(new ExpressionVariable(ExpressionVariable::eKindGo));
diff --git a/source/Plugins/ExpressionParser/Go/GoUserExpression.h b/source/Plugins/ExpressionParser/Go/GoUserExpression.h
index b429c68f023d..711a4c46215d 100644
--- a/source/Plugins/ExpressionParser/Go/GoUserExpression.h
+++ b/source/Plugins/ExpressionParser/Go/GoUserExpression.h
@@ -62,32 +62,34 @@ class GoPersistentExpressionState : public PersistentExpressionState
class GoUserExpression : public UserExpression
{
public:
- GoUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
- lldb::LanguageType language, ResultType desired_type, const EvaluateExpressionOptions &options);
-
- bool
- Parse(Stream &error_stream, ExecutionContext &exe_ctx, lldb_private::ExecutionPolicy execution_policy,
- bool keep_result_in_memory, bool generate_debug_info) override;
-
- lldb::ExpressionResults
- Execute(Stream &error_stream, ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions &options,
- lldb::UserExpressionSP &shared_ptr_to_me,
- lldb::ExpressionVariableSP &result) override;
-
- bool
- CanInterpret() override
- {
- return true;
- }
- bool
- FinalizeJITExecution(Stream &error_stream, ExecutionContext &exe_ctx, lldb::ExpressionVariableSP &result,
- lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
- lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override
- {
- return true;
+ GoUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
+ lldb::LanguageType language, ResultType desired_type, const EvaluateExpressionOptions &options);
+
+ bool
+ Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
+ bool generate_debug_info) override;
+
+ bool
+ CanInterpret() override
+ {
+ return true;
+ }
+ bool
+ FinalizeJITExecution(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb::ExpressionVariableSP &result,
+ lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
+ lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override
+ {
+ return true;
}
+ protected:
+ lldb::ExpressionResults
+ DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me,
+ lldb::ExpressionVariableSP &result) override;
+
private:
class GoInterpreter;
std::unique_ptr<GoInterpreter> m_interpreter;
diff --git a/source/Plugins/ExpressionParser/Go/Makefile b/source/Plugins/ExpressionParser/Go/Makefile
deleted file mode 100644
index c5bd7fb2857e..000000000000
--- a/source/Plugins/ExpressionParser/Go/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ExpressionParser/Clang ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginExpressionParserGo
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index d646d4d4754a..884078b27175 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -13004,7 +13004,7 @@ EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address
{
if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
{
- if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
+ if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || m_arch.IsAlwaysThumbInstructions ())
m_opcode_mode = eModeThumb;
else
{
@@ -13017,7 +13017,7 @@ EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address
else
return false;
}
- if (m_opcode_mode == eModeThumb)
+ if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions ())
m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
else
m_opcode_cpsr = CPSR_MODE_USR;
@@ -13040,7 +13040,7 @@ EmulateInstructionARM::ReadInstruction ()
read_inst_context.type = eContextReadOpcode;
read_inst_context.SetNoArgs ();
- if (m_opcode_cpsr & MASK_CPSR_T)
+ if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions ())
{
m_opcode_mode = eModeThumb;
uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
@@ -13062,6 +13062,15 @@ EmulateInstructionARM::ReadInstruction ()
m_opcode_mode = eModeARM;
m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
}
+
+ if (!m_ignore_conditions)
+ {
+ // If we are not ignoreing the conditions then init the it session from the current
+ // value of cpsr.
+ uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | Bits32(m_opcode_cpsr, 26, 25);
+ if (it != 0)
+ m_it_session.InitIT(it);
+ }
}
}
if (!success)
@@ -13572,20 +13581,13 @@ EmulateInstructionARM::WriteFlags (Context &context,
bool
EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
{
- // Advance the ITSTATE bits to their values for the next instruction.
- if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
- m_it_session.ITAdvance();
-
ARMOpcode *opcode_data = NULL;
if (m_opcode_mode == eModeThumb)
opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
else if (m_opcode_mode == eModeARM)
opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
-
- if (opcode_data == NULL)
- return false;
-
+
const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
@@ -13609,41 +13611,48 @@ EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
if (!success)
return false;
}
-
- // Call the Emulate... function.
- success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
- if (!success)
- return false;
-
+
+ // Call the Emulate... function if we managed to decode the opcode.
+ if (opcode_data)
+ {
+ success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
+ if (!success)
+ return false;
+ }
+
+ // Advance the ITSTATE bits to their values for the next instruction if we haven't just executed
+ // an IT instruction what initialized it.
+ if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
+ (opcode_data == nullptr || opcode_data->callback != &EmulateInstructionARM::EmulateIT))
+ m_it_session.ITAdvance();
+
if (auto_advance_pc)
{
uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
if (!success)
return false;
-
+
if (auto_advance_pc && (after_pc_value == orig_pc_value))
{
- if (opcode_data->size == eSize32)
- after_pc_value += 4;
- else if (opcode_data->size == eSize16)
- after_pc_value += 2;
-
+ after_pc_value += m_opcode.GetByteSize();
+
EmulateInstruction::Context context;
context.type = eContextAdvancePC;
context.SetNoArgs();
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
return false;
-
}
}
return true;
}
-bool
-EmulateInstructionARM::IsInstructionConditional()
+EmulateInstruction::InstructionCondition
+EmulateInstructionARM::GetInstructionCondition()
{
const uint32_t cond = CurrentCond (m_opcode.GetOpcode32());
- return cond != 0xe && cond != 0xf && cond != UINT32_MAX;
+ if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
+ return EmulateInstruction::UnconditionalCondition;
+ return cond;
}
bool
@@ -13669,19 +13678,19 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option
}
test_opcode = value_sp->GetUInt64Value ();
- if (arch.GetTriple().getArch() == llvm::Triple::arm)
- {
- m_opcode_mode = eModeARM;
- m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
- }
- else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
+
+ if (arch.GetTriple().getArch() == llvm::Triple::thumb || arch.IsAlwaysThumbInstructions ())
{
m_opcode_mode = eModeThumb;
if (test_opcode < 0x10000)
- m_opcode.SetOpcode16 (test_opcode, GetByteOrder());
+ m_opcode.SetOpcode16 (test_opcode, endian::InlHostByteOrder());
else
- m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
-
+ m_opcode.SetOpcode32 (test_opcode, endian::InlHostByteOrder());
+ }
+ else if (arch.GetTriple().getArch() == llvm::Triple::arm)
+ {
+ m_opcode_mode = eModeARM;
+ m_opcode.SetOpcode32 (test_opcode, endian::InlHostByteOrder());
}
else
{
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
index 893f43f19977..6e75a3db2eb5 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
+++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
@@ -166,8 +166,8 @@ public:
bool
EvaluateInstruction (uint32_t evaluate_options) override;
- bool
- IsInstructionConditional() override;
+ InstructionCondition
+ GetInstructionCondition() override;
bool
TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) override;
diff --git a/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
index 6072264f1efc..547db44ebfb2 100644
--- a/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
@@ -61,11 +61,15 @@ EmulationStateARM::LoadPseudoRegistersFromFrame (StackFrame &frame)
if (reg_ctx->ReadRegister (reg_info, reg_value))
{
+ uint64_t value = reg_value.GetAsUInt64();
uint32_t idx = i - dwarf_d0;
if (i < 16)
- m_vfp_regs.sd_regs[idx].d_reg = reg_value.GetAsUInt64();
+ {
+ m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
+ m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
+ }
else
- m_vfp_regs.d_regs[idx - 16] = reg_value.GetAsUInt64();
+ m_vfp_regs.d_regs[idx - 16] = value;
}
else
success = false;
@@ -82,16 +86,18 @@ EmulationStateARM::StorePseudoRegisterValue (uint32_t reg_num, uint64_t value)
else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31))
{
uint32_t idx = reg_num - dwarf_s0;
- m_vfp_regs.sd_regs[idx / 2].s_reg[idx % 2] = (uint32_t) value;
+ m_vfp_regs.s_regs[idx] = (uint32_t)value;
}
else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31))
{
- if ((reg_num - dwarf_d0) < 16)
+ uint32_t idx = reg_num - dwarf_d0;
+ if (idx < 16)
{
- m_vfp_regs.sd_regs[reg_num - dwarf_d0].d_reg = value;
+ m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
+ m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
}
else
- m_vfp_regs.d_regs[reg_num - dwarf_d16] = value;
+ m_vfp_regs.d_regs[idx - 16] = value;
}
else
return false;
@@ -110,14 +116,15 @@ EmulationStateARM::ReadPseudoRegisterValue (uint32_t reg_num, bool &success)
else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31))
{
uint32_t idx = reg_num - dwarf_s0;
- value = m_vfp_regs.sd_regs[idx / 2].s_reg[idx % 2];
+ value = m_vfp_regs.d_regs[idx];
}
else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31))
{
- if ((reg_num - dwarf_d0) < 16)
- value = m_vfp_regs.sd_regs[reg_num - dwarf_d0].d_reg;
+ uint32_t idx = reg_num - dwarf_d0;
+ if (idx < 16)
+ value = (uint64_t)m_vfp_regs.s_regs[idx * 2] | ((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] >> 32);
else
- value = m_vfp_regs.d_regs[reg_num - dwarf_d16];
+ value = m_vfp_regs.d_regs[idx - 16];
}
else
success = false;
@@ -131,8 +138,8 @@ EmulationStateARM::ClearPseudoRegisters ()
for (int i = 0; i < 17; ++i)
m_gpr[i] = 0;
- for (int i = 0; i < 16; ++i)
- m_vfp_regs.sd_regs[i].d_reg = 0;
+ for (int i = 0; i < 32; ++i)
+ m_vfp_regs.s_regs[i] = 0;
for (int i = 0; i < 16; ++i)
m_vfp_regs.d_regs[i] = 0;
@@ -145,23 +152,14 @@ EmulationStateARM::ClearPseudoMemory ()
}
bool
-EmulationStateARM::StoreToPseudoAddress (lldb::addr_t p_address, uint64_t value, uint32_t size)
+EmulationStateARM::StoreToPseudoAddress (lldb::addr_t p_address, uint32_t value)
{
- if (size > 8)
- return false;
-
- if (size <= 4)
- m_memory[p_address] = value;
- else if (size == 8)
- {
- m_memory[p_address] = (value << 32) >> 32;
- m_memory[p_address + 4] = value << 32;
- }
+ m_memory[p_address] = value;
return true;
}
uint32_t
-EmulationStateARM::ReadFromPseudoAddress (lldb::addr_t p_address, uint32_t size, bool &success)
+EmulationStateARM::ReadFromPseudoAddress (lldb::addr_t p_address, bool &success)
{
std::map<lldb::addr_t,uint32_t>::iterator pos;
uint32_t ret_val = 0;
@@ -191,25 +189,31 @@ EmulationStateARM::ReadPseudoMemory (EmulateInstruction *instruction,
EmulationStateARM *pseudo_state = (EmulationStateARM *) baton;
if (length <= 4)
{
- uint32_t value = pseudo_state->ReadFromPseudoAddress (addr, length, success);
+ uint32_t value = pseudo_state->ReadFromPseudoAddress (addr, success);
if (!success)
return 0;
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
+ value = llvm::ByteSwap_32 (value);
*((uint32_t *) dst) = value;
}
else if (length == 8)
{
- uint32_t value1 = pseudo_state->ReadFromPseudoAddress (addr, 4, success);
+ uint32_t value1 = pseudo_state->ReadFromPseudoAddress (addr, success);
if (!success)
return 0;
- uint32_t value2 = pseudo_state->ReadFromPseudoAddress (addr + 4, 4, success);
+ uint32_t value2 = pseudo_state->ReadFromPseudoAddress (addr + 4, success);
if (!success)
return 0;
- uint64_t value64 = value2;
- value64 = (value64 << 32) | value1;
- *((uint64_t *) dst) = value64;
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
+ {
+ value1 = llvm::ByteSwap_32 (value1);
+ value2 = llvm::ByteSwap_32 (value2);
+ }
+ ((uint32_t *) dst)[0] = value1;
+ ((uint32_t *) dst)[1] = value2;
}
else
success = false;
@@ -231,13 +235,32 @@ EmulationStateARM::WritePseudoMemory (EmulateInstruction *instruction,
if (!baton)
return 0;
- bool success;
EmulationStateARM *pseudo_state = (EmulationStateARM *) baton;
- uint64_t value = *((const uint64_t *) dst);
- success = pseudo_state->StoreToPseudoAddress (addr, value, length);
- if (success)
+
+ if (length <= 4)
+ {
+ uint32_t value = *((const uint32_t *) dst);
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
+ value = llvm::ByteSwap_32 (value);
+
+ pseudo_state->StoreToPseudoAddress (addr, value);
return length;
-
+ }
+ else if (length == 8)
+ {
+ uint32_t value1 = ((const uint32_t *) dst)[0];
+ uint32_t value2 = ((const uint32_t *) dst)[1];
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
+ {
+ value1 = llvm::ByteSwap_32 (value1);
+ value2 = llvm::ByteSwap_32 (value2);
+ }
+
+ pseudo_state->StoreToPseudoAddress (addr, value1);
+ pseudo_state->StoreToPseudoAddress (addr + 4, value2);
+ return length;
+ }
+
return 0;
}
@@ -289,27 +312,16 @@ EmulationStateARM::CompareState (EmulationStateARM &other_state)
match = false;
}
- for (int i = 0; match && i < 16; ++i)
+ for (int i = 0; match && i < 32; ++i)
{
- if (m_vfp_regs.sd_regs[i].s_reg[0] != other_state.m_vfp_regs.sd_regs[i].s_reg[0])
- match = false;
-
- if (m_vfp_regs.sd_regs[i].s_reg[1] != other_state.m_vfp_regs.sd_regs[i].s_reg[1])
+ if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i])
match = false;
}
- for (int i = 0; match && i < 32; ++i)
+ for (int i = 0; match && i < 16; ++i)
{
- if (i < 16)
- {
- if (m_vfp_regs.sd_regs[i].d_reg != other_state.m_vfp_regs.sd_regs[i].d_reg)
- match = false;
- }
- else
- {
- if (m_vfp_regs.d_regs[i - 16] != other_state.m_vfp_regs.d_regs[i - 16])
- match = false;
- }
+ if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i])
+ match = false;
}
return match;
@@ -355,7 +367,7 @@ EmulationStateARM::LoadStateFromDictionary (OptionValueDictionary *test_data)
if (value_sp.get() == NULL)
return false;
uint64_t value = value_sp->GetUInt64Value();
- StoreToPseudoAddress (address, value, 4);
+ StoreToPseudoAddress (address, value);
address = address + 4;
}
}
diff --git a/source/Plugins/Instruction/ARM/EmulationStateARM.h b/source/Plugins/Instruction/ARM/EmulationStateARM.h
index ad596a3c2779..e82ef94b5a01 100644
--- a/source/Plugins/Instruction/ARM/EmulationStateARM.h
+++ b/source/Plugins/Instruction/ARM/EmulationStateARM.h
@@ -30,10 +30,10 @@ public:
ReadPseudoRegisterValue (uint32_t reg_num, bool &success);
bool
- StoreToPseudoAddress (lldb::addr_t p_address, uint64_t value, uint32_t size);
+ StoreToPseudoAddress (lldb::addr_t p_address, uint32_t value);
uint32_t
- ReadFromPseudoAddress (lldb::addr_t p_address, uint32_t size, bool &success);
+ ReadFromPseudoAddress (lldb::addr_t p_address, bool &success);
void
ClearPseudoRegisters ();
@@ -82,11 +82,7 @@ private:
uint32_t m_gpr[17];
struct _sd_regs
{
- union
- {
- uint32_t s_reg[2];
- uint64_t d_reg;
- } sd_regs[16]; // sregs 0 - 31 & dregs 0 - 15
+ uint32_t s_regs[32]; // sregs 0 - 31 & dregs 0 - 15
uint64_t d_regs[16]; // dregs 16-31
diff --git a/source/Plugins/Instruction/ARM/Makefile b/source/Plugins/Instruction/ARM/Makefile
deleted file mode 100644
index 31a233b0b374..000000000000
--- a/source/Plugins/Instruction/ARM/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Instruction/ARM/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginInstructionARM
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
index 372ccf9b05f4..ea67928280d3 100644
--- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
+++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
@@ -980,7 +980,7 @@ EmulateInstructionARM64::EmulateLDRSTRImm (const uint32_t opcode)
if (!WriteRegister (context, &reg_info_Rt, data_Rt))
return false;
-
+ break;
default:
return false;
}
diff --git a/source/Plugins/Instruction/ARM64/Makefile b/source/Plugins/Instruction/ARM64/Makefile
deleted file mode 100644
index 8f60ce6dcd47..000000000000
--- a/source/Plugins/Instruction/ARM64/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Instruction/ARM/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginInstructionARM64
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index a71fca7c5c3a..99856a3684cb 100644
--- a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -17,7 +17,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCContext.h"
@@ -1142,7 +1142,7 @@ EmulateInstructionMIPS::Emulate_SWSP (llvm::MCInst& insn)
// We look for sp based non-volatile register stores.
if (base == dwarf_sp_mips && nonvolatile_reg_p (src))
{
- RegisterInfo reg_info_src;
+ RegisterInfo reg_info_src = {};
Context context;
RegisterValue data_src;
context.type = eContextPushRegisterOnStack;
@@ -1482,56 +1482,56 @@ EmulateInstructionMIPS::Emulate_BXX_3ops_C (llvm::MCInst& insn)
if (!strcasecmp (op_name, "BEQC"))
{
if (rs_val == rt_val)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BNEC"))
{
if (rs_val != rt_val)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BLTC"))
{
if (rs_val < rt_val)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BGEC"))
{
if (rs_val >= rt_val)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BLTUC"))
{
if (rs_val < rt_val)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BGEUC"))
{
if ((uint32_t)rs_val >= (uint32_t)rt_val)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BOVC"))
{
if (IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BNVC"))
{
if (!IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
@@ -1773,42 +1773,42 @@ EmulateInstructionMIPS::Emulate_BXX_2ops_C (llvm::MCInst& insn)
if (!strcasecmp (op_name, "BLTZC"))
{
if (rs_val < 0)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BLEZC"))
{
if (rs_val <= 0)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BGEZC"))
{
if (rs_val >= 0)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BGTZC"))
{
if (rs_val > 0)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BEQZC"))
{
if (rs_val == 0)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BNEZC"))
{
if (rs_val != 0)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
@@ -2129,7 +2129,7 @@ EmulateInstructionMIPS::Emulate_BALC (llvm::MCInst& insn)
if (!success)
return false;
- target = pc + 4 + offset;
+ target = pc + offset;
Context context;
@@ -2159,7 +2159,7 @@ EmulateInstructionMIPS::Emulate_BC (llvm::MCInst& insn)
if (!success)
return false;
- target = pc + 4 + offset;
+ target = pc + offset;
Context context;
@@ -2603,7 +2603,7 @@ EmulateInstructionMIPS::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_b
bool success = false, branch_hit = true;
int32_t target = 0;
RegisterValue reg_value;
- uint8_t * ptr = NULL;
+ const uint8_t *ptr = NULL;
uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
int32_t offset = insn.getOperand(1).getImm();
@@ -2613,7 +2613,7 @@ EmulateInstructionMIPS::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_b
return false;
if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
- ptr = (uint8_t *)reg_value.GetBytes();
+ ptr = (const uint8_t *)reg_value.GetBytes();
else
return false;
@@ -2626,15 +2626,15 @@ EmulateInstructionMIPS::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_b
branch_hit = false;
break;
case 2:
- if((*(uint16_t *)ptr == 0 && bnz) || (*(uint16_t *)ptr != 0 && !bnz))
+ if ((*(const uint16_t *)ptr == 0 && bnz) || (*(const uint16_t *)ptr != 0 && !bnz))
branch_hit = false;
break;
case 4:
- if((*(uint32_t *)ptr == 0 && bnz) || (*(uint32_t *)ptr != 0 && !bnz))
+ if ((*(const uint32_t *)ptr == 0 && bnz) || (*(const uint32_t *)ptr != 0 && !bnz))
branch_hit = false;
break;
case 8:
- if((*(uint64_t *)ptr == 0 && bnz) || (*(uint64_t *)ptr != 0 && !bnz))
+ if ((*(const uint64_t *)ptr == 0 && bnz) || (*(const uint64_t *)ptr != 0 && !bnz))
branch_hit = false;
break;
}
diff --git a/source/Plugins/Instruction/MIPS/Makefile b/source/Plugins/Instruction/MIPS/Makefile
deleted file mode 100644
index e9cef4ba0cf7..000000000000
--- a/source/Plugins/Instruction/MIPS/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Instruction/MIPS/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginInstructionMIPS
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index 9c09d383beae..dd071b00de31 100644
--- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -17,7 +17,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCContext.h"
@@ -483,6 +483,7 @@ EmulateInstructionMIPS64::GetOpcodeForInstruction (const char *op_name)
// Prologue/Epilogue instructions
//----------------------------------------------------------------------
{ "DADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu, "DADDIU rt,rs,immediate" },
+ { "ADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu, "ADDIU rt,rs,immediate" },
{ "SD", &EmulateInstructionMIPS64::Emulate_SD, "SD rt,offset(rs)" },
{ "LD", &EmulateInstructionMIPS64::Emulate_LD, "LD rt,offset(base)" },
@@ -1066,7 +1067,7 @@ EmulateInstructionMIPS64::Emulate_BALC (llvm::MCInst& insn)
if (!success)
return false;
- target = pc + 4 + offset;
+ target = pc + offset;
Context context;
@@ -1240,7 +1241,7 @@ EmulateInstructionMIPS64::Emulate_BC (llvm::MCInst& insn)
if (!success)
return false;
- target = pc + 4 + offset;
+ target = pc + offset;
Context context;
@@ -1289,56 +1290,56 @@ EmulateInstructionMIPS64::Emulate_BXX_3ops_C (llvm::MCInst& insn)
if (!strcasecmp (op_name, "BEQC"))
{
if (rs_val == rt_val)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BNEC"))
{
if (rs_val != rt_val)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BLTC"))
{
if (rs_val < rt_val)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BGEC"))
{
if (rs_val >= rt_val)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BLTUC"))
{
if (rs_val < rt_val)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BGEUC"))
{
if ((uint32_t)rs_val >= (uint32_t)rt_val)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BOVC"))
{
if (IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BNVC"))
{
if (!IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
@@ -1381,42 +1382,42 @@ EmulateInstructionMIPS64::Emulate_BXX_2ops_C (llvm::MCInst& insn)
if (!strcasecmp (op_name, "BLTZC"))
{
if (rs_val < 0)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BLEZC"))
{
if (rs_val <= 0)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BGEZC"))
{
if (rs_val >= 0)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BGTZC"))
{
if (rs_val > 0)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BEQZC"))
{
if (rs_val == 0)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
else if (!strcasecmp (op_name, "BNEZC"))
{
if (rs_val != 0)
- target = pc + 4 + offset;
+ target = pc + offset;
else
target = pc + 4;
}
@@ -1874,7 +1875,7 @@ EmulateInstructionMIPS64::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element
bool success = false, branch_hit = true;
int64_t target = 0;
RegisterValue reg_value;
- uint8_t * ptr = NULL;
+ const uint8_t *ptr = NULL;
uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
int64_t offset = insn.getOperand(1).getImm();
@@ -1884,7 +1885,7 @@ EmulateInstructionMIPS64::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element
return false;
if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
- ptr = (uint8_t *)reg_value.GetBytes();
+ ptr = (const uint8_t *)reg_value.GetBytes();
else
return false;
@@ -1897,15 +1898,15 @@ EmulateInstructionMIPS64::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element
branch_hit = false;
break;
case 2:
- if((*(uint16_t *)ptr == 0 && bnz) || (*(uint16_t *)ptr != 0 && !bnz))
+ if ((*(const uint16_t *)ptr == 0 && bnz) || (*(const uint16_t *)ptr != 0 && !bnz))
branch_hit = false;
break;
case 4:
- if((*(uint32_t *)ptr == 0 && bnz) || (*(uint32_t *)ptr != 0 && !bnz))
+ if ((*(const uint32_t *)ptr == 0 && bnz) || (*(const uint32_t *)ptr != 0 && !bnz))
branch_hit = false;
break;
case 8:
- if((*(uint64_t *)ptr == 0 && bnz) || (*(uint64_t *)ptr != 0 && !bnz))
+ if ((*(const uint64_t *)ptr == 0 && bnz) || (*(const uint64_t *)ptr != 0 && !bnz))
branch_hit = false;
break;
}
diff --git a/source/Plugins/Instruction/MIPS64/Makefile b/source/Plugins/Instruction/MIPS64/Makefile
deleted file mode 100644
index 7e5b339a359d..000000000000
--- a/source/Plugins/Instruction/MIPS64/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Instruction/MIPS64/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginInstructionMIPS64
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp b/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp
index c2f1f2e95c83..99857cd3d1b0 100644
--- a/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp
@@ -19,6 +19,7 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -97,8 +98,8 @@ AddressSanitizerRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list)
Activate();
return;
}
-
- Mutex::Locker modules_locker(module_list.GetMutex());
+
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
const size_t num_modules = module_list.GetSize();
for (size_t i = 0; i < num_modules; ++i)
{
@@ -127,9 +128,10 @@ AddressSanitizerRuntime::IsActive()
}
#define RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC 2*1000*1000
-
const char *
-address_sanitizer_retrieve_report_data_command = R"(
+address_sanitizer_retrieve_report_data_prefix = R"(
+extern "C"
+{
int __asan_report_present();
void *__asan_get_report_pc();
void *__asan_get_report_bp();
@@ -138,6 +140,11 @@ void *__asan_get_report_address();
const char *__asan_get_report_description();
int __asan_get_report_access_type();
size_t __asan_get_report_access_size();
+}
+)";
+
+const char *
+address_sanitizer_retrieve_report_data_command = R"(
struct {
int present;
int access_type;
@@ -167,7 +174,7 @@ AddressSanitizerRuntime::RetrieveReportData()
if (!process_sp)
return StructuredData::ObjectSP();
- ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread();
+ ThreadSP thread_sp = process_sp->GetThreadList().GetExpressionExecutionThread();
StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
if (!frame_sp)
@@ -179,10 +186,24 @@ AddressSanitizerRuntime::RetrieveReportData()
options.SetStopOthers(true);
options.SetIgnoreBreakpoints(true);
options.SetTimeoutUsec(RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC);
+ options.SetPrefix(address_sanitizer_retrieve_report_data_prefix);
+ options.SetAutoApplyFixIts(false);
+ options.SetLanguage(eLanguageTypeObjC_plus_plus);
ValueObjectSP return_value_sp;
- if (process_sp->GetTarget().EvaluateExpression(address_sanitizer_retrieve_report_data_command, frame_sp.get(), return_value_sp, options) != eExpressionCompleted)
+ ExecutionContext exe_ctx;
+ Error eval_error;
+ frame_sp->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result = UserExpression::Evaluate (exe_ctx,
+ options,
+ address_sanitizer_retrieve_report_data_command,
+ "",
+ return_value_sp,
+ eval_error);
+ if (result != eExpressionCompleted) {
+ process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf("Warning: Cannot evaluate AddressSanitizer expression:\n%s\n", eval_error.AsCString());
return StructuredData::ObjectSP();
+ }
int present = return_value_sp->GetValueForExpressionPath(".present")->GetValueAsUnsigned(0);
if (present != 1)
diff --git a/source/Plugins/InstrumentationRuntime/AddressSanitizer/Makefile b/source/Plugins/InstrumentationRuntime/AddressSanitizer/Makefile
deleted file mode 100644
index 030aec17b026..000000000000
--- a/source/Plugins/InstrumentationRuntime/AddressSanitizer/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/InstrumentationRuntime/AddressSanitizer Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginInstrumentationRuntimeAddressSanitizer
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/InstrumentationRuntime/CMakeLists.txt b/source/Plugins/InstrumentationRuntime/CMakeLists.txt
index 8ee303b25359..ae7c6e5972d3 100644
--- a/source/Plugins/InstrumentationRuntime/CMakeLists.txt
+++ b/source/Plugins/InstrumentationRuntime/CMakeLists.txt
@@ -1 +1,2 @@
add_subdirectory(AddressSanitizer)
+add_subdirectory(ThreadSanitizer)
diff --git a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/CMakeLists.txt b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/CMakeLists.txt
new file mode 100644
index 000000000000..6ef79433d67a
--- /dev/null
+++ b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_lldb_library(lldbPluginInstrumentationRuntimeThreadSanitizer
+ ThreadSanitizerRuntime.cpp
+ )
diff --git a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
new file mode 100644
index 000000000000..62e5ce63a542
--- /dev/null
+++ b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
@@ -0,0 +1,887 @@
+//===-- ThreadSanitizerRuntime.cpp ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ThreadSanitizerRuntime.h"
+
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/UserExpression.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/Variable.h"
+#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/InstrumentationRuntimeStopInfo.h"
+#include "lldb/Target/SectionLoadList.h"
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "Plugins/Process/Utility/HistoryThread.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+lldb::InstrumentationRuntimeSP
+ThreadSanitizerRuntime::CreateInstance (const lldb::ProcessSP &process_sp)
+{
+ return InstrumentationRuntimeSP(new ThreadSanitizerRuntime(process_sp));
+}
+
+void
+ThreadSanitizerRuntime::Initialize()
+{
+ PluginManager::RegisterPlugin (GetPluginNameStatic(),
+ "ThreadSanitizer instrumentation runtime plugin.",
+ CreateInstance,
+ GetTypeStatic);
+}
+
+void
+ThreadSanitizerRuntime::Terminate()
+{
+ PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+lldb_private::ConstString
+ThreadSanitizerRuntime::GetPluginNameStatic()
+{
+ return ConstString("ThreadSanitizer");
+}
+
+lldb::InstrumentationRuntimeType
+ThreadSanitizerRuntime::GetTypeStatic()
+{
+ return eInstrumentationRuntimeTypeThreadSanitizer;
+}
+
+ThreadSanitizerRuntime::ThreadSanitizerRuntime(const ProcessSP &process_sp) :
+m_is_active(false),
+m_runtime_module_wp(),
+m_process_wp(),
+m_breakpoint_id(0)
+{
+ if (process_sp)
+ m_process_wp = process_sp;
+}
+
+ThreadSanitizerRuntime::~ThreadSanitizerRuntime()
+{
+ Deactivate();
+}
+
+static bool
+ModuleContainsTSanRuntime(ModuleSP module_sp)
+{
+ static ConstString g_tsan_get_current_report("__tsan_get_current_report");
+ const Symbol* symbol = module_sp->FindFirstSymbolWithNameAndType(g_tsan_get_current_report, lldb::eSymbolTypeAny);
+ return symbol != nullptr;
+}
+
+void
+ThreadSanitizerRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list)
+{
+ if (IsActive())
+ return;
+
+ if (GetRuntimeModuleSP()) {
+ Activate();
+ return;
+ }
+
+ module_list.ForEach ([this](const lldb::ModuleSP module_sp) -> bool
+ {
+ const FileSpec & file_spec = module_sp->GetFileSpec();
+ if (! file_spec)
+ return true; // Keep iterating through modules
+
+ llvm::StringRef module_basename(file_spec.GetFilename().GetStringRef());
+ if (module_sp->IsExecutable() || module_basename.startswith("libclang_rt.tsan_"))
+ {
+ if (ModuleContainsTSanRuntime(module_sp))
+ {
+ m_runtime_module_wp = module_sp;
+ Activate();
+ return false; // Stop iterating
+ }
+ }
+
+ return true; // Keep iterating through modules
+ });
+}
+
+bool
+ThreadSanitizerRuntime::IsActive()
+{
+ return m_is_active;
+}
+
+#define RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC 2*1000*1000
+
+const char *
+thread_sanitizer_retrieve_report_data_prefix = R"(
+extern "C"
+{
+ void *__tsan_get_current_report();
+ int __tsan_get_report_data(void *report, const char **description, int *count,
+ int *stack_count, int *mop_count, int *loc_count,
+ int *mutex_count, int *thread_count,
+ int *unique_tid_count, void **sleep_trace,
+ unsigned long trace_size);
+ int __tsan_get_report_stack(void *report, unsigned long idx, void **trace,
+ unsigned long trace_size);
+ int __tsan_get_report_mop(void *report, unsigned long idx, int *tid, void **addr,
+ int *size, int *write, int *atomic, void **trace,
+ unsigned long trace_size);
+ int __tsan_get_report_loc(void *report, unsigned long idx, const char **type,
+ void **addr, unsigned long *start, unsigned long *size, int *tid,
+ int *fd, int *suppressable, void **trace,
+ unsigned long trace_size);
+ int __tsan_get_report_mutex(void *report, unsigned long idx, unsigned long *mutex_id, void **addr,
+ int *destroyed, void **trace, unsigned long trace_size);
+ int __tsan_get_report_thread(void *report, unsigned long idx, int *tid, unsigned long *os_id,
+ int *running, const char **name, int *parent_tid,
+ void **trace, unsigned long trace_size);
+ int __tsan_get_report_unique_tid(void *report, unsigned long idx, int *tid);
+}
+
+const int REPORT_TRACE_SIZE = 128;
+const int REPORT_ARRAY_SIZE = 4;
+
+struct data {
+ void *report;
+ const char *description;
+ int report_count;
+
+ void *sleep_trace[REPORT_TRACE_SIZE];
+
+ int stack_count;
+ struct {
+ int idx;
+ void *trace[REPORT_TRACE_SIZE];
+ } stacks[REPORT_ARRAY_SIZE];
+
+ int mop_count;
+ struct {
+ int idx;
+ int tid;
+ int size;
+ int write;
+ int atomic;
+ void *addr;
+ void *trace[REPORT_TRACE_SIZE];
+ } mops[REPORT_ARRAY_SIZE];
+
+ int loc_count;
+ struct {
+ int idx;
+ const char *type;
+ void *addr;
+ unsigned long start;
+ unsigned long size;
+ int tid;
+ int fd;
+ int suppressable;
+ void *trace[REPORT_TRACE_SIZE];
+ } locs[REPORT_ARRAY_SIZE];
+
+ int mutex_count;
+ struct {
+ int idx;
+ unsigned long mutex_id;
+ void *addr;
+ int destroyed;
+ void *trace[REPORT_TRACE_SIZE];
+ } mutexes[REPORT_ARRAY_SIZE];
+
+ int thread_count;
+ struct {
+ int idx;
+ int tid;
+ unsigned long os_id;
+ int running;
+ const char *name;
+ int parent_tid;
+ void *trace[REPORT_TRACE_SIZE];
+ } threads[REPORT_ARRAY_SIZE];
+
+ int unique_tid_count;
+ struct {
+ int idx;
+ int tid;
+ } unique_tids[REPORT_ARRAY_SIZE];
+};
+)";
+
+const char *
+thread_sanitizer_retrieve_report_data_command = R"(
+data t = {0};
+
+t.report = __tsan_get_current_report();
+__tsan_get_report_data(t.report, &t.description, &t.report_count, &t.stack_count, &t.mop_count, &t.loc_count, &t.mutex_count, &t.thread_count, &t.unique_tid_count, t.sleep_trace, REPORT_TRACE_SIZE);
+
+if (t.stack_count > REPORT_ARRAY_SIZE) t.stack_count = REPORT_ARRAY_SIZE;
+for (int i = 0; i < t.stack_count; i++) {
+ t.stacks[i].idx = i;
+ __tsan_get_report_stack(t.report, i, t.stacks[i].trace, REPORT_TRACE_SIZE);
+}
+
+if (t.mop_count > REPORT_ARRAY_SIZE) t.mop_count = REPORT_ARRAY_SIZE;
+for (int i = 0; i < t.mop_count; i++) {
+ t.mops[i].idx = i;
+ __tsan_get_report_mop(t.report, i, &t.mops[i].tid, &t.mops[i].addr, &t.mops[i].size, &t.mops[i].write, &t.mops[i].atomic, t.mops[i].trace, REPORT_TRACE_SIZE);
+}
+
+if (t.loc_count > REPORT_ARRAY_SIZE) t.loc_count = REPORT_ARRAY_SIZE;
+for (int i = 0; i < t.loc_count; i++) {
+ t.locs[i].idx = i;
+ __tsan_get_report_loc(t.report, i, &t.locs[i].type, &t.locs[i].addr, &t.locs[i].start, &t.locs[i].size, &t.locs[i].tid, &t.locs[i].fd, &t.locs[i].suppressable, t.locs[i].trace, REPORT_TRACE_SIZE);
+}
+
+if (t.mutex_count > REPORT_ARRAY_SIZE) t.mutex_count = REPORT_ARRAY_SIZE;
+for (int i = 0; i < t.mutex_count; i++) {
+ t.mutexes[i].idx = i;
+ __tsan_get_report_mutex(t.report, i, &t.mutexes[i].mutex_id, &t.mutexes[i].addr, &t.mutexes[i].destroyed, t.mutexes[i].trace, REPORT_TRACE_SIZE);
+}
+
+if (t.thread_count > REPORT_ARRAY_SIZE) t.thread_count = REPORT_ARRAY_SIZE;
+for (int i = 0; i < t.thread_count; i++) {
+ t.threads[i].idx = i;
+ __tsan_get_report_thread(t.report, i, &t.threads[i].tid, &t.threads[i].os_id, &t.threads[i].running, &t.threads[i].name, &t.threads[i].parent_tid, t.threads[i].trace, REPORT_TRACE_SIZE);
+}
+
+if (t.unique_tid_count > REPORT_ARRAY_SIZE) t.unique_tid_count = REPORT_ARRAY_SIZE;
+for (int i = 0; i < t.unique_tid_count; i++) {
+ t.unique_tids[i].idx = i;
+ __tsan_get_report_unique_tid(t.report, i, &t.unique_tids[i].tid);
+}
+
+t;
+)";
+
+static StructuredData::Array *
+CreateStackTrace(ValueObjectSP o, std::string trace_item_name = ".trace") {
+ StructuredData::Array *trace = new StructuredData::Array();
+ ValueObjectSP trace_value_object = o->GetValueForExpressionPath(trace_item_name.c_str());
+ for (int j = 0; j < 8; j++) {
+ addr_t trace_addr = trace_value_object->GetChildAtIndex(j, true)->GetValueAsUnsigned(0);
+ if (trace_addr == 0)
+ break;
+ trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(trace_addr)));
+ }
+ return trace;
+}
+
+static StructuredData::Array *
+ConvertToStructuredArray(ValueObjectSP return_value_sp, std::string items_name, std::string count_name, std::function <void(ValueObjectSP o, StructuredData::Dictionary *dict)> const &callback)
+{
+ StructuredData::Array *array = new StructuredData::Array();
+ unsigned int count = return_value_sp->GetValueForExpressionPath(count_name.c_str())->GetValueAsUnsigned(0);
+ ValueObjectSP objects = return_value_sp->GetValueForExpressionPath(items_name.c_str());
+ for (unsigned int i = 0; i < count; i++) {
+ ValueObjectSP o = objects->GetChildAtIndex(i, true);
+ StructuredData::Dictionary *dict = new StructuredData::Dictionary();
+
+ callback(o, dict);
+
+ array->AddItem(StructuredData::ObjectSP(dict));
+ }
+ return array;
+}
+
+static std::string
+RetrieveString(ValueObjectSP return_value_sp, ProcessSP process_sp, std::string expression_path)
+{
+ addr_t ptr = return_value_sp->GetValueForExpressionPath(expression_path.c_str())->GetValueAsUnsigned(0);
+ std::string str;
+ Error error;
+ process_sp->ReadCStringFromMemory(ptr, str, error);
+ return str;
+}
+
+static void
+GetRenumberedThreadIds(ProcessSP process_sp, ValueObjectSP data, std::map<uint64_t, user_id_t> &thread_id_map)
+{
+ ConvertToStructuredArray(data, ".threads", ".thread_count", [process_sp, &thread_id_map] (ValueObjectSP o, StructuredData::Dictionary *dict) {
+ uint64_t thread_id = o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0);
+ uint64_t thread_os_id = o->GetValueForExpressionPath(".os_id")->GetValueAsUnsigned(0);
+ user_id_t lldb_user_id = 0;
+
+ bool can_update = true;
+ ThreadSP lldb_thread = process_sp->GetThreadList().FindThreadByID(thread_os_id, can_update);
+ if (lldb_thread) {
+ lldb_user_id = lldb_thread->GetIndexID();
+ } else {
+ // This isn't a live thread anymore. Ask process to assign a new Index ID (or return an old one if we've already seen this thread_os_id).
+ // It will also make sure that no new threads are assigned this Index ID.
+ lldb_user_id = process_sp->AssignIndexIDToThread(thread_os_id);
+ }
+
+ thread_id_map[thread_id] = lldb_user_id;
+ });
+}
+
+static user_id_t Renumber(uint64_t id, std::map<uint64_t, user_id_t> &thread_id_map) {
+ if (! thread_id_map.count(id))
+ return 0;
+
+ return thread_id_map[id];
+}
+
+StructuredData::ObjectSP
+ThreadSanitizerRuntime::RetrieveReportData(ExecutionContextRef exe_ctx_ref)
+{
+ ProcessSP process_sp = GetProcessSP();
+ if (!process_sp)
+ return StructuredData::ObjectSP();
+
+ ThreadSP thread_sp = exe_ctx_ref.GetThreadSP();
+ StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
+
+ if (!frame_sp)
+ return StructuredData::ObjectSP();
+
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetTryAllThreads(true);
+ options.SetStopOthers(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTimeoutUsec(RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC);
+ options.SetPrefix(thread_sanitizer_retrieve_report_data_prefix);
+ options.SetAutoApplyFixIts(false);
+ options.SetLanguage(eLanguageTypeObjC_plus_plus);
+
+ ValueObjectSP main_value;
+ ExecutionContext exe_ctx;
+ Error eval_error;
+ frame_sp->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result = UserExpression::Evaluate (exe_ctx,
+ options,
+ thread_sanitizer_retrieve_report_data_command,
+ "",
+ main_value,
+ eval_error);
+ if (result != eExpressionCompleted) {
+ process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf("Warning: Cannot evaluate ThreadSanitizer expression:\n%s\n", eval_error.AsCString());
+ return StructuredData::ObjectSP();
+ }
+
+ std::map<uint64_t, user_id_t> thread_id_map;
+ GetRenumberedThreadIds(process_sp, main_value, thread_id_map);
+
+ StructuredData::Dictionary *dict = new StructuredData::Dictionary();
+ dict->AddStringItem("instrumentation_class", "ThreadSanitizer");
+ dict->AddStringItem("issue_type", RetrieveString(main_value, process_sp, ".description"));
+ dict->AddIntegerItem("report_count", main_value->GetValueForExpressionPath(".report_count")->GetValueAsUnsigned(0));
+ dict->AddItem("sleep_trace", StructuredData::ObjectSP(CreateStackTrace(main_value, ".sleep_trace")));
+
+ StructuredData::Array *stacks = ConvertToStructuredArray(main_value, ".stacks", ".stack_count", [thread_sp] (ValueObjectSP o, StructuredData::Dictionary *dict) {
+ dict->AddIntegerItem("index", o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
+ dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
+ // "stacks" happen on the current thread
+ dict->AddIntegerItem("thread_id", thread_sp->GetIndexID());
+ });
+ dict->AddItem("stacks", StructuredData::ObjectSP(stacks));
+
+ StructuredData::Array *mops = ConvertToStructuredArray(main_value, ".mops", ".mop_count", [&thread_id_map] (ValueObjectSP o, StructuredData::Dictionary *dict) {
+ dict->AddIntegerItem("index", o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("thread_id", Renumber(o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), thread_id_map));
+ dict->AddIntegerItem("size", o->GetValueForExpressionPath(".size")->GetValueAsUnsigned(0));
+ dict->AddBooleanItem("is_write", o->GetValueForExpressionPath(".write")->GetValueAsUnsigned(0));
+ dict->AddBooleanItem("is_atomic", o->GetValueForExpressionPath(".atomic")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("address", o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0));
+ dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
+ });
+ dict->AddItem("mops", StructuredData::ObjectSP(mops));
+
+ StructuredData::Array *locs = ConvertToStructuredArray(main_value, ".locs", ".loc_count", [process_sp, &thread_id_map] (ValueObjectSP o, StructuredData::Dictionary *dict) {
+ dict->AddIntegerItem("index", o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
+ dict->AddStringItem("type", RetrieveString(o, process_sp, ".type"));
+ dict->AddIntegerItem("address", o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("start", o->GetValueForExpressionPath(".start")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("size", o->GetValueForExpressionPath(".size")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("thread_id", Renumber(o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), thread_id_map));
+ dict->AddIntegerItem("file_descriptor", o->GetValueForExpressionPath(".fd")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("suppressable", o->GetValueForExpressionPath(".suppressable")->GetValueAsUnsigned(0));
+ dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
+ });
+ dict->AddItem("locs", StructuredData::ObjectSP(locs));
+
+ StructuredData::Array *mutexes = ConvertToStructuredArray(main_value, ".mutexes", ".mutex_count", [] (ValueObjectSP o, StructuredData::Dictionary *dict) {
+ dict->AddIntegerItem("index", o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("mutex_id", o->GetValueForExpressionPath(".mutex_id")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("address", o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("destroyed", o->GetValueForExpressionPath(".destroyed")->GetValueAsUnsigned(0));
+ dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
+ });
+ dict->AddItem("mutexes", StructuredData::ObjectSP(mutexes));
+
+ StructuredData::Array *threads = ConvertToStructuredArray(main_value, ".threads", ".thread_count", [process_sp, &thread_id_map] (ValueObjectSP o, StructuredData::Dictionary *dict) {
+ dict->AddIntegerItem("index", o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("thread_id", Renumber(o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), thread_id_map));
+ dict->AddIntegerItem("thread_os_id", o->GetValueForExpressionPath(".os_id")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("running", o->GetValueForExpressionPath(".running")->GetValueAsUnsigned(0));
+ dict->AddStringItem("name", RetrieveString(o, process_sp, ".name"));
+ dict->AddIntegerItem("parent_thread_id", Renumber(o->GetValueForExpressionPath(".parent_tid")->GetValueAsUnsigned(0), thread_id_map));
+ dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
+ });
+ dict->AddItem("threads", StructuredData::ObjectSP(threads));
+
+ StructuredData::Array *unique_tids = ConvertToStructuredArray(main_value, ".unique_tids", ".unique_tid_count", [&thread_id_map] (ValueObjectSP o, StructuredData::Dictionary *dict) {
+ dict->AddIntegerItem("index", o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("tid", Renumber(o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), thread_id_map));
+ });
+ dict->AddItem("unique_tids", StructuredData::ObjectSP(unique_tids));
+
+ return StructuredData::ObjectSP(dict);
+}
+
+std::string
+ThreadSanitizerRuntime::FormatDescription(StructuredData::ObjectSP report)
+{
+ std::string description = report->GetAsDictionary()->GetValueForKey("issue_type")->GetAsString()->GetValue();
+
+ if (description == "data-race") {
+ return "Data race";
+ } else if (description == "data-race-vptr") {
+ return "Data race on C++ virtual pointer";
+ } else if (description == "heap-use-after-free") {
+ return "Use of deallocated memory";
+ } else if (description == "heap-use-after-free-vptr") {
+ return "Use of deallocated C++ virtual pointer";
+ } else if (description == "thread-leak") {
+ return "Thread leak";
+ } else if (description == "locked-mutex-destroy") {
+ return "Destruction of a locked mutex";
+ } else if (description == "mutex-double-lock") {
+ return "Double lock of a mutex";
+ } else if (description == "mutex-invalid-access") {
+ return "Use of an uninitialized or destroyed mutex";
+ } else if (description == "mutex-bad-unlock") {
+ return "Unlock of an unlocked mutex (or by a wrong thread)";
+ } else if (description == "mutex-bad-read-lock") {
+ return "Read lock of a write locked mutex";
+ } else if (description == "mutex-bad-read-unlock") {
+ return "Read unlock of a write locked mutex";
+ } else if (description == "signal-unsafe-call") {
+ return "Signal-unsafe call inside a signal handler";
+ } else if (description == "errno-in-signal-handler") {
+ return "Overwrite of errno in a signal handler";
+ } else if (description == "lock-order-inversion") {
+ return "Lock order inversion (potential deadlock)";
+ }
+
+ // for unknown report codes just show the code
+ return description;
+}
+
+static std::string
+Sprintf(const char *format, ...)
+{
+ StreamString s;
+ va_list args;
+ va_start (args, format);
+ s.PrintfVarArg(format, args);
+ va_end (args);
+ return s.GetString();
+}
+
+static std::string
+GetSymbolNameFromAddress(ProcessSP process_sp, addr_t addr)
+{
+ lldb_private::Address so_addr;
+ if (! process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
+ return "";
+
+ lldb_private::Symbol *symbol = so_addr.CalculateSymbolContextSymbol();
+ if (! symbol)
+ return "";
+
+ std::string sym_name = symbol->GetName().GetCString();
+ return sym_name;
+}
+
+static void
+GetSymbolDeclarationFromAddress(ProcessSP process_sp, addr_t addr, Declaration &decl)
+{
+ lldb_private::Address so_addr;
+ if (! process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
+ return;
+
+ lldb_private::Symbol *symbol = so_addr.CalculateSymbolContextSymbol();
+ if (! symbol)
+ return;
+
+ ConstString sym_name = symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled);
+
+ ModuleSP module = symbol->CalculateSymbolContextModule();
+ if (! module)
+ return;
+
+ VariableList var_list;
+ module->FindGlobalVariables(sym_name, nullptr, true, 1U, var_list);
+ if (var_list.GetSize() < 1)
+ return;
+
+ VariableSP var = var_list.GetVariableAtIndex(0);
+ decl = var->GetDeclaration();
+}
+
+addr_t
+ThreadSanitizerRuntime::GetFirstNonInternalFramePc(StructuredData::ObjectSP trace)
+{
+ ProcessSP process_sp = GetProcessSP();
+ ModuleSP runtime_module_sp = GetRuntimeModuleSP();
+
+ addr_t result = 0;
+ trace->GetAsArray()->ForEach([process_sp, runtime_module_sp, &result] (StructuredData::Object *o) -> bool {
+ addr_t addr = o->GetIntegerValue();
+ lldb_private::Address so_addr;
+ if (! process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
+ return true;
+
+ if (so_addr.GetModule() == runtime_module_sp)
+ return true;
+
+ result = addr;
+ return false;
+ });
+
+ return result;
+}
+
+std::string
+ThreadSanitizerRuntime::GenerateSummary(StructuredData::ObjectSP report)
+{
+ ProcessSP process_sp = GetProcessSP();
+
+ std::string summary = report->GetAsDictionary()->GetValueForKey("description")->GetAsString()->GetValue();
+ addr_t pc = 0;
+ if (report->GetAsDictionary()->GetValueForKey("mops")->GetAsArray()->GetSize() > 0)
+ pc = GetFirstNonInternalFramePc(report->GetAsDictionary()->GetValueForKey("mops")->GetAsArray()->GetItemAtIndex(0)->GetAsDictionary()->GetValueForKey("trace"));
+
+ if (report->GetAsDictionary()->GetValueForKey("stacks")->GetAsArray()->GetSize() > 0)
+ pc = GetFirstNonInternalFramePc(report->GetAsDictionary()->GetValueForKey("stacks")->GetAsArray()->GetItemAtIndex(0)->GetAsDictionary()->GetValueForKey("trace"));
+
+ if (pc != 0) {
+ summary = summary + " in " + GetSymbolNameFromAddress(process_sp, pc);
+ }
+
+ if (report->GetAsDictionary()->GetValueForKey("locs")->GetAsArray()->GetSize() > 0) {
+ StructuredData::ObjectSP loc = report->GetAsDictionary()->GetValueForKey("locs")->GetAsArray()->GetItemAtIndex(0);
+ addr_t addr = loc->GetAsDictionary()->GetValueForKey("address")->GetAsInteger()->GetValue();
+ if (addr == 0)
+ addr = loc->GetAsDictionary()->GetValueForKey("start")->GetAsInteger()->GetValue();
+
+ if (addr != 0) {
+ std::string global_name = GetSymbolNameFromAddress(process_sp, addr);
+ if (!global_name.empty()) {
+ summary = summary + " at " + global_name;
+ } else {
+ summary = summary + " at " + Sprintf("0x%llx", addr);
+ }
+ } else {
+ int fd = loc->GetAsDictionary()->GetValueForKey("file_descriptor")->GetAsInteger()->GetValue();
+ if (fd != 0) {
+ summary = summary + " on file descriptor " + Sprintf("%d", fd);
+ }
+ }
+ }
+
+ return summary;
+}
+
+addr_t
+ThreadSanitizerRuntime::GetMainRacyAddress(StructuredData::ObjectSP report)
+{
+ addr_t result = (addr_t)-1;
+
+ report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach([&result] (StructuredData::Object *o) -> bool {
+ addr_t addr = o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
+ if (addr < result) result = addr;
+ return true;
+ });
+
+ return (result == (addr_t)-1) ? 0 : result;
+}
+
+std::string
+ThreadSanitizerRuntime::GetLocationDescription(StructuredData::ObjectSP report, addr_t &global_addr, std::string &global_name, std::string &filename, uint32_t &line)
+{
+ std::string result = "";
+
+ ProcessSP process_sp = GetProcessSP();
+
+ if (report->GetAsDictionary()->GetValueForKey("locs")->GetAsArray()->GetSize() > 0) {
+ StructuredData::ObjectSP loc = report->GetAsDictionary()->GetValueForKey("locs")->GetAsArray()->GetItemAtIndex(0);
+ std::string type = loc->GetAsDictionary()->GetValueForKey("type")->GetStringValue();
+ if (type == "global") {
+ global_addr = loc->GetAsDictionary()->GetValueForKey("address")->GetAsInteger()->GetValue();
+ global_name = GetSymbolNameFromAddress(process_sp, global_addr);
+ if (!global_name.empty()) {
+ result = Sprintf("'%s' is a global variable (0x%llx)", global_name.c_str(), global_addr);
+ } else {
+ result = Sprintf("0x%llx is a global variable", global_addr);
+ }
+
+ Declaration decl;
+ GetSymbolDeclarationFromAddress(process_sp, global_addr, decl);
+ if (decl.GetFile()) {
+ filename = decl.GetFile().GetPath();
+ line = decl.GetLine();
+ }
+ } else if (type == "heap") {
+ addr_t addr = loc->GetAsDictionary()->GetValueForKey("start")->GetAsInteger()->GetValue();
+ long size = loc->GetAsDictionary()->GetValueForKey("size")->GetAsInteger()->GetValue();
+ result = Sprintf("Location is a %ld-byte heap object at 0x%llx", size, addr);
+ } else if (type == "stack") {
+ int tid = loc->GetAsDictionary()->GetValueForKey("thread_id")->GetAsInteger()->GetValue();
+ result = Sprintf("Location is stack of thread %d", tid);
+ } else if (type == "tls") {
+ int tid = loc->GetAsDictionary()->GetValueForKey("thread_id")->GetAsInteger()->GetValue();
+ result = Sprintf("Location is TLS of thread %d", tid);
+ } else if (type == "fd") {
+ int fd = loc->GetAsDictionary()->GetValueForKey("file_descriptor")->GetAsInteger()->GetValue();
+ result = Sprintf("Location is file descriptor %d", fd);
+ }
+ }
+
+ return result;
+}
+
+bool
+ThreadSanitizerRuntime::NotifyBreakpointHit(void *baton, StoppointCallbackContext *context, user_id_t break_id, user_id_t break_loc_id)
+{
+ assert (baton && "null baton");
+ if (!baton)
+ return false;
+
+ ThreadSanitizerRuntime *const instance = static_cast<ThreadSanitizerRuntime*>(baton);
+
+ StructuredData::ObjectSP report = instance->RetrieveReportData(context->exe_ctx_ref);
+ std::string stop_reason_description;
+ if (report) {
+ std::string issue_description = instance->FormatDescription(report);
+ report->GetAsDictionary()->AddStringItem("description", issue_description);
+ stop_reason_description = issue_description + " detected";
+ report->GetAsDictionary()->AddStringItem("stop_description", stop_reason_description);
+ std::string summary = instance->GenerateSummary(report);
+ report->GetAsDictionary()->AddStringItem("summary", summary);
+ addr_t main_address = instance->GetMainRacyAddress(report);
+ report->GetAsDictionary()->AddIntegerItem("memory_address", main_address);
+
+ addr_t global_addr = 0;
+ std::string global_name = "";
+ std::string location_filename = "";
+ uint32_t location_line = 0;
+ std::string location_description = instance->GetLocationDescription(report, global_addr, global_name, location_filename, location_line);
+ report->GetAsDictionary()->AddStringItem("location_description", location_description);
+ if (global_addr != 0) {
+ report->GetAsDictionary()->AddIntegerItem("global_address", global_addr);
+ }
+ if (!global_name.empty()) {
+ report->GetAsDictionary()->AddStringItem("global_name", global_name);
+ }
+ if (location_filename != "") {
+ report->GetAsDictionary()->AddStringItem("location_filename", location_filename);
+ report->GetAsDictionary()->AddIntegerItem("location_line", location_line);
+ }
+
+ bool all_addresses_are_same = true;
+ report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach([&all_addresses_are_same, main_address] (StructuredData::Object *o) -> bool {
+ addr_t addr = o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
+ if (main_address != addr) all_addresses_are_same = false;
+ return true;
+ });
+ report->GetAsDictionary()->AddBooleanItem("all_addresses_are_same", all_addresses_are_same);
+ }
+
+ ProcessSP process_sp = instance->GetProcessSP();
+ // Make sure this is the right process
+ if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP())
+ {
+ ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
+ if (thread_sp)
+ thread_sp->SetStopInfo(InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData(*thread_sp, stop_reason_description.c_str(), 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");
+ }
+ return true; // Return true to stop the target
+ }
+ else
+ return false; // Let target run
+}
+
+void
+ThreadSanitizerRuntime::Activate()
+{
+ if (m_is_active)
+ return;
+
+ ProcessSP process_sp = GetProcessSP();
+ if (!process_sp)
+ return;
+
+ ConstString symbol_name ("__tsan_on_report");
+ const Symbol *symbol = GetRuntimeModuleSP()->FindFirstSymbolWithNameAndType (symbol_name, eSymbolTypeCode);
+
+ if (symbol == NULL)
+ return;
+
+ if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid())
+ return;
+
+ Target &target = process_sp->GetTarget();
+ addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
+
+ if (symbol_address == LLDB_INVALID_ADDRESS)
+ return;
+
+ bool internal = true;
+ bool hardware = false;
+ Breakpoint *breakpoint = process_sp->GetTarget().CreateBreakpoint(symbol_address, internal, hardware).get();
+ breakpoint->SetCallback (ThreadSanitizerRuntime::NotifyBreakpointHit, this, true);
+ breakpoint->SetBreakpointKind ("thread-sanitizer-report");
+ m_breakpoint_id = breakpoint->GetID();
+
+ StreamFileSP stream_sp (process_sp->GetTarget().GetDebugger().GetOutputFile());
+ if (stream_sp)
+ {
+ stream_sp->Printf ("ThreadSanitizer debugger support is active.\n");
+ }
+
+ m_is_active = true;
+}
+
+void
+ThreadSanitizerRuntime::Deactivate()
+{
+ if (m_breakpoint_id != LLDB_INVALID_BREAK_ID)
+ {
+ ProcessSP process_sp = GetProcessSP();
+ if (process_sp)
+ {
+ process_sp->GetTarget().RemoveBreakpointByID(m_breakpoint_id);
+ m_breakpoint_id = LLDB_INVALID_BREAK_ID;
+ }
+ }
+ m_is_active = false;
+}
+
+static std::string
+GenerateThreadName(std::string path, StructuredData::Object *o, StructuredData::ObjectSP main_info) {
+ std::string result = "additional information";
+
+ if (path == "mops") {
+ int size = o->GetObjectForDotSeparatedPath("size")->GetIntegerValue();
+ int thread_id = o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
+ bool is_write = o->GetObjectForDotSeparatedPath("is_write")->GetBooleanValue();
+ bool is_atomic = o->GetObjectForDotSeparatedPath("is_atomic")->GetBooleanValue();
+ addr_t addr = o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
+
+ std::string addr_string = Sprintf(" at 0x%llx", addr);
+
+ if (main_info->GetObjectForDotSeparatedPath("all_addresses_are_same")->GetBooleanValue()){
+ addr_string = "";
+ }
+
+ result = Sprintf("%s%s of size %d%s by thread %d", is_atomic ? "atomic " : "", is_write ? "write" : "read", size, addr_string.c_str(), thread_id);
+ }
+
+ if (path == "threads") {
+ int thread_id = o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
+ result = Sprintf("Thread %d created", thread_id);
+ }
+
+ if (path == "locs") {
+ std::string type = o->GetAsDictionary()->GetValueForKey("type")->GetStringValue();
+ int thread_id = o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
+ int fd = o->GetObjectForDotSeparatedPath("file_descriptor")->GetIntegerValue();
+ if (type == "heap") {
+ result = Sprintf("Heap block allocated by thread %d", thread_id);
+ } else if (type == "fd") {
+ result = Sprintf("File descriptor %d created by thread %t", fd, thread_id);
+ }
+ }
+
+ if (path == "mutexes") {
+ int mutex_id = o->GetObjectForDotSeparatedPath("mutex_id")->GetIntegerValue();
+
+ result = Sprintf("Mutex M%d created", mutex_id);
+ }
+
+ if (path == "stacks") {
+ int thread_id = o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
+ result = Sprintf("Thread %d", thread_id);
+ }
+
+ result[0] = toupper(result[0]);
+
+ return result;
+}
+
+static void
+AddThreadsForPath(std::string path, ThreadCollectionSP threads, ProcessSP process_sp, StructuredData::ObjectSP info)
+{
+ info->GetObjectForDotSeparatedPath(path)->GetAsArray()->ForEach([process_sp, threads, path, info] (StructuredData::Object *o) -> bool {
+ std::vector<lldb::addr_t> pcs;
+ o->GetObjectForDotSeparatedPath("trace")->GetAsArray()->ForEach([&pcs] (StructuredData::Object *pc) -> bool {
+ pcs.push_back(pc->GetAsInteger()->GetValue());
+ return true;
+ });
+
+ if (pcs.size() == 0)
+ return true;
+
+ StructuredData::ObjectSP thread_id_obj = o->GetObjectForDotSeparatedPath("thread_os_id");
+ tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
+
+ uint32_t stop_id = 0;
+ bool stop_id_is_valid = false;
+ HistoryThread *history_thread = new HistoryThread(*process_sp, tid, pcs, stop_id, stop_id_is_valid);
+ ThreadSP new_thread_sp(history_thread);
+ new_thread_sp->SetName(GenerateThreadName(path, o, info).c_str());
+
+ // Save this in the Process' ExtendedThreadList so a strong pointer retains the object
+ process_sp->GetExtendedThreadList().AddThread(new_thread_sp);
+ threads->AddThread(new_thread_sp);
+
+ return true;
+ });
+}
+
+lldb::ThreadCollectionSP
+ThreadSanitizerRuntime::GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info)
+{
+ ThreadCollectionSP threads;
+ threads.reset(new ThreadCollection());
+
+ if (info->GetObjectForDotSeparatedPath("instrumentation_class")->GetStringValue() != "ThreadSanitizer")
+ return threads;
+
+ ProcessSP process_sp = GetProcessSP();
+
+ AddThreadsForPath("stacks", threads, process_sp, info);
+ AddThreadsForPath("mops", threads, process_sp, info);
+ AddThreadsForPath("locs", threads, process_sp, info);
+ AddThreadsForPath("mutexes", threads, process_sp, info);
+ AddThreadsForPath("threads", threads, process_sp, info);
+
+ return threads;
+}
diff --git a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h
new file mode 100644
index 000000000000..ca7af23aa3bd
--- /dev/null
+++ b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h
@@ -0,0 +1,119 @@
+//===-- ThreadSanitizerRuntime.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadSanitizerRuntime_h_
+#define liblldb_ThreadSanitizerRuntime_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Target/ABI.h"
+#include "lldb/Target/InstrumentationRuntime.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Core/StructuredData.h"
+
+namespace lldb_private {
+
+class ThreadSanitizerRuntime : public lldb_private::InstrumentationRuntime
+{
+public:
+ ~ThreadSanitizerRuntime() override;
+
+ static lldb::InstrumentationRuntimeSP
+ CreateInstance (const lldb::ProcessSP &process_sp);
+
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb_private::ConstString
+ GetPluginNameStatic();
+
+ static lldb::InstrumentationRuntimeType
+ GetTypeStatic();
+
+ lldb_private::ConstString
+ GetPluginName() override
+ {
+ return GetPluginNameStatic();
+ }
+
+ virtual lldb::InstrumentationRuntimeType
+ GetType() { return GetTypeStatic(); }
+
+ uint32_t
+ GetPluginVersion() override
+ {
+ return 1;
+ }
+
+ void
+ ModulesDidLoad(lldb_private::ModuleList &module_list) override;
+
+ bool
+ IsActive() override;
+
+ lldb::ThreadCollectionSP
+ GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override;
+
+private:
+ ThreadSanitizerRuntime(const lldb::ProcessSP &process_sp);
+
+ lldb::ProcessSP
+ GetProcessSP ()
+ {
+ return m_process_wp.lock();
+ }
+
+ lldb::ModuleSP
+ GetRuntimeModuleSP ()
+ {
+ return m_runtime_module_wp.lock();
+ }
+
+ void
+ Activate();
+
+ void
+ Deactivate();
+
+ static bool
+ NotifyBreakpointHit(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ StructuredData::ObjectSP
+ RetrieveReportData(ExecutionContextRef exe_ctx_ref);
+
+ std::string
+ FormatDescription(StructuredData::ObjectSP report);
+
+ std::string
+ GenerateSummary(StructuredData::ObjectSP report);
+
+ lldb::addr_t
+ GetMainRacyAddress(StructuredData::ObjectSP report);
+
+ std::string
+ GetLocationDescription(StructuredData::ObjectSP report, lldb::addr_t &global_addr, std::string &global_name, std::string &filename, uint32_t &line);
+
+ lldb::addr_t
+ GetFirstNonInternalFramePc(StructuredData::ObjectSP trace);
+
+ bool m_is_active;
+ lldb::ModuleWP m_runtime_module_wp;
+ lldb::ProcessWP m_process_wp;
+ lldb::user_id_t m_breakpoint_id;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadSanitizerRuntime_h_
diff --git a/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
index 143e44794057..a126ad026a55 100644
--- a/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
+++ b/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
@@ -9,7 +9,10 @@
// C Includes
+#include "llvm/Support/MathExtras.h"
+
#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
@@ -22,12 +25,41 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "JITLoaderGDB.h"
using namespace lldb;
using namespace lldb_private;
+//------------------------------------------------------------------
+// Debug Interface Structures
+//------------------------------------------------------------------
+typedef enum
+{
+ JIT_NOACTION = 0,
+ JIT_REGISTER_FN,
+ JIT_UNREGISTER_FN
+} jit_actions_t;
+
+template <typename ptr_t>
+struct jit_code_entry
+{
+ ptr_t next_entry; // pointer
+ ptr_t prev_entry; // pointer
+ ptr_t symfile_addr; // pointer
+ uint64_t symfile_size;
+};
+
+template <typename ptr_t>
+struct jit_descriptor
+{
+ uint32_t version;
+ uint32_t action_flag; // Values are jit_action_t
+ ptr_t relevant_entry; // pointer
+ ptr_t first_entry; // pointer
+};
+
namespace {
PropertyDefinition
@@ -78,34 +110,34 @@ namespace {
return g_settings_sp;
}
-} // anonymous namespace end
+ template <typename ptr_t>
+ bool ReadJITEntry(const addr_t from_addr, Process *process, jit_code_entry<ptr_t> *entry)
+ {
+ lldbassert(from_addr % sizeof(ptr_t) == 0);
-//------------------------------------------------------------------
-// Debug Interface Structures
-//------------------------------------------------------------------
-typedef enum
-{
- JIT_NOACTION = 0,
- JIT_REGISTER_FN,
- JIT_UNREGISTER_FN
-} jit_actions_t;
+ ArchSpec::Core core = process->GetTarget().GetArchitecture().GetCore();
+ bool i386_target = ArchSpec::kCore_x86_32_first <= core && core <= ArchSpec::kCore_x86_32_last;
+ uint8_t uint64_align_bytes = i386_target ? 4 : 8;
+ const size_t data_byte_size = llvm::alignTo(sizeof(ptr_t) * 3, uint64_align_bytes) + sizeof(uint64_t);
-template <typename ptr_t>
-struct jit_code_entry
-{
- ptr_t next_entry; // pointer
- ptr_t prev_entry; // pointer
- ptr_t symfile_addr; // pointer
- uint64_t symfile_size;
-};
-template <typename ptr_t>
-struct jit_descriptor
-{
- uint32_t version;
- uint32_t action_flag; // Values are jit_action_t
- ptr_t relevant_entry; // pointer
- ptr_t first_entry; // pointer
-};
+ Error error;
+ DataBufferHeap data(data_byte_size, 0);
+ size_t bytes_read = process->ReadMemory(from_addr, data.GetBytes(), data.GetByteSize(), error);
+ if (bytes_read != data_byte_size || !error.Success())
+ return false;
+
+ DataExtractor extractor (data.GetBytes(), data.GetByteSize(), process->GetByteOrder(), sizeof(ptr_t));
+ lldb::offset_t offset = 0;
+ entry->next_entry = extractor.GetPointer(&offset);
+ entry->prev_entry = extractor.GetPointer(&offset);
+ entry->symfile_addr = extractor.GetPointer(&offset);
+ offset = llvm::alignTo(offset, uint64_align_bytes);
+ entry->symfile_size = extractor.GetU64(&offset);
+
+ return true;
+ }
+
+} // anonymous namespace end
JITLoaderGDB::JITLoaderGDB (lldb_private::Process *process) :
JITLoader(process),
@@ -268,8 +300,7 @@ static void updateSectionLoadAddress(const SectionList &section_list,
bool
JITLoaderGDB::ReadJITDescriptor(bool all_entries)
{
- Target &target = m_process->GetTarget();
- if (target.GetArchitecture().GetAddressByteSize() == 8)
+ if (m_process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
return ReadJITDescriptorImpl<uint64_t>(all_entries);
else
return ReadJITDescriptorImpl<uint32_t>(all_entries);
@@ -310,9 +341,7 @@ JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries)
while (jit_relevant_entry != 0)
{
jit_code_entry<ptr_t> jit_entry;
- const size_t jit_entry_size = sizeof(jit_entry);
- bytes_read = m_process->DoReadMemory(jit_relevant_entry, &jit_entry, jit_entry_size, error);
- if (bytes_read != jit_entry_size || !error.Success())
+ if (!ReadJITEntry(jit_relevant_entry, m_process, &jit_entry))
{
if (log)
log->Printf(
@@ -340,7 +369,9 @@ JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries)
if (module_sp && module_sp->GetObjectFile())
{
- bool changed;
+ // load the symbol table right away
+ module_sp->GetObjectFile()->GetSymtab();
+
m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
if (module_sp->GetObjectFile()->GetPluginName() == ConstString("mach-o"))
{
@@ -360,12 +391,10 @@ JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries)
}
else
{
+ bool changed = false;
module_sp->SetLoadAddress(target, 0, true, changed);
}
- // load the symbol table right away
- module_sp->GetObjectFile()->GetSymtab();
-
module_list.AppendIfNeeded(module_sp);
ModuleList module_list;
diff --git a/source/Plugins/JITLoader/GDB/Makefile b/source/Plugins/JITLoader/GDB/Makefile
deleted file mode 100644
index cd5404ffca18..000000000000
--- a/source/Plugins/JITLoader/GDB/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/JITLoader/GDB/Makefile ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginJITLoaderGDB
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Language/CMakeLists.txt b/source/Plugins/Language/CMakeLists.txt
index 60b3da2406b6..725138a56c8e 100644
--- a/source/Plugins/Language/CMakeLists.txt
+++ b/source/Plugins/Language/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(CPlusPlus)
add_subdirectory(Go)
+add_subdirectory(Java)
add_subdirectory(ObjC)
add_subdirectory(ObjCPlusPlus)
diff --git a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
new file mode 100644
index 000000000000..92e30d54f6e1
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -0,0 +1,225 @@
+//===-- BlockPointer.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "BlockPointer.h"
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangASTImporter.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Symbol/TypeSystem.h"
+#include "lldb/Target/Target.h"
+
+#include "lldb/Utility/LLDBAssert.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+namespace lldb_private
+{
+namespace formatters
+{
+
+class BlockPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+{
+public:
+ BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp),
+ m_block_struct_type()
+ {
+ CompilerType block_pointer_type(m_backend.GetCompilerType());
+ CompilerType function_pointer_type;
+ block_pointer_type.IsBlockPointerType(&function_pointer_type);
+
+ TargetSP target_sp(m_backend.GetTargetSP());
+
+ if (!target_sp)
+ {
+ return;
+ }
+
+ Error err;
+ TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(&err, lldb::eLanguageTypeC_plus_plus);
+
+ if (!err.Success() || !type_system)
+ {
+ return;
+ }
+
+ ClangASTContext *clang_ast_context = llvm::dyn_cast<ClangASTContext>(type_system);
+
+ if (!clang_ast_context)
+ {
+ return;
+ }
+
+ ClangASTImporterSP clang_ast_importer = target_sp->GetClangASTImporter();
+
+ if (!clang_ast_importer)
+ {
+ return;
+ }
+
+ const char *const isa_name("__isa");
+ const CompilerType isa_type = clang_ast_context->GetBasicType(lldb::eBasicTypeObjCClass);
+ const char *const flags_name("__flags");
+ const CompilerType flags_type = clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
+ const char *const reserved_name("__reserved");
+ const CompilerType reserved_type = clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
+ const char *const FuncPtr_name("__FuncPtr");
+ const CompilerType FuncPtr_type = clang_ast_importer->CopyType(*clang_ast_context, function_pointer_type);
+
+ m_block_struct_type = clang_ast_context->CreateStructForIdentifier(ConstString(),
+ {
+ {isa_name, isa_type},
+ {flags_name, flags_type},
+ {reserved_name, reserved_type},
+ {FuncPtr_name, FuncPtr_type}
+ });
+
+ }
+
+ ~BlockPointerSyntheticFrontEnd() override = default;
+
+ size_t
+ CalculateNumChildren() override
+ {
+ const bool omit_empty_base_classes = false;
+ return m_block_struct_type.GetNumChildren(omit_empty_base_classes);
+ }
+
+ lldb::ValueObjectSP
+ GetChildAtIndex(size_t idx) override
+ {
+ if (!m_block_struct_type.IsValid())
+ {
+ return lldb::ValueObjectSP();
+ }
+
+ if (idx >= CalculateNumChildren())
+ {
+ return lldb::ValueObjectSP();
+ }
+
+ const bool thread_and_frame_only_if_stopped = true;
+ ExecutionContext exe_ctx = m_backend.GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped);
+ const bool transparent_pointers = false;
+ const bool omit_empty_base_classes = false;
+ const bool ignore_array_bounds = false;
+ ValueObject *value_object = nullptr;
+
+ std::string child_name;
+ uint32_t child_byte_size = 0;
+ int32_t child_byte_offset = 0;
+ uint32_t child_bitfield_bit_size = 0;
+ uint32_t child_bitfield_bit_offset = 0;
+ bool child_is_base_class = false;
+ bool child_is_deref_of_parent = false;
+ uint64_t language_flags = 0;
+
+ const CompilerType child_type = m_block_struct_type.GetChildCompilerTypeAtIndex(&exe_ctx, idx, transparent_pointers, omit_empty_base_classes, ignore_array_bounds, child_name, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent, value_object, language_flags);
+
+ ValueObjectSP struct_pointer_sp = m_backend.Cast(m_block_struct_type.GetPointerType());
+
+ if (!struct_pointer_sp)
+ {
+ return lldb::ValueObjectSP();
+ }
+
+ Error err;
+ ValueObjectSP struct_sp = struct_pointer_sp->Dereference(err);
+
+ if (!struct_sp || !err.Success())
+ {
+ return lldb::ValueObjectSP();
+ }
+
+ ValueObjectSP child_sp(struct_sp->GetSyntheticChildAtOffset(child_byte_offset,
+ child_type,
+ true,
+ ConstString(child_name.c_str(), child_name.size())));
+
+ return child_sp;
+ }
+
+ // return true if this object is now safe to use forever without
+ // ever updating again; the typical (and tested) answer here is
+ // 'false'
+ bool
+ Update() override
+ {
+ return false;
+ }
+
+ // maybe return false if the block pointer is, say, null
+ bool
+ MightHaveChildren() override
+ {
+ return true;
+ }
+
+ size_t
+ GetIndexOfChildWithName(const ConstString &name) override
+ {
+ if (!m_block_struct_type.IsValid())
+ return UINT32_MAX;
+
+ const bool omit_empty_base_classes = false;
+ return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(), omit_empty_base_classes);
+ }
+
+private:
+ CompilerType m_block_struct_type;
+};
+
+} // namespace formatters
+} // namespace lldb_private
+
+bool
+lldb_private::formatters::BlockPointerSummaryProvider(ValueObject &valobj, Stream &s, const TypeSummaryOptions &)
+{
+ lldb_private::SyntheticChildrenFrontEnd *synthetic_children = BlockPointerSyntheticFrontEndCreator(nullptr, valobj.GetSP());
+ if (!synthetic_children)
+ {
+ return false;
+ }
+
+ synthetic_children->Update();
+
+ static const ConstString s_FuncPtr_name("__FuncPtr");
+
+ lldb::ValueObjectSP child_sp = synthetic_children->GetChildAtIndex(synthetic_children->GetIndexOfChildWithName(s_FuncPtr_name));
+
+ if (!child_sp)
+ {
+ return false;
+ }
+
+ lldb::ValueObjectSP qualified_child_representation_sp = child_sp->GetQualifiedRepresentationIfAvailable(lldb::eDynamicDontRunTarget, true);
+
+ const char *child_value = qualified_child_representation_sp->GetValueAsCString();
+
+ s.Printf("%s", child_value);
+
+ return true;
+}
+
+lldb_private::SyntheticChildrenFrontEnd *
+lldb_private::formatters::BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp)
+{
+ if (!valobj_sp)
+ return nullptr;
+ return new BlockPointerSyntheticFrontEnd(valobj_sp);
+}
diff --git a/source/Plugins/Language/CPlusPlus/BlockPointer.h b/source/Plugins/Language/CPlusPlus/BlockPointer.h
new file mode 100644
index 000000000000..5e6c748b5dbb
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/BlockPointer.h
@@ -0,0 +1,27 @@
+//===-- BlockPointer.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BlockPointer_h_
+#define liblldb_BlockPointer_h_
+
+#include "lldb/lldb-forward.h"
+
+namespace lldb_private
+{
+namespace formatters
+{
+bool
+BlockPointerSummaryProvider(ValueObject &, Stream &, const TypeSummaryOptions &);
+
+SyntheticChildrenFrontEnd *
+BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP);
+} // namespace formatters
+} // namespace lldb_private
+
+#endif // liblldb_BlockPointer_h_
diff --git a/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index 0b0f0f451a8d..de0dc99d85dd 100644
--- a/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -1,7 +1,9 @@
add_lldb_library(lldbPluginCPlusPlusLanguage
+ BlockPointer.cpp
CPlusPlusLanguage.cpp
CxxStringTypes.cpp
LibCxx.cpp
+ LibCxxAtomic.cpp
LibCxxInitializerList.cpp
LibCxxList.cpp
LibCxxMap.cpp
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 09031e2f8064..33d22bf2e583 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1,4 +1,4 @@
-//===-- CPlusPlusLanguage.cpp --------------------------------------*- C++ -*-===//
+//===-- CPlusPlusLanguage.cpp -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,9 +9,17 @@
#include "CPlusPlusLanguage.h"
+// C Includes
+// C++ Includes
+#include <cstring>
+#include <cctype>
+#include <functional>
+#include <mutex>
+// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
+// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
@@ -21,15 +29,12 @@
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/VectorType.h"
+#include "BlockPointer.h"
#include "CxxStringTypes.h"
#include "LibCxx.h"
+#include "LibCxxAtomic.h"
#include "LibStdcpp.h"
-#include <cstring>
-#include <cctype>
-#include <functional>
-#include <mutex>
-
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
@@ -55,10 +60,10 @@ CPlusPlusLanguage::GetPluginNameStatic()
return g_name;
}
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
lldb_private::ConstString
CPlusPlusLanguage::GetPluginName()
{
@@ -74,6 +79,7 @@ CPlusPlusLanguage::GetPluginVersion()
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
Language *
CPlusPlusLanguage::CreateInstance (lldb::LanguageType language)
{
@@ -319,16 +325,13 @@ CPlusPlusLanguage::IsCPPMangledName (const char *name)
// this is a C++ mangled name, but we can put that off till there is actually more than one
// we care about.
- if (name && name[0] == '_' && name[1] == 'Z')
- return true;
- else
- return false;
+ return (name != nullptr && name[0] == '_' && name[1] == 'Z');
}
bool
CPlusPlusLanguage::ExtractContextAndIdentifier (const char *name, llvm::StringRef &context, llvm::StringRef &identifier)
{
- static RegularExpression g_basename_regex("^(([A-Za-z_][A-Za-z_0-9]*::)*)([A-Za-z_][A-Za-z_0-9]*)$");
+ static RegularExpression g_basename_regex("^(([A-Za-z_][A-Za-z_0-9]*::)*)(~?[A-Za-z_~][A-Za-z_0-9]*)$");
RegularExpression::Match match(4);
if (g_basename_regex.Execute (name, &match))
{
@@ -344,7 +347,6 @@ class CPPRuntimeEquivalents
public:
CPPRuntimeEquivalents ()
{
-
m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >").AsCString(), ConstString("basic_string<char>"));
// these two (with a prefixed std::) occur when c++stdlib string class occurs as a template argument in some STL container
@@ -364,11 +366,10 @@ public:
FindExactMatches (ConstString& type_name,
std::vector<ConstString>& equivalents)
{
-
uint32_t count = 0;
for (ImplData match = m_impl.FindFirstValueForName(type_name.AsCString());
- match != NULL;
+ match != nullptr;
match = m_impl.FindNextValueForName(match))
{
equivalents.push_back(match->value);
@@ -387,7 +388,6 @@ public:
FindPartialMatches (ConstString& type_name,
std::vector<ConstString>& equivalents)
{
-
uint32_t count = 0;
const char* type_name_cstr = type_name.AsCString();
@@ -406,11 +406,9 @@ public:
}
return count;
-
}
private:
-
std::string& replace (std::string& target,
std::string& pattern,
std::string& with)
@@ -429,14 +427,13 @@ private:
const char *matching_key,
std::vector<ConstString>& equivalents)
{
-
std::string matching_key_str(matching_key);
ConstString original_const(original);
uint32_t count = 0;
for (ImplData match = m_impl.FindFirstValueForName(matching_key);
- match != NULL;
+ match != nullptr;
match = m_impl.FindNextValueForName(match))
{
std::string target(original);
@@ -470,7 +467,6 @@ GetEquivalentsMap ()
return g_equivalents_map;
}
-
uint32_t
CPlusPlusLanguage::FindEquivalentNames(ConstString type_name, std::vector<ConstString>& equivalents)
{
@@ -478,8 +474,8 @@ CPlusPlusLanguage::FindEquivalentNames(ConstString type_name, std::vector<ConstS
bool might_have_partials=
( count == 0 ) // if we have a full name match just use it
- && (strchr(type_name.AsCString(), '<') != NULL // we should only have partial matches when templates are involved, check that we have
- && strchr(type_name.AsCString(), '>') != NULL); // angle brackets in the type_name before trying to scan for partial matches
+ && (strchr(type_name.AsCString(), '<') != nullptr // we should only have partial matches when templates are involved, check that we have
+ && strchr(type_name.AsCString(), '>') != nullptr); // angle brackets in the type_name before trying to scan for partial matches
if ( might_have_partials )
count = GetEquivalentsMap().FindPartialMatches(type_name, equivalents);
@@ -508,60 +504,66 @@ LoadLibCxxFormatters (lldb::TypeCategoryImplSP cpp_category_sp)
cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::string"),
std_string_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::string"),
+ std_string_summary_sp);
cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >"),
std_string_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >"),
+ std_string_summary_sp);
cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::wstring"),
std_wstring_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::wstring"),
+ std_wstring_summary_sp);
cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >"),
std_wstring_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::basic_string<wchar_t, std::__ndk1::char_traits<wchar_t>, std::__ndk1::allocator<wchar_t> >"),
+ std_wstring_summary_sp);
SyntheticChildren::Flags stl_synth_flags;
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator, "libc++ std::vector synthetic children", ConstString("^std::__1::vector<.+>(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator, "libc++ std::list synthetic children", ConstString("^std::__1::list<.+>(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::map synthetic children", ConstString("^std::__1::map<.+> >(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("std::__1::vector<std::__1::allocator<bool> >"), stl_synth_flags);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("std::__1::vector<bool, std::__1::allocator<bool> >"), stl_synth_flags);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::set synthetic children", ConstString("^std::__1::set<.+> >(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multiset synthetic children", ConstString("^std::__1::multiset<.+> >(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multimap synthetic children", ConstString("^std::__1::multimap<.+> >(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator, "libc++ std::unordered containers synthetic children", ConstString("^(std::__1::)unordered_(multi)?(map|set)<.+> >$"), stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("^std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >$"), stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator, "libc++ std::vector synthetic children", ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator, "libc++ std::list synthetic children", ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::map synthetic children", ConstString("^std::__(ndk)?1::map<.+> >(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("std::__(ndk)?1::vector<std::__(ndk)?1::allocator<bool> >"), stl_synth_flags);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), stl_synth_flags);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::set synthetic children", ConstString("^std::__(ndk)?1::set<.+> >(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multiset synthetic children", ConstString("^std::__(ndk)?1::multiset<.+> >(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multimap synthetic children", ConstString("^std::__(ndk)?1::multimap<.+> >(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator, "libc++ std::unordered containers synthetic children", ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"), stl_synth_flags, true);
AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator, "libc++ std::initializer_list synthetic children", ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags, true);
-
- cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)deque<.+>(( )?&)?$")),
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator, "libc++ std::atomic synthetic children", ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_synth_flags, true);
+
+ cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^(std::__(ndk)?1::)deque<.+>(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
"lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "shared_ptr synthetic children", ConstString("^(std::__1::)shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "weak_ptr synthetic children", ConstString("^(std::__1::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "shared_ptr synthetic children", ConstString("^(std::__(ndk)?1::)shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "weak_ptr synthetic children", ConstString("^(std::__(ndk)?1::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(false);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("std::__1::vector<bool, std::__1::allocator<bool> >"), stl_synth_flags);
-
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector summary provider", ConstString("^std::__1::vector<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::list summary provider", ConstString("^std::__1::list<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::map summary provider", ConstString("^std::__1::map<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::deque summary provider", ConstString("^std::__1::deque<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector<bool> summary provider", ConstString("std::__1::vector<std::__1::allocator<bool> >"), stl_summary_flags);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector<bool> summary provider", ConstString("std::__1::vector<bool, std::__1::allocator<bool> >"), stl_summary_flags);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::set summary provider", ConstString("^std::__1::set<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multiset summary provider", ConstString("^std::__1::multiset<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multimap summary provider", ConstString("^std::__1::multimap<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::unordered containers summary provider", ConstString("^(std::__1::)unordered_(multi)?(map|set)<.+> >$"), stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector<bool> summary provider", ConstString("std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector summary provider", ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::list summary provider", ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::map summary provider", ConstString("^std::__(ndk)?1::map<.+>(( )?&)?$"), stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::deque summary provider", ConstString("^std::__(ndk)?1::deque<.+>(( )?&)?$"), stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::set summary provider", ConstString("^std::__(ndk)?1::set<.+>(( )?&)?$"), stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multiset summary provider", ConstString("^std::__(ndk)?1::multiset<.+>(( )?&)?$"), stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multimap summary provider", ConstString("^std::__(ndk)?1::multimap<.+>(( )?&)?$"), stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::unordered containers summary provider", ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"), stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider, "libc++ std::atomic summary provider", ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_summary_flags, true);
stl_summary_flags.SetSkipPointers(true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, "libc++ std::shared_ptr summary provider", ConstString("^std::__1::shared_ptr<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, "libc++ std::weak_ptr summary provider", ConstString("^std::__1::weak_ptr<.+>(( )?&)?$"), stl_summary_flags, true);
-
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^std::__1::__wrap_iter<.+>$"), stl_synth_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, "libc++ std::shared_ptr summary provider", ConstString("^std::__(ndk)?1::shared_ptr<.+>(( )?&)?$"), stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, "libc++ std::weak_ptr summary provider", ConstString("^std::__(ndk)?1::weak_ptr<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector<bool> summary provider", ConstString("std::__1::vector<bool, std::__1::allocator<bool> >"), stl_summary_flags);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::__1::__map_iterator<.+>$"), stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^std::__(ndk)?1::__wrap_iter<.+>$"), stl_synth_flags, true);
- AddFilter(cpp_category_sp, {"__a_"}, "libc++ std::atomic filter", ConstString("^std::__1::atomic<.*>$"), stl_synth_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector<bool> summary provider", ConstString("std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), stl_summary_flags);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::__(ndk)?1::__map_iterator<.+>$"), stl_synth_flags, true);
#endif
}
@@ -648,8 +650,22 @@ LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp)
"size=${svar%#}")));
AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true);
-
+
AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true);
+
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
+ "std::shared_ptr synthetic children", ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags,
+ true);
+ AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
+ "std::weak_ptr synthetic children", ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_synth_flags,
+ true);
+
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
+ "libstdc++ std::shared_ptr summary provider", ConstString("^std::shared_ptr<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
+ "libstdc++ std::weak_ptr summary provider", ConstString("^std::weak_ptr<.+>(( )?&)?$"),
+ stl_summary_flags, true);
#endif
}
@@ -774,6 +790,25 @@ CPlusPlusLanguage::GetHardcodedSummaries ()
}
return nullptr;
});
+ g_formatters.push_back(
+ [](lldb_private::ValueObject& valobj,
+ lldb::DynamicValueType,
+ FormatManager& fmt_mgr) -> TypeSummaryImpl::SharedPointer {
+ static CXXFunctionSummaryFormat::SharedPointer formatter_sp(new CXXFunctionSummaryFormat(TypeSummaryImpl::Flags()
+ .SetCascades(true)
+ .SetDontShowChildren(true)
+ .SetHideItemNames(true)
+ .SetShowMembersOneLiner(true)
+ .SetSkipPointers(true)
+ .SetSkipReferences(false),
+ lldb_private::formatters::BlockPointerSummaryProvider,
+ "block pointer summary provider"));
+ if (valobj.GetCompilerType().IsBlockPointerType(nullptr))
+ {
+ return formatter_sp;
+ }
+ return nullptr;
+ });
});
return g_formatters;
@@ -801,8 +836,21 @@ CPlusPlusLanguage::GetHardcodedSynthetics ()
}
return nullptr;
});
+ g_formatters.push_back(
+ [](lldb_private::ValueObject& valobj,
+ lldb::DynamicValueType,
+ FormatManager& fmt_mgr) -> SyntheticChildren::SharedPointer {
+ static CXXSyntheticChildren::SharedPointer formatter_sp(new CXXSyntheticChildren(SyntheticChildren::Flags().SetCascades(true).SetSkipPointers(true).SetSkipReferences(true).SetNonCacheable(true),
+ "block pointer synthetic children",
+ lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
+ if (valobj.GetCompilerType().IsBlockPointerType(nullptr))
+ {
+ return formatter_sp;
+ }
+ return nullptr;
+ });
+
});
return g_formatters;
}
-
diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
index 7e8d9582a2b5..a2c45fb99893 100644
--- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
+++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
@@ -192,6 +192,14 @@ lldb_private::formatters::WCharSummaryProvider (ValueObject& valobj, Stream& str
if (error.Fail())
return false;
+ // Get a wchar_t basic type from the current type system
+ CompilerType wchar_compiler_type = valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
+
+ if (!wchar_compiler_type)
+ return false;
+
+ const uint32_t wchar_size = wchar_compiler_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here
+
StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
options.SetData(data);
options.SetStream(&stream);
@@ -200,5 +208,17 @@ lldb_private::formatters::WCharSummaryProvider (ValueObject& valobj, Stream& str
options.SetSourceSize(1);
options.SetBinaryZeroIsTerminator(false);
- return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
+ switch (wchar_size)
+ {
+ case 8:
+ return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF8>(options);
+ case 16:
+ return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
+ case 32:
+ return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF32>(options);
+ default:
+ stream.Printf("size for wchar_t is not valid");
+ return true;
+ }
+ return true;
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 950bd62c5c9f..beb89b89c635 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -9,6 +9,10 @@
#include "LibCxx.h"
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
@@ -74,12 +78,12 @@ lldb_private::formatters::LibcxxSmartPointerSummaryProvider (ValueObject& valobj
}
lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::LibcxxVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_bool_type(),
-m_exe_ctx_ref(),
-m_count(0),
-m_base_data_address(0),
-m_children()
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_bool_type(),
+ m_exe_ctx_ref(),
+ m_count(0),
+ m_base_data_address(0),
+ m_children()
{
if (valobj_sp)
{
@@ -141,7 +145,7 @@ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex (si
return ValueObjectSP();
}
bool bit_set = ((byte & mask) != 0);
- DataBufferSP buffer_sp(new DataBufferHeap(m_bool_type.GetByteSize(nullptr),0));
+ DataBufferSP buffer_sp(new DataBufferHeap(m_bool_type.GetByteSize(nullptr), 0));
if (bit_set && buffer_sp && buffer_sp->GetBytes())
*(buffer_sp->GetBytes()) = 1; // regardless of endianness, anything non-zero is true
StreamString name; name.Printf("[%" PRIu64 "]", (uint64_t)idx);
@@ -208,15 +212,12 @@ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetIndexOfChildWith
return idx;
}
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::~LibcxxVectorBoolSyntheticFrontEnd ()
-{}
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::~LibcxxVectorBoolSyntheticFrontEnd() = default;
SyntheticChildrenFrontEnd*
lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
{
- if (!valobj_sp)
- return NULL;
- return (new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp));
+ return (valobj_sp ? new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp) : nullptr);
}
/*
@@ -238,8 +239,8 @@ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator (CXXSynthetic
*/
lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::LibCxxMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_pair_ptr()
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_pair_ptr()
{
if (valobj_sp)
Update();
@@ -264,11 +265,11 @@ lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update()
// it if were a ValueObjectSP, we would end up with a loop (iterator -> synthetic -> child -> parent == iterator)
// and that would in turn leak memory by never allowing the ValueObjects to die and free their memory
m_pair_ptr = valobj_sp->GetValueForExpressionPath(".__i_.__ptr_->__value_",
- NULL,
- NULL,
- NULL,
- ValueObject::GetValueForExpressionPathOptions().DontCheckDotVsArrowSyntax().SetSyntheticChildrenTraversal(ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal::None),
- NULL).get();
+ nullptr,
+ nullptr,
+ nullptr,
+ ValueObject::GetValueForExpressionPathOptions().DontCheckDotVsArrowSyntax().SetSyntheticChildrenTraversal(ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal::None),
+ nullptr).get();
return false;
}
@@ -312,9 +313,7 @@ lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::~LibCxxMapIterator
SyntheticChildrenFrontEnd*
lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
{
- if (!valobj_sp)
- return NULL;
- return (new LibCxxMapIteratorSyntheticFrontEnd(valobj_sp));
+ return (valobj_sp ? new LibCxxMapIteratorSyntheticFrontEnd(valobj_sp) : nullptr);
}
/*
@@ -332,18 +331,16 @@ lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator (CXXSynth
static ConstString g_item_name;
if (!g_item_name)
g_item_name.SetCString("__i");
- if (!valobj_sp)
- return NULL;
- return (new VectorIteratorSyntheticFrontEnd(valobj_sp,g_item_name));
+ return (valobj_sp ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name) : nullptr);
}
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_cntrl(NULL),
-m_count_sp(),
-m_weak_count_sp(),
-m_ptr_size(0),
-m_byte_order(lldb::eByteOrderInvalid)
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_cntrl(nullptr),
+ m_count_sp(),
+ m_weak_count_sp(),
+ m_ptr_size(0),
+ m_byte_order(lldb::eByteOrderInvalid)
{
if (valobj_sp)
Update();
@@ -404,7 +401,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update()
{
m_count_sp.reset();
m_weak_count_sp.reset();
- m_cntrl = NULL;
+ m_cntrl = nullptr;
ValueObjectSP valobj_sp = m_backend.GetSP();
if (!valobj_sp)
@@ -441,15 +438,12 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetIndexOfChildWithN
return UINT32_MAX;
}
-lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::~LibcxxSharedPtrSyntheticFrontEnd ()
-{}
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::~LibcxxSharedPtrSyntheticFrontEnd() = default;
SyntheticChildrenFrontEnd*
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
{
- if (!valobj_sp)
- return NULL;
- return (new LibcxxSharedPtrSyntheticFrontEnd(valobj_sp));
+ return (valobj_sp ? new LibcxxSharedPtrSyntheticFrontEnd(valobj_sp) : nullptr);
}
bool
@@ -462,7 +456,7 @@ lldb_private::formatters::LibcxxContainerSummaryProvider (ValueObject& valobj, S
return false;
stream.Printf("0x%016" PRIx64 " ", value);
}
- return FormatEntity::FormatStringRef("size=${svar%#}", stream, NULL, NULL, NULL, &valobj, false, false);
+ return FormatEntity::FormatStringRef("size=${svar%#}", stream, nullptr, nullptr, nullptr, &valobj, false, false);
}
// the field layout in a libc++ string (cap, side, data or data, size, cap)
@@ -551,7 +545,7 @@ bool
lldb_private::formatters::LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options)
{
uint64_t size = 0;
- ValueObjectSP location_sp((ValueObject*)nullptr);
+ ValueObjectSP location_sp;
if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
return false;
if (size == 0)
@@ -613,7 +607,7 @@ bool
lldb_private::formatters::LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options)
{
uint64_t size = 0;
- ValueObjectSP location_sp((ValueObject*)nullptr);
+ ValueObjectSP location_sp;
if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
return false;
@@ -643,7 +637,7 @@ lldb_private::formatters::LibcxxStringSummaryProvider (ValueObject& valobj, Stre
options.SetData(extractor);
options.SetStream(&stream);
- options.SetPrefixToken(0);
+ options.SetPrefixToken(nullptr);
options.SetQuote('"');
options.SetSourceSize(size);
options.SetBinaryZeroIsTerminator(false);
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp b/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
new file mode 100644
index 000000000000..a20d7f7d9871
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
@@ -0,0 +1,121 @@
+//===-- LibCxxAtomic.cpp ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibCxxAtomic.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+bool
+lldb_private::formatters::LibCxxAtomicSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
+{
+ static ConstString g___a_("__a_");
+
+ if (ValueObjectSP child = valobj.GetChildMemberWithName(g___a_, true))
+ {
+ std::string summary;
+ if (child->GetSummaryAsCString(summary, options) && summary.size() > 0)
+ {
+ stream.Printf("%s", summary.c_str());
+ return true;
+ }
+ }
+
+ return false;
+}
+
+namespace lldb_private {
+ namespace formatters {
+ class LibcxxStdAtomicSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibcxxStdAtomicSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ ~LibcxxStdAtomicSyntheticFrontEnd() override = default;
+
+ size_t
+ CalculateNumChildren() override;
+
+ lldb::ValueObjectSP
+ GetChildAtIndex(size_t idx) override;
+
+ bool
+ Update() override;
+
+ bool
+ MightHaveChildren() override;
+
+ size_t
+ GetIndexOfChildWithName(const ConstString &name) override;
+
+ lldb::ValueObjectSP
+ GetSyntheticValue () override;
+ private:
+ ValueObject *m_real_child;
+ };
+ } // namespace formatters
+} // namespace lldb_private
+
+lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::LibcxxStdAtomicSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_real_child(nullptr)
+{
+}
+
+bool
+lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::Update()
+{
+ static ConstString g___a_("__a_");
+
+ m_real_child = m_backend.GetChildMemberWithName(g___a_, true).get();
+
+ return false;
+}
+
+bool
+lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::MightHaveChildren()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::CalculateNumChildren()
+{
+ return m_real_child ? m_real_child->GetNumChildren() : 0;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex(size_t idx)
+{
+ return m_real_child ? m_real_child->GetChildAtIndex(idx, true) : nullptr;
+}
+
+size_t
+lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name)
+{
+ return m_real_child ? m_real_child->GetIndexOfChildWithName(name) : UINT32_MAX;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetSyntheticValue ()
+{
+ if (m_real_child && m_real_child->CanProvideValue())
+ return m_real_child->GetSP();
+ return nullptr;
+}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ if (valobj_sp)
+ return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp);
+ return nullptr;
+}
+
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h b/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h
new file mode 100644
index 000000000000..5cf729bfa45f
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h
@@ -0,0 +1,29 @@
+//===-- LibCxxAtomic.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_LibCxxAtomic_h_
+#define liblldb_LibCxxAtomic_h_
+
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/TypeSummary.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
+
+namespace lldb_private {
+ namespace formatters
+ {
+ bool
+ LibCxxAtomicSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+
+ SyntheticChildrenFrontEnd* LibcxxAtomicSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ } // namespace formatters
+} // namespace lldb_private
+
+#endif // liblldb_LibCxxAtomic_h_
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
index 9970d49dac62..54fddd15dd0b 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
@@ -50,18 +50,16 @@ namespace lldb_private {
CompilerType m_element_type;
uint32_t m_element_size;
size_t m_num_elements;
- std::map<size_t,lldb::ValueObjectSP> m_children;
};
} // namespace formatters
} // namespace lldb_private
lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::LibcxxInitializerListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_start(NULL),
-m_element_type(),
-m_element_size(0),
-m_num_elements(0),
-m_children()
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_start(nullptr),
+ m_element_type(),
+ m_element_size(0),
+ m_num_elements(0)
{
if (valobj_sp)
Update();
@@ -90,17 +88,11 @@ lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::GetChildAtInde
if (!m_start)
return lldb::ValueObjectSP();
- auto cached = m_children.find(idx);
- if (cached != m_children.end())
- return cached->second;
-
uint64_t offset = idx * m_element_size;
offset = offset + m_start->GetValueAsUnsigned(0);
StreamString name;
name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- ValueObjectSP child_sp = CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type);
- m_children[idx] = child_sp;
- return child_sp;
+ return CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type);
}
bool
@@ -110,10 +102,9 @@ lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::Update()
m_start = nullptr;
m_num_elements = 0;
- m_children.clear();
lldb::TemplateArgumentKind kind;
m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind);
- if (kind != lldb::eTemplateArgumentKindType || false == m_element_type.IsValid())
+ if (kind != lldb::eTemplateArgumentKindType || !m_element_type.IsValid())
return false;
m_element_size = m_element_type.GetByteSize(nullptr);
@@ -141,7 +132,5 @@ lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::GetIndexOfChil
lldb_private::SyntheticChildrenFrontEnd*
lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
{
- if (!valobj_sp)
- return NULL;
- return (new LibcxxInitializerListSyntheticFrontEnd(valobj_sp));
+ return (valobj_sp ? new LibcxxInitializerListSyntheticFrontEnd(valobj_sp) : nullptr);
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
index f86f968ea857..35cee566a773 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
@@ -34,7 +34,7 @@ namespace {
public:
ListEntry() = default;
ListEntry (ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
- ListEntry (const ListEntry& rhs) : m_entry_sp(rhs.m_entry_sp) {}
+ ListEntry(const ListEntry& rhs) = default;
ListEntry (ValueObject* entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
ListEntry
@@ -69,7 +69,7 @@ namespace {
explicit operator bool ()
{
- return GetEntry().get() != nullptr && null() == false;
+ return GetEntry() && !null();
}
ValueObjectSP
@@ -106,7 +106,7 @@ namespace {
ListIterator() = default;
ListIterator (ListEntry entry) : m_entry(entry) {}
ListIterator (ValueObjectSP entry) : m_entry(entry) {}
- ListIterator (const ListIterator& rhs) : m_entry(rhs.m_entry) {}
+ ListIterator(const ListIterator& rhs) = default;
ListIterator (ValueObject* entry) : m_entry(entry) {}
ValueObjectSP
@@ -200,23 +200,21 @@ namespace lldb_private {
ValueObject* m_tail;
CompilerType m_element_type;
size_t m_count;
- std::map<size_t,lldb::ValueObjectSP> m_children;
std::map<size_t, ListIterator> m_iterators;
};
} // namespace formatters
} // namespace lldb_private
lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_list_capping_size(0),
-m_loop_detected(0),
-m_node_address(),
-m_head(NULL),
-m_tail(NULL),
-m_element_type(),
-m_count(UINT32_MAX),
-m_children(),
-m_iterators()
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_list_capping_size(0),
+ m_loop_detected(0),
+ m_node_address(),
+ m_head(nullptr),
+ m_tail(nullptr),
+ m_element_type(),
+ m_count(UINT32_MAX),
+ m_iterators()
{
if (valobj_sp)
Update();
@@ -225,7 +223,7 @@ m_iterators()
bool
lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop(size_t count)
{
- if (g_use_loop_detect == false)
+ if (!g_use_loop_detect)
return false;
// don't bother checking for a loop if we won't actually need to jump nodes
if (m_count < 2)
@@ -312,10 +310,6 @@ lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex (size_
if (!m_head || !m_tail || m_node_address == 0)
return lldb::ValueObjectSP();
- auto cached = m_children.find(idx);
- if (cached != m_children.end())
- return cached->second;
-
if (HasLoop(idx+1))
return lldb::ValueObjectSP();
@@ -350,15 +344,17 @@ lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex (size_
StreamString name;
name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- return (m_children[idx] = CreateValueObjectFromData(name.GetData(), data, m_backend.GetExecutionContextRef(), m_element_type));
+ return CreateValueObjectFromData(name.GetData(),
+ data,
+ m_backend.GetExecutionContextRef(),
+ m_element_type);
}
bool
lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update()
{
- m_children.clear();
m_iterators.clear();
- m_head = m_tail = NULL;
+ m_head = m_tail = nullptr;
m_node_address = 0;
m_count = UINT32_MAX;
m_loop_detected = 0;
@@ -372,7 +368,7 @@ lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update()
m_list_capping_size = m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
if (m_list_capping_size == 0)
m_list_capping_size = 255;
- if (err.Fail() || backend_addr.get() == NULL)
+ if (err.Fail() || !backend_addr)
return false;
m_node_address = backend_addr->GetValueAsUnsigned(0);
if (!m_node_address || m_node_address == LLDB_INVALID_ADDRESS)
@@ -408,7 +404,5 @@ lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetIndexOfChildWithNam
SyntheticChildrenFrontEnd*
lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
{
- if (!valobj_sp)
- return NULL;
- return (new LibcxxStdListSyntheticFrontEnd(valobj_sp));
+ return (valobj_sp ? new LibcxxStdListSyntheticFrontEnd(valobj_sp) : nullptr);
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index aa82557edb02..d89869283cd3 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -32,7 +32,7 @@ class MapEntry
public:
MapEntry() = default;
explicit MapEntry (ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
- MapEntry (const MapEntry& rhs) : m_entry_sp(rhs.m_entry_sp) {}
+ MapEntry(const MapEntry& rhs) = default;
explicit MapEntry (ValueObject* entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
ValueObjectSP
@@ -124,7 +124,7 @@ public:
ValueObjectSP
advance (size_t count)
{
- ValueObjectSP fail(nullptr);
+ ValueObjectSP fail;
if (m_error)
return fail;
size_t steps = 0;
@@ -147,7 +147,7 @@ protected:
if (m_entry.null())
return;
MapEntry right(m_entry.right());
- if (right.null() == false)
+ if (!right.null())
{
m_entry = tree_min(std::move(right));
return;
@@ -179,7 +179,7 @@ private:
return MapEntry();
MapEntry left(x.left());
size_t steps = 0;
- while (left.null() == false)
+ while (!left.null())
{
if (left.error())
{
@@ -246,21 +246,19 @@ namespace lldb_private {
CompilerType m_element_type;
uint32_t m_skip_size;
size_t m_count;
- std::map<size_t, lldb::ValueObjectSP> m_children;
std::map<size_t, MapIterator> m_iterators;
};
} // namespace formatters
} // namespace lldb_private
lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_tree(NULL),
-m_root_node(NULL),
-m_element_type(),
-m_skip_size(UINT32_MAX),
-m_count(UINT32_MAX),
-m_children(),
-m_iterators()
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_tree(nullptr),
+ m_root_node(nullptr),
+ m_element_type(),
+ m_skip_size(UINT32_MAX),
+ m_count(UINT32_MAX),
+ m_iterators()
{
if (valobj_sp)
Update();
@@ -274,7 +272,7 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::CalculateNumChildren ()
if (m_count != UINT32_MAX)
return m_count;
- if (m_tree == NULL)
+ if (m_tree == nullptr)
return 0;
ValueObjectSP m_item(m_tree->GetChildMemberWithName(g___pair3_, true));
if (!m_item)
@@ -315,7 +313,7 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset (const l
return;
CompilerType node_type(node->GetCompilerType());
uint64_t bit_offset;
- if (node_type.GetIndexOfFieldWithName("__value_", NULL, &bit_offset) == UINT32_MAX)
+ if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) == UINT32_MAX)
return;
m_skip_size = bit_offset / 8u;
}
@@ -327,16 +325,11 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (size_t
static ConstString g___nc("__nc");
static ConstString g___value_("__value_");
-
if (idx >= CalculateNumChildren())
return lldb::ValueObjectSP();
- if (m_tree == NULL || m_root_node == NULL)
+ if (m_tree == nullptr || m_root_node == nullptr)
return lldb::ValueObjectSP();
- auto cached = m_children.find(idx);
- if (cached != m_children.end())
- return cached->second;
-
MapIterator iterator(m_root_node, CalculateNumChildren());
const bool need_to_skip = (idx > 0);
@@ -352,10 +345,10 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (size_t
}
ValueObjectSP iterated_sp(iterator.advance(actual_advancde));
- if (iterated_sp.get() == NULL)
+ if (!iterated_sp)
{
// this tree is garbage - stop
- m_tree = NULL; // this will stop all future searches until an Update() happens
+ m_tree = nullptr; // this will stop all future searches until an Update() happens
return iterated_sp;
}
if (GetDataType())
@@ -366,14 +359,14 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (size_t
iterated_sp = iterated_sp->Dereference(error);
if (!iterated_sp || error.Fail())
{
- m_tree = NULL;
+ m_tree = nullptr;
return lldb::ValueObjectSP();
}
GetValueOffset(iterated_sp);
iterated_sp = iterated_sp->GetChildMemberWithName(g___value_, true);
if (!iterated_sp)
{
- m_tree = NULL;
+ m_tree = nullptr;
return lldb::ValueObjectSP();
}
}
@@ -385,20 +378,20 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (size_t
GetChildAtIndex(0);
if (m_skip_size == UINT32_MAX)
{
- m_tree = NULL;
+ m_tree = nullptr;
return lldb::ValueObjectSP();
}
iterated_sp = iterated_sp->GetSyntheticChildAtOffset(m_skip_size, m_element_type, true);
if (!iterated_sp)
{
- m_tree = NULL;
+ m_tree = nullptr;
return lldb::ValueObjectSP();
}
}
}
else
{
- m_tree = NULL;
+ m_tree = nullptr;
return lldb::ValueObjectSP();
}
// at this point we have a valid
@@ -408,7 +401,7 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (size_t
iterated_sp->GetData(data, error);
if (error.Fail())
{
- m_tree = NULL;
+ m_tree = nullptr;
return lldb::ValueObjectSP();
}
StreamString name;
@@ -438,7 +431,7 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (size_t
potential_child_sp->SetName(ConstString(name.GetData()));
}
m_iterators[idx] = iterator;
- return (m_children[idx] = potential_child_sp);
+ return potential_child_sp;
}
bool
@@ -447,8 +440,7 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::Update()
static ConstString g___tree_("__tree_");
static ConstString g___begin_node_("__begin_node_");
m_count = UINT32_MAX;
- m_tree = m_root_node = NULL;
- m_children.clear();
+ m_tree = m_root_node = nullptr;
m_iterators.clear();
m_tree = m_backend.GetChildMemberWithName(g___tree_, true).get();
if (!m_tree)
@@ -472,7 +464,5 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetIndexOfChildWithName
SyntheticChildrenFrontEnd*
lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
{
- if (!valobj_sp)
- return NULL;
- return (new LibcxxStdMapSyntheticFrontEnd(valobj_sp));
+ return (valobj_sp ? new LibcxxStdMapSyntheticFrontEnd(valobj_sp) : nullptr);
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index 8ad806d52bce..a547695448ce 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -55,19 +55,17 @@ namespace lldb_private {
ValueObject* m_tree;
size_t m_num_elements;
ValueObject* m_next_element;
- std::map<size_t,lldb::ValueObjectSP> m_children;
std::vector<std::pair<ValueObject*, uint64_t> > m_elements_cache;
};
} // namespace formatters
} // namespace lldb_private
lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_tree(NULL),
-m_num_elements(0),
-m_next_element(nullptr),
-m_children(),
-m_elements_cache()
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_tree(nullptr),
+ m_num_elements(0),
+ m_next_element(nullptr),
+ m_elements_cache()
{
if (valobj_sp)
Update();
@@ -86,13 +84,9 @@ lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtInde
{
if (idx >= CalculateNumChildren())
return lldb::ValueObjectSP();
- if (m_tree == NULL)
+ if (m_tree == nullptr)
return lldb::ValueObjectSP();
- auto cached = m_children.find(idx);
- if (cached != m_children.end())
- return cached->second;
-
while (idx >= m_elements_cache.size())
{
if (m_next_element == nullptr)
@@ -125,10 +119,10 @@ lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtInde
return lldb::ValueObjectSP();
const bool thread_and_frame_only_if_stopped = true;
ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped);
- return val_hash.first->CreateValueObjectFromData(stream.GetData(),
- data,
- exe_ctx,
- val_hash.first->GetCompilerType());
+ return CreateValueObjectFromData(stream.GetData(),
+ data,
+ exe_ctx,
+ val_hash.first->GetCompilerType());
}
bool
@@ -137,7 +131,6 @@ lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::Update()
m_num_elements = UINT32_MAX;
m_next_element = nullptr;
m_elements_cache.clear();
- m_children.clear();
ValueObjectSP table_sp = m_backend.GetChildMemberWithName(ConstString("__table_"), true);
if (!table_sp)
return false;
@@ -166,7 +159,5 @@ lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetIndexOfChil
SyntheticChildrenFrontEnd*
lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
{
- if (!valobj_sp)
- return NULL;
- return (new LibcxxStdUnorderedMapSyntheticFrontEnd(valobj_sp));
+ return (valobj_sp ? new LibcxxStdUnorderedMapSyntheticFrontEnd(valobj_sp) : nullptr);
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
index 9fb4f48e9090..ed26eaea121c 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
@@ -50,18 +50,16 @@ namespace lldb_private {
ValueObject* m_finish;
CompilerType m_element_type;
uint32_t m_element_size;
- std::map<size_t,lldb::ValueObjectSP> m_children;
};
} // namespace formatters
} // namespace lldb_private
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_start(NULL),
-m_finish(NULL),
-m_element_type(),
-m_element_size(0),
-m_children()
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_start(nullptr),
+ m_finish(nullptr),
+ m_element_type(),
+ m_element_size(0)
{
if (valobj_sp)
Update();
@@ -100,24 +98,20 @@ lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (siz
if (!m_start || !m_finish)
return lldb::ValueObjectSP();
- auto cached = m_children.find(idx);
- if (cached != m_children.end())
- return cached->second;
-
uint64_t offset = idx * m_element_size;
offset = offset + m_start->GetValueAsUnsigned(0);
StreamString name;
name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- ValueObjectSP child_sp = CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type);
- m_children[idx] = child_sp;
- return child_sp;
+ return CreateValueObjectFromAddress(name.GetData(),
+ offset,
+ m_backend.GetExecutionContextRef(),
+ m_element_type);
}
bool
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update()
{
- m_start = m_finish = NULL;
- m_children.clear();
+ m_start = m_finish = nullptr;
ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true));
if (!data_type_finder_sp)
return false;
@@ -153,7 +147,5 @@ lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithN
lldb_private::SyntheticChildrenFrontEnd*
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
{
- if (!valobj_sp)
- return NULL;
- return (new LibcxxStdVectorSyntheticFrontEnd(valobj_sp));
+ return (valobj_sp ? new LibcxxStdVectorSyntheticFrontEnd(valobj_sp) : nullptr);
}
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
index ed89c5c84ea3..6d6f915f68e2 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
@@ -1,4 +1,4 @@
-//===-- LibStdcpp.cpp ---------------------------------------------*- C++ -*-===//
+//===-- LibStdcpp.cpp -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,6 +9,10 @@
#include "LibStdcpp.h"
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Stream.h"
@@ -24,11 +28,25 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
+namespace
+{
+
class LibstdcppMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
{
+ /*
+ (std::_Rb_tree_iterator<std::pair<const int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) ibeg = {
+ (_Base_ptr) _M_node = 0x0000000100103910 {
+ (std::_Rb_tree_color) _M_color = _S_black
+ (std::_Rb_tree_node_base::_Base_ptr) _M_parent = 0x00000001001038c0
+ (std::_Rb_tree_node_base::_Base_ptr) _M_left = 0x0000000000000000
+ (std::_Rb_tree_node_base::_Base_ptr) _M_right = 0x0000000000000000
+ }
+ }
+ */
+
public:
- LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
+ explicit LibstdcppMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
size_t
CalculateNumChildren() override;
@@ -44,41 +62,45 @@ public:
size_t
GetIndexOfChildWithName (const ConstString &name) override;
- ~LibstdcppMapIteratorSyntheticFrontEnd() override;
-
private:
ExecutionContextRef m_exe_ctx_ref;
lldb::addr_t m_pair_address;
CompilerType m_pair_type;
- EvaluateExpressionOptions m_options;
lldb::ValueObjectSP m_pair_sp;
};
-/*
- (std::_Rb_tree_iterator<std::pair<const int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) ibeg = {
- (_Base_ptr) _M_node = 0x0000000100103910 {
- (std::_Rb_tree_color) _M_color = _S_black
- (std::_Rb_tree_node_base::_Base_ptr) _M_parent = 0x00000001001038c0
- (std::_Rb_tree_node_base::_Base_ptr) _M_left = 0x0000000000000000
- (std::_Rb_tree_node_base::_Base_ptr) _M_right = 0x0000000000000000
- }
- }
- */
+class LibStdcppSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+{
+public:
+ explicit LibStdcppSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ size_t
+ CalculateNumChildren() override;
+
+ lldb::ValueObjectSP
+ GetChildAtIndex(size_t idx) override;
+
+ bool
+ Update() override;
+
+ bool
+ MightHaveChildren() override;
+
+ size_t
+ GetIndexOfChildWithName(const ConstString &name) override;
+};
+
+} // end of anonymous namespace
LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp.get()),
+ SyntheticChildrenFrontEnd(*valobj_sp),
m_exe_ctx_ref(),
m_pair_address(0),
m_pair_type(),
- m_options(),
m_pair_sp()
{
if (valobj_sp)
Update();
- m_options.SetCoerceToId(false);
- m_options.SetUnwindOnError(true);
- m_options.SetKeepInMemory(true);
- m_options.SetUseDynamic(lldb::eDynamicCanRunTarget);
}
bool
@@ -159,15 +181,10 @@ LibstdcppMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstStrin
return UINT32_MAX;
}
-LibstdcppMapIteratorSyntheticFrontEnd::~LibstdcppMapIteratorSyntheticFrontEnd ()
-{}
-
SyntheticChildrenFrontEnd*
lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
{
- if (!valobj_sp)
- return NULL;
- return (new LibstdcppMapIteratorSyntheticFrontEnd(valobj_sp));
+ return (valobj_sp ? new LibstdcppMapIteratorSyntheticFrontEnd(valobj_sp) : nullptr);
}
/*
@@ -185,24 +202,22 @@ lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSy
static ConstString g_item_name;
if (!g_item_name)
g_item_name.SetCString("_M_current");
- if (!valobj_sp)
- return NULL;
- return (new VectorIteratorSyntheticFrontEnd(valobj_sp,g_item_name));
+ return (valobj_sp ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name) : nullptr);
}
lldb_private::formatters::VectorIteratorSyntheticFrontEnd::VectorIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp,
ConstString item_name) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_exe_ctx_ref(),
-m_item_name(item_name),
-m_item_sp()
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_exe_ctx_ref(),
+ m_item_name(item_name),
+ m_item_sp()
{
if (valobj_sp)
Update();
}
bool
-lldb_private::formatters::VectorIteratorSyntheticFrontEnd::Update()
+VectorIteratorSyntheticFrontEnd::Update()
{
m_item_sp.reset();
@@ -227,13 +242,13 @@ lldb_private::formatters::VectorIteratorSyntheticFrontEnd::Update()
}
size_t
-lldb_private::formatters::VectorIteratorSyntheticFrontEnd::CalculateNumChildren ()
+VectorIteratorSyntheticFrontEnd::CalculateNumChildren()
{
return 1;
}
lldb::ValueObjectSP
-lldb_private::formatters::VectorIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+VectorIteratorSyntheticFrontEnd::GetChildAtIndex(size_t idx)
{
if (idx == 0)
return m_item_sp;
@@ -241,23 +256,19 @@ lldb_private::formatters::VectorIteratorSyntheticFrontEnd::GetChildAtIndex (size
}
bool
-lldb_private::formatters::VectorIteratorSyntheticFrontEnd::MightHaveChildren ()
+VectorIteratorSyntheticFrontEnd::MightHaveChildren()
{
return true;
}
size_t
-lldb_private::formatters::VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name)
{
if (name == ConstString("item"))
return 0;
return UINT32_MAX;
}
-lldb_private::formatters::VectorIteratorSyntheticFrontEnd::~VectorIteratorSyntheticFrontEnd ()
-{
-}
-
bool
lldb_private::formatters::LibStdcppStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
{
@@ -371,3 +382,95 @@ lldb_private::formatters::LibStdcppWStringSummaryProvider (ValueObject& valobj,
}
return false;
}
+
+LibStdcppSharedPtrSyntheticFrontEnd::LibStdcppSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp)
+{
+ if (valobj_sp)
+ Update();
+}
+
+size_t
+LibStdcppSharedPtrSyntheticFrontEnd::CalculateNumChildren()
+{
+ return 1;
+}
+
+lldb::ValueObjectSP
+LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(size_t idx)
+{
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return lldb::ValueObjectSP();
+
+ if (idx == 0)
+ return valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true);
+ else
+ return lldb::ValueObjectSP();
+}
+
+bool
+LibStdcppSharedPtrSyntheticFrontEnd::Update()
+{
+ return false;
+}
+
+bool
+LibStdcppSharedPtrSyntheticFrontEnd::MightHaveChildren()
+{
+ return true;
+}
+
+size_t
+LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name)
+{
+ if (name == ConstString("_M_ptr"))
+ return 0;
+ return UINT32_MAX;
+}
+
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp)
+{
+ return (valobj_sp ? new LibStdcppSharedPtrSyntheticFrontEnd(valobj_sp) : nullptr);
+}
+
+bool
+lldb_private::formatters::LibStdcppSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options)
+{
+ ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+ if (!valobj_sp)
+ return false;
+
+ ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true));
+ if (!ptr_sp)
+ return false;
+
+ ValueObjectSP usecount_sp(
+ valobj_sp->GetChildAtNamePath({ConstString("_M_refcount"), ConstString("_M_pi"), ConstString("_M_use_count")}));
+ if (!usecount_sp)
+ return false;
+
+ if (ptr_sp->GetValueAsUnsigned(0) == 0 || usecount_sp->GetValueAsUnsigned(0) == 0)
+ {
+ stream.Printf("nullptr");
+ return true;
+ }
+
+ Error error;
+ ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
+ if (pointee_sp && error.Success())
+ {
+ if (pointee_sp->DumpPrintableRepresentation(stream, ValueObject::eValueObjectRepresentationStyleSummary,
+ lldb::eFormatInvalid,
+ ValueObject::ePrintableRepresentationSpecialCasesDisable, false))
+ {
+ return true;
+ }
+ }
+
+ stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
+ return true;
+}
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/source/Plugins/Language/CPlusPlus/LibStdcpp.h
index 347856a1695c..b84c0ff831eb 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcpp.h
+++ b/source/Plugins/Language/CPlusPlus/LibStdcpp.h
@@ -24,9 +24,14 @@ namespace lldb_private {
bool
LibStdcppWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libcstdc++ c++11 std::wstring
+ bool
+ LibStdcppSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libstdc++ std::shared_ptr<> and std::weak_ptr<>
+
SyntheticChildrenFrontEnd* LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
+
SyntheticChildrenFrontEnd* LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ SyntheticChildrenFrontEnd* LibStdcppSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
} // namespace formatters
} // namespace lldb_private
diff --git a/source/Plugins/Language/CPlusPlus/Makefile b/source/Plugins/Language/CPlusPlus/Makefile
deleted file mode 100644
index 2cb0dcf638b3..000000000000
--- a/source/Plugins/Language/CPlusPlus/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Language/CPlusPlus -------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginCPlusPlusLanguage
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Language/Go/Makefile b/source/Plugins/Language/Go/Makefile
deleted file mode 100644
index 3ea09f6c538f..000000000000
--- a/source/Plugins/Language/Go/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Language/Go -------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginGoLanguage
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Language/Java/CMakeLists.txt b/source/Plugins/Language/Java/CMakeLists.txt
new file mode 100644
index 000000000000..80f7b08e7b65
--- /dev/null
+++ b/source/Plugins/Language/Java/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_lldb_library(lldbPluginJavaLanguage
+ JavaFormatterFunctions.cpp
+ JavaLanguage.cpp
+)
diff --git a/source/Plugins/Language/Java/JavaFormatterFunctions.cpp b/source/Plugins/Language/Java/JavaFormatterFunctions.cpp
new file mode 100644
index 000000000000..29e6ad0ee89f
--- /dev/null
+++ b/source/Plugins/Language/Java/JavaFormatterFunctions.cpp
@@ -0,0 +1,186 @@
+//===-- JavaFormatterFunctions.cpp-------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "JavaFormatterFunctions.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/DataFormatters/StringPrinter.h"
+#include "lldb/Symbol/JavaASTContext.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+namespace
+{
+
+class JavaArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd
+{
+public:
+ JavaArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) :
+ SyntheticChildrenFrontEnd(*valobj_sp)
+ {
+ if (valobj_sp)
+ Update();
+ }
+
+ size_t
+ CalculateNumChildren() override
+ {
+ ValueObjectSP valobj = GetDereferencedValueObject();
+ if (!valobj)
+ return 0;
+
+ CompilerType type = valobj->GetCompilerType();
+ uint32_t size = JavaASTContext::CalculateArraySize(type, *valobj);
+ if (size == UINT32_MAX)
+ return 0;
+ return size;
+ }
+
+ lldb::ValueObjectSP
+ GetChildAtIndex(size_t idx) override
+ {
+ ValueObjectSP valobj = GetDereferencedValueObject();
+ if (!valobj)
+ return nullptr;
+
+ ProcessSP process_sp = valobj->GetProcessSP();
+ if (!process_sp)
+ return nullptr;
+
+ CompilerType type = valobj->GetCompilerType();
+ CompilerType element_type = type.GetArrayElementType();
+ lldb::addr_t address = valobj->GetAddressOf() + JavaASTContext::CalculateArrayElementOffset(type, idx);
+
+ Error error;
+ size_t byte_size = element_type.GetByteSize(nullptr);
+ DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
+ size_t bytes_read = process_sp->ReadMemory(address, buffer_sp->GetBytes(), byte_size, error);
+ if (error.Fail() || byte_size != bytes_read)
+ return nullptr;
+
+ StreamString name;
+ name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ DataExtractor data(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize());
+ return CreateValueObjectFromData(name.GetData(), data, valobj->GetExecutionContextRef(),
+ element_type);
+ }
+
+ bool
+ Update() override
+ {
+ return false;
+ }
+
+ bool
+ MightHaveChildren() override
+ {
+ return true;
+ }
+
+ size_t
+ GetIndexOfChildWithName(const ConstString &name) override
+ {
+ return ExtractIndexFromString(name.GetCString());
+ }
+
+private:
+ ValueObjectSP
+ GetDereferencedValueObject()
+ {
+ if (!m_backend.IsPointerOrReferenceType())
+ return m_backend.GetSP();
+
+ Error error;
+ return m_backend.Dereference(error);
+ }
+};
+
+} // end of anonymous namespace
+
+bool
+lldb_private::formatters::JavaStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts)
+{
+ if (valobj.IsPointerOrReferenceType())
+ {
+ Error error;
+ ValueObjectSP deref = valobj.Dereference(error);
+ if (error.Fail())
+ return false;
+ return JavaStringSummaryProvider(*deref, stream, opts);
+ }
+
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ConstString data_name("value");
+ ConstString length_name("count");
+
+ ValueObjectSP length_sp = valobj.GetChildMemberWithName(length_name, true);
+ ValueObjectSP data_sp = valobj.GetChildMemberWithName(data_name, true);
+ if (!data_sp || !length_sp)
+ return false;
+
+ bool success = false;
+ uint64_t length = length_sp->GetValueAsUnsigned(0, &success);
+ if (!success)
+ return false;
+
+ if (length == 0)
+ {
+ stream.Printf("\"\"");
+ return true;
+ }
+ lldb::addr_t valobj_addr = data_sp->GetAddressOf();
+
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(valobj_addr);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetSourceSize(length);
+ options.SetNeedsZeroTermination(false);
+ options.SetLanguage(eLanguageTypeJava);
+
+ if (StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options))
+ return true;
+
+ stream.Printf("Summary Unavailable");
+ return true;
+}
+
+bool
+lldb_private::formatters::JavaArraySummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
+{
+ if (valobj.IsPointerOrReferenceType())
+ {
+ Error error;
+ ValueObjectSP deref = valobj.Dereference(error);
+ if (error.Fail())
+ return false;
+ return JavaArraySummaryProvider(*deref, stream, options);
+ }
+
+ CompilerType type = valobj.GetCompilerType();
+ uint32_t size = JavaASTContext::CalculateArraySize(type, valobj);
+ if (size == UINT32_MAX)
+ return false;
+ stream.Printf("[%u]{...}", size);
+ return true;
+}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::JavaArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ return valobj_sp ? new JavaArraySyntheticFrontEnd(valobj_sp) : nullptr;
+}
diff --git a/source/Plugins/Language/Java/JavaFormatterFunctions.h b/source/Plugins/Language/Java/JavaFormatterFunctions.h
new file mode 100644
index 000000000000..f9588c5590ae
--- /dev/null
+++ b/source/Plugins/Language/Java/JavaFormatterFunctions.h
@@ -0,0 +1,36 @@
+//===-- JavaFormatterFunctions.h---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_JavaFormatterFunctions_h_
+#define liblldb_JavaFormatterFunctions_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-forward.h"
+
+namespace lldb_private
+{
+namespace formatters
+{
+
+bool
+JavaStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
+
+bool
+JavaArraySummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
+
+SyntheticChildrenFrontEnd*
+JavaArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp);
+
+} // namespace formatters
+} // namespace lldb_private
+
+#endif // liblldb_JavaFormatterFunctions_h_
diff --git a/source/Plugins/Language/Java/JavaLanguage.cpp b/source/Plugins/Language/Java/JavaLanguage.cpp
new file mode 100644
index 000000000000..a4f883f68827
--- /dev/null
+++ b/source/Plugins/Language/Java/JavaLanguage.cpp
@@ -0,0 +1,112 @@
+//===-- JavaLanguage.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <string.h>
+// C++ Includes
+#include <functional>
+#include <mutex>
+
+// Other libraries and framework includes
+#include "llvm/ADT/StringRef.h"
+
+// Project includes
+#include "JavaFormatterFunctions.h"
+#include "JavaLanguage.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/DataFormatters/DataVisualization.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Symbol/JavaASTContext.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+void
+JavaLanguage::Initialize()
+{
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java Language", CreateInstance);
+}
+
+void
+JavaLanguage::Terminate()
+{
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString
+JavaLanguage::GetPluginNameStatic()
+{
+ static ConstString g_name("Java");
+ return g_name;
+}
+
+lldb_private::ConstString
+JavaLanguage::GetPluginName()
+{
+ return GetPluginNameStatic();
+}
+
+uint32_t
+JavaLanguage::GetPluginVersion()
+{
+ return 1;
+}
+
+Language *
+JavaLanguage::CreateInstance(lldb::LanguageType language)
+{
+ if (language == eLanguageTypeJava)
+ return new JavaLanguage();
+ return nullptr;
+}
+
+bool
+JavaLanguage::IsNilReference(ValueObject &valobj)
+{
+ if (!valobj.GetCompilerType().IsReferenceType())
+ return false;
+
+ // If we failed to read the value then it is not a nil reference.
+ return valobj.GetValueAsUnsigned(UINT64_MAX) == 0;
+}
+
+lldb::TypeCategoryImplSP
+JavaLanguage::GetFormatters()
+{
+ static std::once_flag g_initialize;
+ static TypeCategoryImplSP g_category;
+
+ std::call_once(g_initialize, [this]() -> void {
+ DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
+ if (g_category)
+ {
+ const char* array_regexp = "^.*\\[\\]&?$";
+
+ lldb::TypeSummaryImplSP string_summary_sp(new CXXFunctionSummaryFormat(
+ TypeSummaryImpl::Flags().SetDontShowChildren(true), lldb_private::formatters::JavaStringSummaryProvider,
+ "java.lang.String summary provider"));
+ g_category->GetTypeSummariesContainer()->Add(ConstString("java::lang::String"), string_summary_sp);
+
+ lldb::TypeSummaryImplSP array_summary_sp(new CXXFunctionSummaryFormat(
+ TypeSummaryImpl::Flags().SetDontShowChildren(true), lldb_private::formatters::JavaArraySummaryProvider,
+ "Java array summary provider"));
+ g_category->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression(array_regexp)),
+ array_summary_sp);
+
+#ifndef LLDB_DISABLE_PYTHON
+ AddCXXSynthetic(g_category, lldb_private::formatters::JavaArraySyntheticFrontEndCreator,
+ "Java array synthetic children", ConstString(array_regexp),
+ SyntheticChildren::Flags().SetCascades(true), true);
+#endif
+ }
+ });
+ return g_category;
+}
diff --git a/source/Plugins/Language/Java/JavaLanguage.h b/source/Plugins/Language/Java/JavaLanguage.h
new file mode 100644
index 000000000000..164facd27ab5
--- /dev/null
+++ b/source/Plugins/Language/Java/JavaLanguage.h
@@ -0,0 +1,64 @@
+//===-- JavaLanguage.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_JavaLanguage_h_
+#define liblldb_JavaLanguage_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+#include "llvm/ADT/StringRef.h"
+
+// Project includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/Target/Language.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private
+{
+
+class JavaLanguage : public Language
+{
+public:
+ lldb::LanguageType
+ GetLanguageType() const override
+ {
+ return lldb::eLanguageTypeJava;
+ }
+
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb_private::Language *
+ CreateInstance(lldb::LanguageType language);
+
+ static lldb_private::ConstString
+ GetPluginNameStatic();
+
+ ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
+
+ bool
+ IsNilReference(ValueObject &valobj) override;
+
+ lldb::TypeCategoryImplSP
+ GetFormatters() override;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_JavaLanguage_h_
diff --git a/source/Plugins/Language/ObjC/CF.cpp b/source/Plugins/Language/ObjC/CF.cpp
index 614eb29a0f7a..617bb613aa0b 100644
--- a/source/Plugins/Language/ObjC/CF.cpp
+++ b/source/Plugins/Language/ObjC/CF.cpp
@@ -73,37 +73,28 @@ lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& str
if (descriptor->IsCFType())
{
ConstString type_name(valobj.GetTypeName());
- if (type_name == ConstString("__CFBag") || type_name == ConstString("const struct __CFBag"))
+
+ static ConstString g___CFBag("__CFBag");
+ static ConstString g_conststruct__CFBag("const struct __CFBag");
+
+ if (type_name == g___CFBag ||
+ type_name == g_conststruct__CFBag)
{
if (valobj.IsPointerType())
is_type_ok = true;
}
}
- if (is_type_ok == false)
- {
- StackFrameSP frame_sp(valobj.GetFrameSP());
- if (!frame_sp)
- return false;
- ValueObjectSP count_sp;
- StreamString expr;
- expr.Printf("(int)CFBagGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue());
- EvaluateExpressionOptions options;
- options.SetResultIsInternal(true);
- if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp, options) != eExpressionCompleted)
- return false;
- if (!count_sp)
- return false;
- count = count_sp->GetValueAsUnsigned(0);
- }
- else
+ if (is_type_ok)
{
- uint32_t offset = 2*ptr_size+4 + valobj_addr;
+ lldb::addr_t offset = 2*ptr_size+4 + valobj_addr;
Error error;
count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
if (error.Fail())
return false;
}
+ else
+ return false;
std::string prefix,suffix;
if (Language* language = Language::FindPlugin(options.GetLanguage()))
@@ -284,37 +275,30 @@ lldb_private::formatters::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stre
if (descriptor->IsCFType())
{
ConstString type_name(valobj.GetTypeName());
- if (type_name == ConstString("__CFBinaryHeap") || type_name == ConstString("const struct __CFBinaryHeap"))
+
+ static ConstString g___CFBinaryHeap("__CFBinaryHeap");
+ static ConstString g_conststruct__CFBinaryHeap("const struct __CFBinaryHeap");
+ static ConstString g_CFBinaryHeapRef("CFBinaryHeapRef");
+
+ if (type_name == g___CFBinaryHeap ||
+ type_name == g_conststruct__CFBinaryHeap ||
+ type_name == g_CFBinaryHeapRef)
{
if (valobj.IsPointerType())
is_type_ok = true;
}
}
- if (is_type_ok == false)
+ if (is_type_ok)
{
- StackFrameSP frame_sp(valobj.GetFrameSP());
- if (!frame_sp)
- return false;
- ValueObjectSP count_sp;
- StreamString expr;
- expr.Printf("(int)CFBinaryHeapGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue());
- EvaluateExpressionOptions options;
- options.SetResultIsInternal(true);
- if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp, options) != eExpressionCompleted)
- return false;
- if (!count_sp)
- return false;
- count = count_sp->GetValueAsUnsigned(0);
- }
- else
- {
- uint32_t offset = 2*ptr_size;
+ lldb::addr_t offset = 2*ptr_size + valobj_addr;
Error error;
count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
if (error.Fail())
return false;
}
+ else
+ return false;
std::string prefix,suffix;
if (Language* language = Language::FindPlugin(options.GetLanguage()))
diff --git a/source/Plugins/Language/ObjC/Cocoa.cpp b/source/Plugins/Language/ObjC/Cocoa.cpp
index aa6e476b6131..017c46ee3bb3 100644
--- a/source/Plugins/Language/ObjC/Cocoa.cpp
+++ b/source/Plugins/Language/ObjC/Cocoa.cpp
@@ -50,7 +50,7 @@ lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream&
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
uint32_t ptr_size = process_sp->GetAddressByteSize();
@@ -71,16 +71,15 @@ lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream&
ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID), true));
StreamString summary_stream;
- bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream, options);
+ bool was_nsstring_ok = NSStringSummaryProvider(*text, summary_stream, options);
if (was_nsstring_ok && summary_stream.GetSize() > 0)
{
stream.Printf("%s",summary_stream.GetData());
return true;
}
}
- // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle]
- // which is encoded differently and needs to be handled by running code
- return ExtractSummaryFromObjCExpression(valobj, "NSString*", "bundlePath", stream, options.GetLanguage());
+
+ return false;
}
bool
@@ -97,7 +96,7 @@ lldb_private::formatters::NSTimeZoneSummaryProvider (ValueObject& valobj, Stream
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
uint32_t ptr_size = process_sp->GetAddressByteSize();
@@ -117,14 +116,15 @@ lldb_private::formatters::NSTimeZoneSummaryProvider (ValueObject& valobj, Stream
uint64_t offset = ptr_size;
ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetCompilerType(), true));
StreamString summary_stream;
- bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream, options);
+ bool was_nsstring_ok = NSStringSummaryProvider(*text, summary_stream, options);
if (was_nsstring_ok && summary_stream.GetSize() > 0)
{
stream.Printf("%s",summary_stream.GetData());
return true;
}
}
- return ExtractSummaryFromObjCExpression(valobj, "NSString*", "name", stream, options.GetLanguage());
+
+ return false;
}
bool
@@ -141,7 +141,7 @@ lldb_private::formatters::NSNotificationSummaryProvider (ValueObject& valobj, St
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
uint32_t ptr_size = process_sp->GetAddressByteSize();
@@ -161,16 +161,15 @@ lldb_private::formatters::NSNotificationSummaryProvider (ValueObject& valobj, St
uint64_t offset = ptr_size;
ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetCompilerType(), true));
StreamString summary_stream;
- bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream, options);
+ bool was_nsstring_ok = NSStringSummaryProvider(*text, summary_stream, options);
if (was_nsstring_ok && summary_stream.GetSize() > 0)
{
stream.Printf("%s",summary_stream.GetData());
return true;
}
}
- // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle]
- // which is encoded differently and needs to be handled by running code
- return ExtractSummaryFromObjCExpression(valobj, "NSString*", "name", stream, options.GetLanguage());
+
+ return false;
}
bool
@@ -187,7 +186,7 @@ lldb_private::formatters::NSMachPortSummaryProvider (ValueObject& valobj, Stream
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
uint32_t ptr_size = process_sp->GetAddressByteSize();
@@ -204,22 +203,19 @@ lldb_private::formatters::NSMachPortSummaryProvider (ValueObject& valobj, Stream
uint64_t port_number = 0;
- do
+ if (!strcmp(class_name,"NSMachPort"))
{
- if (!strcmp(class_name,"NSMachPort"))
+ uint64_t offset = (ptr_size == 4 ? 12 : 20);
+ Error error;
+ port_number = process_sp->ReadUnsignedIntegerFromMemory(offset+valobj_addr, 4, 0, error);
+ if (error.Success())
{
- uint64_t offset = (ptr_size == 4 ? 12 : 20);
- Error error;
- port_number = process_sp->ReadUnsignedIntegerFromMemory(offset+valobj_addr, 4, 0, error);
- if (error.Success())
- break;
+ stream.Printf("mach port: %u",(uint32_t)(port_number & 0x00000000FFFFFFFF));
+ return true;
}
- if (!ExtractValueFromObjCExpression(valobj, "int", "machPort", port_number))
- return false;
- } while (false);
+ }
- stream.Printf("mach port: %u",(uint32_t)(port_number & 0x00000000FFFFFFFF));
- return true;
+ return false;
}
bool
@@ -236,7 +232,7 @@ lldb_private::formatters::NSIndexSetSummaryProvider (ValueObject& valobj, Stream
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
uint32_t ptr_size = process_sp->GetAddressByteSize();
@@ -289,10 +285,7 @@ lldb_private::formatters::NSIndexSetSummaryProvider (ValueObject& valobj, Stream
}
}
else
- {
- if (!ExtractValueFromObjCExpression(valobj, "unsigned long long int", "count", count))
- return false;
- }
+ return false;
} while (false);
stream.Printf("%" PRIu64 " index%s",
count,
@@ -458,7 +451,7 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream&
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
uint32_t ptr_size = process_sp->GetAddressByteSize();
@@ -531,6 +524,7 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream&
break;
case 17: // 0B10001
data_location += 8;
+ LLVM_FALLTHROUGH;
case 4: // 0B0100
value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
if (error.Fail())
@@ -542,7 +536,8 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream&
uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
if (error.Fail())
return false;
- float flt_value = *((float*)&flt_as_int);
+ float flt_value = 0.0f;
+ memcpy(&flt_value, &flt_as_int, sizeof(flt_as_int));
NSNumber_FormatFloat(valobj, stream, flt_value, options.GetLanguage());
break;
}
@@ -551,7 +546,8 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream&
uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
if (error.Fail())
return false;
- double dbl_value = *((double*)&dbl_as_lng);
+ double dbl_value = 0.0;
+ memcpy(&dbl_value, &dbl_as_lng, sizeof(dbl_as_lng));
NSNumber_FormatDouble(valobj, stream, dbl_value, options.GetLanguage());
break;
}
@@ -561,10 +557,8 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream&
return true;
}
}
- else
- {
- return ExtractSummaryFromObjCExpression(valobj, "NSString*", "stringValue", stream, options.GetLanguage());
- }
+
+ return false;
}
bool
@@ -581,7 +575,7 @@ lldb_private::formatters::NSURLSummaryProvider (ValueObject& valobj, Stream& str
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
uint32_t ptr_size = process_sp->GetAddressByteSize();
@@ -625,10 +619,7 @@ lldb_private::formatters::NSURLSummaryProvider (ValueObject& valobj, Stream& str
return true;
}
}
- else
- {
- return ExtractSummaryFromObjCExpression(valobj, "NSString*", "description", stream, options.GetLanguage());
- }
+
return false;
}
@@ -646,7 +637,7 @@ lldb_private::formatters::NSDateSummaryProvider (ValueObject& valobj, Stream& st
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
uint32_t ptr_size = process_sp->GetAddressByteSize();
@@ -659,44 +650,48 @@ lldb_private::formatters::NSDateSummaryProvider (ValueObject& valobj, Stream& st
uint64_t date_value_bits = 0;
double date_value = 0.0;
- const char* class_name = descriptor->GetClassName().GetCString();
+ ConstString class_name = descriptor->GetClassName();
- if (!class_name || !*class_name)
+ static const ConstString g_NSDate("NSDate");
+ static const ConstString g___NSDate("__NSDate");
+ static const ConstString g___NSTaggedDate("__NSTaggedDate");
+ static const ConstString g_NSCalendarDate("NSCalendarDate");
+
+ if (class_name.IsEmpty())
return false;
- if (strcmp(class_name,"NSDate") == 0 ||
- strcmp(class_name,"__NSDate") == 0 ||
- strcmp(class_name,"__NSTaggedDate") == 0)
+ if ((class_name == g_NSDate) ||
+ (class_name == g___NSDate) ||
+ (class_name == g___NSTaggedDate))
{
uint64_t info_bits=0,value_bits = 0;
if (descriptor->GetTaggedPointerInfo(&info_bits,&value_bits))
{
date_value_bits = ((value_bits << 8) | (info_bits << 4));
- date_value = *((double*)&date_value_bits);
+ memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
}
else
{
+ llvm::Triple triple(process_sp->GetTarget().GetArchitecture().GetTriple());
+ uint32_t delta = (triple.isWatchOS() && triple.isWatchABI()) ? 8 : ptr_size;
Error error;
- date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+ptr_size, 8, 0, error);
- date_value = *((double*)&date_value_bits);
+ date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+delta, 8, 0, error);
+ memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
if (error.Fail())
return false;
}
}
- else if (!strcmp(class_name,"NSCalendarDate"))
+ else if (class_name == g_NSCalendarDate)
{
Error error;
date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, 8, 0, error);
- date_value = *((double*)&date_value_bits);
+ memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
if (error.Fail())
return false;
}
else
- {
- if (ExtractValueFromObjCExpression(valobj, "NSTimeInterval", "ExtractValueFromObjCExpression", date_value_bits) == false)
- return false;
- date_value = *((double*)&date_value_bits);
- }
+ return false;
+
if (date_value == -63114076800)
{
stream.Printf("0001-12-30 00:00:00 +0000");
@@ -731,7 +726,7 @@ lldb_private::formatters::ObjCClassSummaryProvider (ValueObject& valobj, Stream&
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptorFromISA(valobj.GetValueAsUnsigned(0)));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
ConstString class_name = descriptor->GetClassName();
@@ -750,7 +745,7 @@ class ObjCClassSyntheticChildrenFrontEnd : public SyntheticChildrenFrontEnd
{
public:
ObjCClassSyntheticChildrenFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp.get())
+ SyntheticChildrenFrontEnd(*valobj_sp)
{
}
@@ -808,7 +803,7 @@ lldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& st
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
bool is_64bit = (process_sp->GetAddressByteSize() == 8);
@@ -834,11 +829,20 @@ lldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& st
if (error.Fail())
return false;
}
- else
+ else if (!strcmp(class_name, "_NSInlineData"))
{
- if (!ExtractValueFromObjCExpression(valobj, "int", "length", value))
+ uint32_t offset = (is_64bit ? 8 : 4);
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, 2, 0, error);
+ if (error.Fail())
return false;
}
+ else if (!strcmp(class_name, "_NSZeroData"))
+ {
+ value = 0;
+ }
+ else
+ return false;
stream.Printf("%s%" PRIu64 " byte%s%s",
(needs_at ? "@\"" : ""),
@@ -869,13 +873,19 @@ lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream&
if (!real_guy_sp)
return false;
}
- uint64_t value = real_guy_sp->GetValueAsUnsigned(0);
- if (value == 0)
+ uint8_t value = (real_guy_sp->GetValueAsUnsigned(0) & 0xFF);
+ switch (value)
{
- stream.Printf("NO");
- return true;
+ case 0:
+ stream.Printf("NO");
+ break;
+ case 1:
+ stream.Printf("YES");
+ break;
+ default:
+ stream.Printf("%u",value);
+ break;
}
- stream.Printf("YES");
return true;
}
@@ -932,28 +942,16 @@ lldb_private::formatters::GetOSXEpoch ()
tm_epoch.tm_min = 0;
tm_epoch.tm_mon = 0;
tm_epoch.tm_mday = 1;
- tm_epoch.tm_year = 2001-1900; // for some reason, we need to subtract 1900 from this field. not sure why.
+ tm_epoch.tm_year = 2001-1900;
tm_epoch.tm_isdst = -1;
tm_epoch.tm_gmtoff = 0;
- tm_epoch.tm_zone = NULL;
+ tm_epoch.tm_zone = nullptr;
epoch = timegm(&tm_epoch);
#endif
}
return epoch;
}
-bool
-lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- if (const char* description = valobj.GetObjectDescription())
- {
- stream.Printf("%s", description);
- return true;
- }
- else
- return false;
-}
-
template bool
lldb_private::formatters::NSDataSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&);
diff --git a/source/Plugins/Language/ObjC/Cocoa.h b/source/Plugins/Language/ObjC/Cocoa.h
index 0caacf3453d4..f43b1639cb38 100644
--- a/source/Plugins/Language/ObjC/Cocoa.h
+++ b/source/Plugins/Language/ObjC/Cocoa.h
@@ -13,6 +13,7 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
namespace lldb_private {
@@ -78,9 +79,6 @@ namespace lldb_private {
ObjCSELSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&);
bool
- RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
NSError_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
bool
@@ -91,6 +89,16 @@ namespace lldb_private {
SyntheticChildrenFrontEnd*
NSExceptionSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp);
+
+ class NSArray_Additionals
+ {
+ public:
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
+ GetAdditionalSummaries ();
+
+ static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
+ GetAdditionalSynthetics ();
+ };
} // namespace formatters
} // namespace lldb_private
diff --git a/source/Plugins/Language/ObjC/Makefile b/source/Plugins/Language/ObjC/Makefile
deleted file mode 100644
index 58c9e58f2bc6..000000000000
--- a/source/Plugins/Language/ObjC/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Language/ObjC ------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginObjCLanguage
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Language/ObjC/NSArray.cpp b/source/Plugins/Language/ObjC/NSArray.cpp
index ccc82ab95ecc..5de97b6f0257 100644
--- a/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/source/Plugins/Language/ObjC/NSArray.cpp
@@ -35,6 +35,20 @@ using namespace lldb_private::formatters;
namespace lldb_private {
namespace formatters {
+ std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
+ NSArray_Additionals::GetAdditionalSummaries ()
+ {
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
+ return g_map;
+ }
+
+ std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
+ NSArray_Additionals::GetAdditionalSynthetics ()
+ {
+ static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> g_map;
+ return g_map;
+ }
+
class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
{
public:
@@ -73,7 +87,6 @@ namespace lldb_private {
ExecutionContextRef m_exe_ctx_ref;
uint8_t m_ptr_size;
CompilerType m_id_type;
- std::vector<lldb::ValueObjectSP> m_children;
};
class NSArrayMSyntheticFrontEnd_109 : public NSArrayMSyntheticFrontEnd
@@ -103,7 +116,7 @@ namespace lldb_private {
struct DataDescriptor_32
{
uint32_t _used;
- uint32_t _priv1 : 2 ;
+ uint32_t _priv1 : 2;
uint32_t _size : 30;
uint32_t _priv2 : 2;
uint32_t _offset : 30;
@@ -114,7 +127,7 @@ namespace lldb_private {
struct DataDescriptor_64
{
uint64_t _used;
- uint64_t _priv1 : 2 ;
+ uint64_t _priv1 : 2;
uint64_t _size : 62;
uint64_t _priv2 : 2;
uint64_t _offset : 62;
@@ -202,7 +215,6 @@ namespace lldb_private {
uint64_t m_items;
lldb::addr_t m_data_ptr;
CompilerType m_id_type;
- std::vector<lldb::ValueObjectSP> m_children;
};
class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd
@@ -227,14 +239,14 @@ namespace lldb_private {
size_t
GetIndexOfChildWithName(const ConstString &name) override;
};
-
- class NSArrayCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+
+ class NSArray1SyntheticFrontEnd : public SyntheticChildrenFrontEnd
{
public:
- NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSArrayCodeRunningSyntheticFrontEnd() override = default;
-
+ NSArray1SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ ~NSArray1SyntheticFrontEnd() override = default;
+
size_t
CalculateNumChildren() override;
@@ -269,7 +281,7 @@ lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& s
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
uint32_t ptr_size = process_sp->GetAddressByteSize();
@@ -281,30 +293,40 @@ lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& s
uint64_t value = 0;
- const char* class_name = descriptor->GetClassName().GetCString();
+ ConstString class_name(descriptor->GetClassName());
- if (!class_name || !*class_name)
+ static const ConstString g_NSArrayI("__NSArrayI");
+ static const ConstString g_NSArrayM("__NSArrayM");
+ static const ConstString g_NSArray0("__NSArray0");
+ static const ConstString g_NSArray1("__NSSingleObjectArrayI");
+ static const ConstString g_NSArrayCF("__NSCFArray");
+
+ if (class_name.IsEmpty())
return false;
- if (!strcmp(class_name,"__NSArrayI"))
+ if (class_name == g_NSArrayI)
{
Error error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
if (error.Fail())
return false;
}
- else if (!strcmp(class_name,"__NSArrayM"))
+ else if (class_name == g_NSArrayM)
{
Error error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
if (error.Fail())
return false;
}
- else if (!strcmp(class_name,"__NSArray0"))
+ else if (class_name == g_NSArray0)
{
value = 0;
}
- else if (!strcmp(class_name,"__NSCFArray"))
+ else if (class_name == g_NSArray1)
+ {
+ value = 1;
+ }
+ else if (class_name == g_NSArrayCF)
{
Error error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + 2 * ptr_size, ptr_size, 0, error);
@@ -313,7 +335,11 @@ lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& s
}
else
{
- if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
+ auto& map(NSArray_Additionals::GetAdditionalSummaries());
+ auto iter = map.find(class_name), end = map.end();
+ if (iter != end)
+ return iter->second(valobj, stream, options);
+ else
return false;
}
@@ -340,8 +366,7 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (
SyntheticChildrenFrontEnd(*valobj_sp),
m_exe_ctx_ref(),
m_ptr_size(8),
-m_id_type(),
-m_children()
+m_id_type()
{
if (valobj_sp)
{
@@ -354,16 +379,16 @@ m_children()
}
lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::NSArrayMSyntheticFrontEnd_109 (lldb::ValueObjectSP valobj_sp) :
-NSArrayMSyntheticFrontEnd(valobj_sp),
-m_data_32(NULL),
-m_data_64(NULL)
+ NSArrayMSyntheticFrontEnd(valobj_sp),
+ m_data_32(nullptr),
+ m_data_64(nullptr)
{
}
lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::NSArrayMSyntheticFrontEnd_1010 (lldb::ValueObjectSP valobj_sp) :
-NSArrayMSyntheticFrontEnd(valobj_sp),
-m_data_32(NULL),
-m_data_64(NULL)
+ NSArrayMSyntheticFrontEnd(valobj_sp),
+ m_data_32(nullptr),
+ m_data_64(nullptr)
{
}
@@ -386,24 +411,21 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex (size_t idx
object_at_idx += (pyhs_idx * m_ptr_size);
StreamString idx_name;
idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- lldb::ValueObjectSP retval_sp = CreateValueObjectFromAddress(idx_name.GetData(),
- object_at_idx,
- m_exe_ctx_ref,
- m_id_type);
- m_children.push_back(retval_sp);
- return retval_sp;
+ return CreateValueObjectFromAddress(idx_name.GetData(),
+ object_at_idx,
+ m_exe_ctx_ref,
+ m_id_type);
}
bool
lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::Update()
{
- m_children.clear();
ValueObjectSP valobj_sp = m_backend.GetSP();
m_ptr_size = 0;
delete m_data_32;
- m_data_32 = NULL;
+ m_data_32 = nullptr;
delete m_data_64;
- m_data_64 = NULL;
+ m_data_64 = nullptr;
if (!valobj_sp)
return false;
m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
@@ -432,13 +454,12 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::Update()
bool
lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::Update()
{
- m_children.clear();
ValueObjectSP valobj_sp = m_backend.GetSP();
m_ptr_size = 0;
delete m_data_32;
- m_data_32 = NULL;
+ m_data_32 = nullptr;
delete m_data_64;
- m_data_64 = NULL;
+ m_data_64 = nullptr;
if (!valobj_sp)
return false;
m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
@@ -483,9 +504,9 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName (co
lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::~NSArrayMSyntheticFrontEnd_109()
{
delete m_data_32;
- m_data_32 = NULL;
+ m_data_32 = nullptr;
delete m_data_64;
- m_data_64 = NULL;
+ m_data_64 = nullptr;
}
lldb::addr_t
@@ -527,9 +548,9 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetSize ()
lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::~NSArrayMSyntheticFrontEnd_1010()
{
delete m_data_32;
- m_data_32 = NULL;
+ m_data_32 = nullptr;
delete m_data_64;
- m_data_64 = NULL;
+ m_data_64 = nullptr;
}
lldb::addr_t
@@ -569,11 +590,11 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetSize ()
}
lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd (*valobj_sp.get()),
-m_exe_ctx_ref (),
-m_ptr_size (8),
-m_items (0),
-m_data_ptr (0)
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_exe_ctx_ref(),
+ m_ptr_size(8),
+ m_items(0),
+ m_data_ptr(0)
{
if (valobj_sp)
{
@@ -609,7 +630,6 @@ lldb_private::formatters::NSArrayISyntheticFrontEnd::Update()
m_ptr_size = 0;
m_items = 0;
m_data_ptr = 0;
- m_children.clear();
ValueObjectSP valobj_sp = m_backend.GetSP();
if (!valobj_sp)
return false;
@@ -649,16 +669,14 @@ lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex (size_t idx
return lldb::ValueObjectSP();
StreamString idx_name;
idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- lldb::ValueObjectSP retval_sp = CreateValueObjectFromAddress(idx_name.GetData(),
- object_at_idx,
- m_exe_ctx_ref,
- m_id_type);
- m_children.push_back(retval_sp);
- return retval_sp;
+ return CreateValueObjectFromAddress(idx_name.GetData(),
+ object_at_idx,
+ m_exe_ctx_ref,
+ m_id_type);
}
lldb_private::formatters::NSArray0SyntheticFrontEnd::NSArray0SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd (*valobj_sp.get())
+ SyntheticChildrenFrontEnd(*valobj_sp)
{
}
@@ -692,17 +710,64 @@ lldb_private::formatters::NSArray0SyntheticFrontEnd::GetChildAtIndex (size_t idx
return lldb::ValueObjectSP();
}
-SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+lldb_private::formatters::NSArray1SyntheticFrontEnd::NSArray1SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd (*valobj_sp.get())
+{
+}
+
+size_t
+lldb_private::formatters::NSArray1SyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ static const ConstString g_zero("[0]");
+
+ if (name == g_zero)
+ return 0;
+
+ return UINT32_MAX;
+}
+
+size_t
+lldb_private::formatters::NSArray1SyntheticFrontEnd::CalculateNumChildren ()
+{
+ return 1;
+}
+
+bool
+lldb_private::formatters::NSArray1SyntheticFrontEnd::Update()
+{
+ return false;
+}
+
+bool
+lldb_private::formatters::NSArray1SyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSArray1SyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ static const ConstString g_zero("[0]");
+
+ if (idx == 0)
+ {
+ CompilerType id_type(m_backend.GetTargetSP()->GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeObjCID));
+ return m_backend.GetSyntheticChildAtOffset(m_backend.GetProcessSP()->GetAddressByteSize(), id_type, true, g_zero);
+ }
+ return lldb::ValueObjectSP();
+}
+
+SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCreator (CXXSyntheticChildren* synth, lldb::ValueObjectSP valobj_sp)
{
if (!valobj_sp)
return nullptr;
lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
if (!process_sp)
- return NULL;
+ return nullptr;
AppleObjCRuntime *runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(process_sp->GetObjCLanguageRuntime());
if (!runtime)
- return NULL;
+ return nullptr;
CompilerType valobj_type(valobj_sp->GetCompilerType());
Flags flags(valobj_type.GetTypeInfo());
@@ -712,28 +777,37 @@ SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCre
Error error;
valobj_sp = valobj_sp->AddressOf(error);
if (error.Fail() || !valobj_sp)
- return NULL;
+ return nullptr;
}
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp));
- if (!descriptor.get() || !descriptor->IsValid())
- return NULL;
+ if (!descriptor || !descriptor->IsValid())
+ return nullptr;
- const char* class_name = descriptor->GetClassName().GetCString();
+ ConstString class_name(descriptor->GetClassName());
- if (!class_name || !*class_name)
- return NULL;
+ static const ConstString g_NSArrayI("__NSArrayI");
+ static const ConstString g_NSArrayM("__NSArrayM");
+ static const ConstString g_NSArray0("__NSArray0");
+ static const ConstString g_NSArray1("__NSSingleObjectArrayI");
+
+ if (class_name.IsEmpty())
+ return nullptr;
- if (!strcmp(class_name,"__NSArrayI"))
+ if (class_name == g_NSArrayI)
{
return (new NSArrayISyntheticFrontEnd(valobj_sp));
}
- else if (!strcmp(class_name,"__NSArray0"))
+ else if (class_name == g_NSArray0)
{
return (new NSArray0SyntheticFrontEnd(valobj_sp));
}
- else if (!strcmp(class_name,"__NSArrayM"))
+ else if (class_name == g_NSArray1)
+ {
+ return (new NSArray1SyntheticFrontEnd(valobj_sp));
+ }
+ else if (class_name == g_NSArrayM)
{
if (runtime->GetFoundationVersion() >= 1100)
return (new NSArrayMSyntheticFrontEnd_1010(valobj_sp));
@@ -742,51 +816,11 @@ SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCre
}
else
{
- return (new NSArrayCodeRunningSyntheticFrontEnd(valobj_sp));
- }
-}
-
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get())
-{}
-
-size_t
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
-{
- uint64_t count = 0;
- if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
- return count;
- return 0;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- lldb::ValueObjectSP valobj_sp = CallSelectorOnObject(m_backend,"id","objectAtIndex:",idx);
- if (valobj_sp)
- {
- valobj_sp->SetPreferredDisplayLanguage(m_backend.GetPreferredDisplayLanguage());
- valobj_sp->SetName(ConstString(idx_name.GetData()));
+ auto& map(NSArray_Additionals::GetAdditionalSynthetics());
+ auto iter = map.find(class_name), end = map.end();
+ if (iter != end)
+ return iter->second(synth, valobj_sp);
}
- return valobj_sp;
-}
-
-bool
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::Update()
-{
- return false;
-}
-
-bool
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
-}
-
-size_t
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- return 0;
+
+ return nullptr;
}
diff --git a/source/Plugins/Language/ObjC/NSDictionary.cpp b/source/Plugins/Language/ObjC/NSDictionary.cpp
index e4a7425329f5..cdebd6b3c23c 100644
--- a/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -63,7 +63,7 @@ GetLLDBNSPairType (TargetSP target_sp)
if (!compiler_type)
{
- compiler_type = target_ast_context->CreateRecordType(NULL, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC);
+ compiler_type = target_ast_context->CreateRecordType(nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC);
if (compiler_type)
{
@@ -131,6 +131,32 @@ namespace lldb_private {
CompilerType m_pair_type;
std::vector<DictionaryItemDescriptor> m_children;
};
+
+ class NSDictionary1SyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ NSDictionary1SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ ~NSDictionary1SyntheticFrontEnd() override = default;
+
+ size_t
+ CalculateNumChildren() override;
+
+ lldb::ValueObjectSP
+ GetChildAtIndex(size_t idx) override;
+
+ bool
+ Update() override;
+
+ bool
+ MightHaveChildren() override;
+
+ size_t
+ GetIndexOfChildWithName(const ConstString &name) override;
+
+ private:
+ ValueObjectSP m_pair;
+ };
class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
{
@@ -190,29 +216,6 @@ namespace lldb_private {
CompilerType m_pair_type;
std::vector<DictionaryItemDescriptor> m_children;
};
-
- class NSDictionaryCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSDictionaryCodeRunningSyntheticFrontEnd() override = default;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
- };
} // namespace formatters
} // namespace lldb_private
@@ -232,7 +235,7 @@ lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stre
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
uint32_t ptr_size = process_sp->GetAddressByteSize();
@@ -245,13 +248,16 @@ lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stre
uint64_t value = 0;
- ConstString class_name_cs = descriptor->GetClassName();
- const char* class_name = class_name_cs.GetCString();
+ ConstString class_name(descriptor->GetClassName());
+
+ static const ConstString g_DictionaryI("__NSDictionaryI");
+ static const ConstString g_DictionaryM("__NSDictionaryM");
+ static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
- if (!class_name || !*class_name)
+ if (class_name.IsEmpty())
return false;
-
- if (!strcmp(class_name,"__NSDictionaryI"))
+
+ if (class_name == g_DictionaryI)
{
Error error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
@@ -259,7 +265,7 @@ lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stre
return false;
value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
}
- else if (!strcmp(class_name,"__NSDictionaryM"))
+ else if (class_name == g_DictionaryM)
{
Error error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
@@ -267,6 +273,10 @@ lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stre
return false;
value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
}
+ else if (class_name == g_Dictionary1)
+ {
+ value = 1;
+ }
/*else if (!strcmp(class_name,"__NSCFDictionary"))
{
Error error;
@@ -279,10 +289,10 @@ lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stre
else
{
auto& map(NSDictionary_Additionals::GetAdditionalSummaries());
- auto iter = map.find(class_name_cs), end = map.end();
+ auto iter = map.find(class_name), end = map.end();
if (iter != end)
return iter->second(valobj, stream, options);
- if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
+ else
return false;
}
@@ -309,10 +319,10 @@ SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontE
{
lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
if (!process_sp)
- return NULL;
+ return nullptr;
ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
if (!runtime)
- return NULL;
+ return nullptr;
CompilerType valobj_type(valobj_sp->GetCompilerType());
Flags flags(valobj_type.GetTypeInfo());
@@ -322,111 +332,63 @@ SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontE
Error error;
valobj_sp = valobj_sp->AddressOf(error);
if (error.Fail() || !valobj_sp)
- return NULL;
+ return nullptr;
}
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp));
- if (!descriptor.get() || !descriptor->IsValid())
- return NULL;
+ if (!descriptor || !descriptor->IsValid())
+ return nullptr;
- ConstString class_name_cs = descriptor->GetClassName();
- const char* class_name = class_name_cs.GetCString();
+ ConstString class_name(descriptor->GetClassName());
- if (!class_name || !*class_name)
- return NULL;
+ static const ConstString g_DictionaryI("__NSDictionaryI");
+ static const ConstString g_DictionaryM("__NSDictionaryM");
+ static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
- if (!strcmp(class_name,"__NSDictionaryI"))
+ if (class_name.IsEmpty())
+ return nullptr;
+
+ if (class_name == g_DictionaryI)
{
return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
}
- else if (!strcmp(class_name,"__NSDictionaryM"))
+ else if (class_name == g_DictionaryM)
{
return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
}
+ else if (class_name == g_Dictionary1)
+ {
+ return (new NSDictionary1SyntheticFrontEnd(valobj_sp));
+ }
else
{
auto& map(NSDictionary_Additionals::GetAdditionalSynthetics());
- auto iter = map.find(class_name_cs), end = map.end();
+ auto iter = map.find(class_name), end = map.end();
if (iter != end)
return iter->second(synth, valobj_sp);
- return (new NSDictionaryCodeRunningSyntheticFrontEnd(valobj_sp));
}
-}
-
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get())
-{}
-
-size_t
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
-{
- uint64_t count = 0;
- if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
- return count;
- return 0;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- StreamString key_fetcher_expr;
- key_fetcher_expr.Printf("(id)[(NSArray*)[(id)0x%" PRIx64 " allKeys] objectAtIndex:%" PRIu64 "]", m_backend.GetPointerValue(), (uint64_t)idx);
- StreamString value_fetcher_expr;
- value_fetcher_expr.Printf("(id)[(id)0x%" PRIx64 " objectForKey:(%s)]",m_backend.GetPointerValue(),key_fetcher_expr.GetData());
- StreamString object_fetcher_expr;
- object_fetcher_expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = %s; _lldb_valgen_item.value = %s; _lldb_valgen_item;",key_fetcher_expr.GetData(),value_fetcher_expr.GetData());
- lldb::ValueObjectSP child_sp;
- EvaluateExpressionOptions options;
- options.SetKeepInMemory(true);
- options.SetLanguage(lldb::eLanguageTypeObjC_plus_plus);
- options.SetResultIsInternal(true);
- m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(),
- GetViableFrame(m_backend.GetTargetSP().get()),
- child_sp,
- options);
- if (child_sp)
- child_sp->SetName(ConstString(idx_name.GetData()));
- return child_sp;
-}
-
-bool
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::Update()
-{
- return false;
-}
-
-bool
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
-}
-
-size_t
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- return 0;
+
+ return nullptr;
}
lldb_private::formatters::NSDictionaryISyntheticFrontEnd::NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_exe_ctx_ref(),
-m_ptr_size(8),
-m_order(lldb::eByteOrderInvalid),
-m_data_32(NULL),
-m_data_64(NULL),
-m_pair_type()
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_exe_ctx_ref(),
+ m_ptr_size(8),
+ m_order(lldb::eByteOrderInvalid),
+ m_data_32(nullptr),
+ m_data_64(nullptr),
+ m_pair_type()
{
}
lldb_private::formatters::NSDictionaryISyntheticFrontEnd::~NSDictionaryISyntheticFrontEnd ()
{
delete m_data_32;
- m_data_32 = NULL;
+ m_data_32 = nullptr;
delete m_data_64;
- m_data_64 = NULL;
+ m_data_64 = nullptr;
}
size_t
@@ -452,9 +414,9 @@ lldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update()
{
m_children.clear();
delete m_data_32;
- m_data_32 = NULL;
+ m_data_32 = nullptr;
delete m_data_64;
- m_data_64 = NULL;
+ m_data_64 = nullptr;
m_ptr_size = 0;
ValueObjectSP valobj_sp = m_backend.GetSP();
if (!valobj_sp)
@@ -575,23 +537,113 @@ lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (size_
return dict_item.valobj_sp;
}
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+lldb_private::formatters::NSDictionary1SyntheticFrontEnd::NSDictionary1SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_exe_ctx_ref(),
-m_ptr_size(8),
-m_order(lldb::eByteOrderInvalid),
-m_data_32(NULL),
-m_data_64(NULL),
-m_pair_type()
+m_pair(nullptr)
+{
+}
+
+size_t
+lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ static const ConstString g_zero("[0]");
+
+ if (name == g_zero)
+ return 0;
+
+ return UINT32_MAX;
+}
+
+size_t
+lldb_private::formatters::NSDictionary1SyntheticFrontEnd::CalculateNumChildren ()
+{
+ return 1;
+}
+
+bool
+lldb_private::formatters::NSDictionary1SyntheticFrontEnd::Update()
+{
+ m_pair.reset();
+ return false;
+}
+
+bool
+lldb_private::formatters::NSDictionary1SyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (idx != 0)
+ return lldb::ValueObjectSP();
+
+ if (m_pair.get())
+ return m_pair;
+
+ auto process_sp(m_backend.GetProcessSP());
+ if (!process_sp)
+ return nullptr;
+
+ auto ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t key_ptr = m_backend.GetValueAsUnsigned(LLDB_INVALID_ADDRESS) + ptr_size;
+ lldb::addr_t value_ptr = key_ptr + ptr_size;
+
+ Error error;
+
+ lldb::addr_t value_at_idx = process_sp->ReadPointerFromMemory(key_ptr, error);
+ if (error.Fail())
+ return nullptr;
+ lldb::addr_t key_at_idx = process_sp->ReadPointerFromMemory(value_ptr, error);
+ if (error.Fail())
+ return nullptr;
+
+ auto pair_type = GetLLDBNSPairType(process_sp->GetTarget().shared_from_this());
+
+ DataBufferSP buffer_sp(new DataBufferHeap(2*ptr_size,0));
+
+ if (ptr_size == 8)
+ {
+ uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
+ *data_ptr = key_at_idx;
+ *(data_ptr+1) = value_at_idx;
+ }
+ else
+ {
+ uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
+ *data_ptr = key_ptr;
+ *(data_ptr+1) = value_ptr;
+ }
+
+ DataExtractor data(buffer_sp, process_sp->GetByteOrder(), ptr_size);
+ m_pair = CreateValueObjectFromData("[0]",
+ data,
+ m_backend.GetExecutionContextRef(),
+ pair_type);
+
+
+ return m_pair;
+}
+
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_exe_ctx_ref(),
+ m_ptr_size(8),
+ m_order(lldb::eByteOrderInvalid),
+ m_data_32(nullptr),
+ m_data_64(nullptr),
+ m_pair_type()
{
}
lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd ()
{
delete m_data_32;
- m_data_32 = NULL;
+ m_data_32 = nullptr;
delete m_data_64;
- m_data_64 = NULL;
+ m_data_64 = nullptr;
}
size_t
@@ -619,9 +671,9 @@ lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update()
ValueObjectSP valobj_sp = m_backend.GetSP();
m_ptr_size = 0;
delete m_data_32;
- m_data_32 = NULL;
+ m_data_32 = nullptr;
delete m_data_64;
- m_data_64 = NULL;
+ m_data_64 = nullptr;
if (!valobj_sp)
return false;
m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
diff --git a/source/Plugins/Language/ObjC/NSError.cpp b/source/Plugins/Language/ObjC/NSError.cpp
index c627cd031926..4bfb024206d3 100644
--- a/source/Plugins/Language/ObjC/NSError.cpp
+++ b/source/Plugins/Language/ObjC/NSError.cpp
@@ -34,27 +34,49 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-bool
-lldb_private::formatters::NSError_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
+static lldb::addr_t
+DerefToNSErrorPointer (ValueObject& valobj)
{
- ProcessSP process_sp(valobj.GetProcessSP());
- if (!process_sp)
- return false;
-
- lldb::addr_t ptr_value = LLDB_INVALID_ADDRESS;
-
CompilerType valobj_type(valobj.GetCompilerType());
Flags type_flags(valobj_type.GetTypeInfo());
if (type_flags.AllClear(eTypeHasValue))
{
if (valobj.IsBaseClass() && valobj.GetParent())
- ptr_value = valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ return valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
}
else
- ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ {
+ lldb::addr_t ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ if (type_flags.AllSet(eTypeIsPointer))
+ {
+ CompilerType pointee_type(valobj_type.GetPointeeType());
+ Flags pointee_flags(pointee_type.GetTypeInfo());
+ if (pointee_flags.AllSet(eTypeIsPointer))
+ {
+ if (ProcessSP process_sp = valobj.GetProcessSP())
+ {
+ Error error;
+ ptr_value = process_sp->ReadPointerFromMemory(ptr_value, error);
+ }
+ }
+ }
+ return ptr_value;
+ }
+
+ return LLDB_INVALID_ADDRESS;
+}
+bool
+lldb_private::formatters::NSError_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
+{
+ ProcessSP process_sp(valobj.GetProcessSP());
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t ptr_value = DerefToNSErrorPointer(valobj);
if (ptr_value == LLDB_INVALID_ADDRESS)
return false;
+
size_t ptr_size = process_sp->GetAddressByteSize();
lldb::addr_t code_location = ptr_value + 2 * ptr_size;
lldb::addr_t domain_location = ptr_value + 3 * ptr_size;
@@ -135,18 +157,7 @@ public:
if (!process_sp)
return false;
- lldb::addr_t userinfo_location = LLDB_INVALID_ADDRESS;
-
- CompilerType valobj_type(m_backend.GetCompilerType());
- Flags type_flags(valobj_type.GetTypeInfo());
- if (type_flags.AllClear(eTypeHasValue))
- {
- if (m_backend.IsBaseClass() && m_backend.GetParent())
- userinfo_location = m_backend.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- }
- else
- userinfo_location = m_backend.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-
+ lldb::addr_t userinfo_location = DerefToNSErrorPointer(m_backend);
if (userinfo_location == LLDB_INVALID_ADDRESS)
return false;
@@ -158,10 +169,10 @@ public:
if (userinfo == LLDB_INVALID_ADDRESS || error.Fail())
return false;
InferiorSizedWord isw(userinfo,*process_sp);
- m_child_sp = ValueObject::CreateValueObjectFromData("_userInfo",
- isw.GetAsData(process_sp->GetByteOrder()),
- m_backend.GetExecutionContextRef(),
- process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeObjCID));
+ m_child_sp = CreateValueObjectFromData("_userInfo",
+ isw.GetAsData(process_sp->GetByteOrder()),
+ m_backend.GetExecutionContextRef(),
+ process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeObjCID));
return false;
}
diff --git a/source/Plugins/Language/ObjC/NSException.cpp b/source/Plugins/Language/ObjC/NSException.cpp
index e58223a4d461..f70e7c7356e1 100644
--- a/source/Plugins/Language/ObjC/NSException.cpp
+++ b/source/Plugins/Language/ObjC/NSException.cpp
@@ -157,10 +157,10 @@ public:
if (userinfo == LLDB_INVALID_ADDRESS || error.Fail())
return false;
InferiorSizedWord isw(userinfo,*process_sp);
- m_child_sp = ValueObject::CreateValueObjectFromData("userInfo",
- isw.GetAsData(process_sp->GetByteOrder()),
- m_backend.GetExecutionContextRef(),
- process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeObjCID));
+ m_child_sp = CreateValueObjectFromData("userInfo",
+ isw.GetAsData(process_sp->GetByteOrder()),
+ m_backend.GetExecutionContextRef(),
+ process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeObjCID));
return false;
}
diff --git a/source/Plugins/Language/ObjC/NSIndexPath.cpp b/source/Plugins/Language/ObjC/NSIndexPath.cpp
index 245f6da80c7f..0c8a54d76df1 100644
--- a/source/Plugins/Language/ObjC/NSIndexPath.cpp
+++ b/source/Plugins/Language/ObjC/NSIndexPath.cpp
@@ -31,6 +31,8 @@ class NSIndexPathSyntheticFrontEnd : public SyntheticChildrenFrontEnd
public:
NSIndexPathSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
SyntheticChildrenFrontEnd (*valobj_sp.get()),
+ m_descriptor_sp(nullptr),
+ m_impl(),
m_ptr_size(0),
m_uint_star_type()
{
@@ -169,9 +171,8 @@ protected:
Invalid
};
- struct Impl {
- Mode m_mode;
-
+ struct Impl
+ {
size_t
GetNumIndexes ()
{
@@ -200,48 +201,52 @@ protected:
return m_outsourced.GetIndexAtIndex (idx);
}
}
-
- struct InlinedIndexes {
+
+ struct InlinedIndexes
+ {
public:
- void SetIndexes(uint64_t value, Process& p)
- {
- m_indexes = value;
- _lengthForInlinePayload(p.GetAddressByteSize());
- m_process = &p;
- }
-
- size_t
- GetNumIndexes ()
- {
- return m_count;
- }
-
- lldb::ValueObjectSP
- GetIndexAtIndex (size_t idx, const CompilerType& desired_type)
- {
- std::pair<uint64_t, bool> value(_indexAtPositionForInlinePayload(idx));
- if (!value.second)
- return nullptr;
-
- Value v;
- if (m_ptr_size == 8)
- {
- Scalar scalar( (unsigned long long)value.first );
- v = Value(scalar);
- }
- else
- {
- Scalar scalar( (unsigned int)value.first );
- v = Value(scalar);
- }
-
- v.SetCompilerType(desired_type);
-
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ void SetIndexes(uint64_t value, Process& p)
+ {
+ m_indexes = value;
+ _lengthForInlinePayload(p.GetAddressByteSize());
+ m_process = &p;
+ }
+
+ size_t
+ GetNumIndexes ()
+ {
+ return m_count;
+ }
+
+ lldb::ValueObjectSP
+ GetIndexAtIndex (size_t idx, const CompilerType& desired_type)
+ {
+ if (!m_process)
+ return nullptr;
- return ValueObjectConstResult::Create(m_process, v, ConstString(idx_name.GetData()));
- }
+ std::pair<uint64_t, bool> value(_indexAtPositionForInlinePayload(idx));
+ if (!value.second)
+ return nullptr;
+
+ Value v;
+ if (m_ptr_size == 8)
+ {
+ Scalar scalar( (unsigned long long)value.first );
+ v = Value(scalar);
+ }
+ else
+ {
+ Scalar scalar( (unsigned int)value.first );
+ v = Value(scalar);
+ }
+
+ v.SetCompilerType(desired_type);
+
+ StreamString idx_name;
+ idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+
+ return ValueObjectConstResult::Create(m_process, v, ConstString(idx_name.GetData()));
+ }
void
Clear ()
@@ -251,53 +256,60 @@ protected:
m_ptr_size = 0;
m_process = nullptr;
}
-
+
+ InlinedIndexes () :
+ m_indexes(0),
+ m_count(0),
+ m_ptr_size(0),
+ m_process(nullptr)
+ {
+ }
+
private:
- uint64_t m_indexes;
- size_t m_count;
- uint32_t m_ptr_size;
- Process *m_process;
-
- // cfr. Foundation for the details of this code
- size_t _lengthForInlinePayload(uint32_t ptr_size) {
- m_ptr_size = ptr_size;
- if (m_ptr_size == 8)
- m_count = ((m_indexes >> 3) & 0x7);
- else
- m_count = ((m_indexes >> 3) & 0x3);
- return m_count;
- }
-
- std::pair<uint64_t, bool>
- _indexAtPositionForInlinePayload(size_t pos)
- {
- if (m_ptr_size == 8)
- {
- switch (pos) {
- case 5: return {((m_indexes >> 51) & 0x1ff),true};
- case 4: return {((m_indexes >> 42) & 0x1ff),true};
- case 3: return {((m_indexes >> 33) & 0x1ff),true};
- case 2: return {((m_indexes >> 24) & 0x1ff),true};
- case 1: return {((m_indexes >> 15) & 0x1ff),true};
- case 0: return {((m_indexes >> 6) & 0x1ff),true};
+ uint64_t m_indexes;
+ size_t m_count;
+ uint32_t m_ptr_size;
+ Process *m_process;
+
+ // cfr. Foundation for the details of this code
+ size_t _lengthForInlinePayload(uint32_t ptr_size) {
+ m_ptr_size = ptr_size;
+ if (m_ptr_size == 8)
+ m_count = ((m_indexes >> 3) & 0x7);
+ else
+ m_count = ((m_indexes >> 3) & 0x3);
+ return m_count;
+ }
+
+ std::pair<uint64_t, bool>
+ _indexAtPositionForInlinePayload(size_t pos)
+ {
+ if (m_ptr_size == 8)
+ {
+ switch (pos) {
+ case 5: return {((m_indexes >> 51) & 0x1ff),true};
+ case 4: return {((m_indexes >> 42) & 0x1ff),true};
+ case 3: return {((m_indexes >> 33) & 0x1ff),true};
+ case 2: return {((m_indexes >> 24) & 0x1ff),true};
+ case 1: return {((m_indexes >> 15) & 0x1ff),true};
+ case 0: return {((m_indexes >> 6) & 0x1ff),true};
+ }
}
- }
- else
- {
- switch (pos) {
- case 2: return {((m_indexes >> 23) & 0x1ff),true};
- case 1: return {((m_indexes >> 14) & 0x1ff),true};
- case 0: return {((m_indexes >> 5) & 0x1ff),true};
- }
- }
- return {0,false};
- }
-
+ else
+ {
+ switch (pos) {
+ case 2: return {((m_indexes >> 23) & 0x1ff),true};
+ case 1: return {((m_indexes >> 14) & 0x1ff),true};
+ case 0: return {((m_indexes >> 5) & 0x1ff),true};
+ }
+ }
+ return {0,false};
+ }
+
};
- struct OutsourcedIndexes {
- ValueObject *m_indexes;
- size_t m_count;
-
+
+ struct OutsourcedIndexes
+ {
lldb::ValueObjectSP
GetIndexAtIndex (size_t idx)
{
@@ -315,9 +327,19 @@ protected:
m_indexes = nullptr;
m_count = 0;
}
+
+ OutsourcedIndexes () :
+ m_indexes(nullptr),
+ m_count(0)
+ {
+ }
+
+ ValueObject *m_indexes;
+ size_t m_count;
};
-
- union {
+
+ union
+ {
struct InlinedIndexes m_inlined;
struct OutsourcedIndexes m_outsourced;
};
@@ -329,6 +351,13 @@ protected:
m_inlined.Clear();
m_outsourced.Clear();
}
+
+ Impl() :
+ m_mode(Mode::Invalid)
+ {
+ }
+
+ Mode m_mode;
} m_impl;
uint32_t m_ptr_size;
diff --git a/source/Plugins/Language/ObjC/NSSet.cpp b/source/Plugins/Language/ObjC/NSSet.cpp
index 93115957e329..315771045ba6 100644
--- a/source/Plugins/Language/ObjC/NSSet.cpp
+++ b/source/Plugins/Language/ObjC/NSSet.cpp
@@ -94,33 +94,6 @@ namespace lldb_private {
std::vector<SetItemDescriptor> m_children;
};
- class NSOrderedSetSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSOrderedSetSyntheticFrontEnd() override = default;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- private:
- uint32_t m_count;
- std::map<uint32_t,lldb::ValueObjectSP> m_children;
- };
-
class NSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
{
public:
@@ -215,7 +188,7 @@ lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& str
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
- if (!descriptor.get() || !descriptor->IsValid())
+ if (!descriptor || !descriptor->IsValid())
return false;
uint32_t ptr_size = process_sp->GetAddressByteSize();
@@ -277,7 +250,7 @@ lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& str
auto iter = map.find(class_name_cs), end = map.end();
if (iter != end)
return iter->second(valobj, stream, options);
- if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
+ else
return false;
}
@@ -304,10 +277,10 @@ SyntheticChildrenFrontEnd* lldb_private::formatters::NSSetSyntheticFrontEndCreat
{
lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
if (!process_sp)
- return NULL;
+ return nullptr;
ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
if (!runtime)
- return NULL;
+ return nullptr;
CompilerType valobj_type(valobj_sp->GetCompilerType());
Flags flags(valobj_type.GetTypeInfo());
@@ -317,19 +290,19 @@ SyntheticChildrenFrontEnd* lldb_private::formatters::NSSetSyntheticFrontEndCreat
Error error;
valobj_sp = valobj_sp->AddressOf(error);
if (error.Fail() || !valobj_sp)
- return NULL;
+ return nullptr;
}
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp));
- if (!descriptor.get() || !descriptor->IsValid())
- return NULL;
+ if (!descriptor || !descriptor->IsValid())
+ return nullptr;
ConstString class_name_cs = descriptor->GetClassName();
const char* class_name = class_name_cs.GetCString();
if (!class_name || !*class_name)
- return NULL;
+ return nullptr;
if (!strcmp(class_name,"__NSSetI"))
{
@@ -339,26 +312,22 @@ SyntheticChildrenFrontEnd* lldb_private::formatters::NSSetSyntheticFrontEndCreat
{
return (new NSSetMSyntheticFrontEnd(valobj_sp));
}
- else if ((!strcmp(class_name,"__NSOrderedSetI")) || (!strcmp(class_name,"__NSOrderedSetM")))
- {
- return new NSOrderedSetSyntheticFrontEnd(valobj_sp); // this runs code
- }
else
{
auto& map(NSSet_Additionals::GetAdditionalSynthetics());
auto iter = map.find(class_name_cs), end = map.end();
if (iter != end)
return iter->second(synth, valobj_sp);
- return /*(new NSSetCodeRunningSyntheticFrontEnd(valobj_sp))*/ NULL;
+ return nullptr;
}
}
lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_exe_ctx_ref(),
-m_ptr_size(8),
-m_data_32(NULL),
-m_data_64(NULL)
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_exe_ctx_ref(),
+ m_ptr_size(8),
+ m_data_32(nullptr),
+ m_data_64(nullptr)
{
if (valobj_sp)
Update();
@@ -367,9 +336,9 @@ m_data_64(NULL)
lldb_private::formatters::NSSetISyntheticFrontEnd::~NSSetISyntheticFrontEnd ()
{
delete m_data_32;
- m_data_32 = NULL;
+ m_data_32 = nullptr;
delete m_data_64;
- m_data_64 = NULL;
+ m_data_64 = nullptr;
}
size_t
@@ -395,9 +364,9 @@ lldb_private::formatters::NSSetISyntheticFrontEnd::Update()
{
m_children.clear();
delete m_data_32;
- m_data_32 = NULL;
+ m_data_32 = nullptr;
delete m_data_64;
- m_data_64 = NULL;
+ m_data_64 = nullptr;
m_ptr_size = 0;
ValueObjectSP valobj_sp = m_backend.GetSP();
if (!valobj_sp)
@@ -521,11 +490,11 @@ lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex (size_t idx)
}
lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_exe_ctx_ref(),
-m_ptr_size(8),
-m_data_32(NULL),
-m_data_64(NULL)
+ SyntheticChildrenFrontEnd(*valobj_sp),
+ m_exe_ctx_ref(),
+ m_ptr_size(8),
+ m_data_32(nullptr),
+ m_data_64(nullptr)
{
if (valobj_sp)
Update ();
@@ -534,9 +503,9 @@ m_data_64(NULL)
lldb_private::formatters::NSSetMSyntheticFrontEnd::~NSSetMSyntheticFrontEnd ()
{
delete m_data_32;
- m_data_32 = NULL;
+ m_data_32 = nullptr;
delete m_data_64;
- m_data_64 = NULL;
+ m_data_64 = nullptr;
}
size_t
@@ -564,9 +533,9 @@ lldb_private::formatters::NSSetMSyntheticFrontEnd::Update()
ValueObjectSP valobj_sp = m_backend.GetSP();
m_ptr_size = 0;
delete m_data_32;
- m_data_32 = NULL;
+ m_data_32 = nullptr;
delete m_data_64;
- m_data_64 = NULL;
+ m_data_64 = nullptr;
if (!valobj_sp)
return false;
if (!valobj_sp)
@@ -688,69 +657,6 @@ lldb_private::formatters::NSSetMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
return set_item.valobj_sp;
}
-lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_count(UINT32_MAX),
-m_children()
-{}
-
-size_t
-lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::CalculateNumChildren ()
-{
- if (m_count != UINT32_MAX)
- return m_count;
- uint64_t count_temp;
- if (ExtractValueFromObjCExpression(m_backend,"unsigned int","count",count_temp))
- return (m_count = count_temp);
- return (m_count = 0);
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- auto iter = m_children.find(idx);
- if (iter == m_children.end())
- {
- lldb::ValueObjectSP retval_sp;
- if (idx <= m_count)
- {
- retval_sp = CallSelectorOnObject(m_backend, "id", "objectAtIndex", idx);
- if (retval_sp)
- {
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- retval_sp->SetName(ConstString(idx_name.GetData()));
- }
- m_children[idx] = retval_sp;
- }
- return retval_sp;
- }
- else
- return iter->second;
-}
-
-bool
-lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::Update()
-{
- return false;
-}
-
-bool
-lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
-}
-
-size_t
-lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
-}
-
template bool
lldb_private::formatters::NSSetSummaryProvider<true> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
diff --git a/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index 91a3a0fb4299..0ecbfd35b1a2 100644
--- a/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -61,6 +61,7 @@ ObjCLanguage::GetPluginNameStatic()
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
+
lldb_private::ConstString
ObjCLanguage::GetPluginName()
{
@@ -76,6 +77,7 @@ ObjCLanguage::GetPluginVersion()
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
+
Language *
ObjCLanguage::CreateInstance (lldb::LanguageType language)
{
@@ -192,7 +194,7 @@ ObjCLanguage::MethodName::GetClassNameWithCategory ()
m_class_category.SetCStringWithLength (class_start, space_pos - class_start);
// If m_class hasn't been filled in and the class with category doesn't
// contain a '(', then we can also fill in the m_class
- if (!m_class && strchr (m_class_category.GetCString(), '(') == NULL)
+ if (!m_class && strchr(m_class_category.GetCString(), '(') == nullptr)
{
m_class = m_class_category;
// No '(' was found in the full name, we can definitively say
@@ -451,6 +453,7 @@ LoadObjCFormatters(TypeCategoryImplSP objc_category_sp)
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArray0"), appkit_flags);
+ AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSSingleObjectArrayI"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
@@ -460,6 +463,7 @@ LoadObjCFormatters(TypeCategoryImplSP objc_category_sp)
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSMutableDictionary"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSCFDictionary"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryI"), appkit_flags);
+ AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSSingleEntryDictionaryI"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryM"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFDictionaryRef"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags);
@@ -487,6 +491,7 @@ LoadObjCFormatters(TypeCategoryImplSP objc_category_sp)
AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayM"), ScriptedSyntheticChildren::Flags());
AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayI"), ScriptedSyntheticChildren::Flags());
AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArray0"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSSingleObjectArrayI"), ScriptedSyntheticChildren::Flags());
AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSArray"), ScriptedSyntheticChildren::Flags());
AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSMutableArray"), ScriptedSyntheticChildren::Flags());
AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSCFArray"), ScriptedSyntheticChildren::Flags());
@@ -495,6 +500,7 @@ LoadObjCFormatters(TypeCategoryImplSP objc_category_sp)
AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryM"), ScriptedSyntheticChildren::Flags());
AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryI"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSSingleEntryDictionaryI"), ScriptedSyntheticChildren::Flags());
AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSCFDictionary"), ScriptedSyntheticChildren::Flags());
AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSDictionary"), ScriptedSyntheticChildren::Flags());
AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSMutableDictionary"), ScriptedSyntheticChildren::Flags());
@@ -532,6 +538,7 @@ LoadObjCFormatters(TypeCategoryImplSP objc_category_sp)
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFConstantString"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFString"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
+ AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSTaggedPointerString"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSAttributedStringSummaryProvider, "NSAttributedString summary provider", ConstString("NSAttributedString"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSMutableAttributedStringSummaryProvider, "NSMutableAttributedString summary provider", ConstString("NSMutableAttributedString"), appkit_flags);
@@ -540,6 +547,7 @@ LoadObjCFormatters(TypeCategoryImplSP objc_category_sp)
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSBundleSummaryProvider, "NSBundle summary provider", ConstString("NSBundle"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSData"), appkit_flags);
+ AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("_NSInlineData"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteMutableData"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSMutableData"), appkit_flags);
@@ -551,10 +559,7 @@ LoadObjCFormatters(TypeCategoryImplSP objc_category_sp)
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, "NSNotification summary provider", ConstString("NSNotification"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, "NSNotification summary provider", ConstString("NSConcreteNotification"), appkit_flags);
-
- AddStringSummary(objc_category_sp, "domain: ${var._domain} - code: ${var._code}", ConstString("NSError"), appkit_flags);
- AddStringSummary(objc_category_sp,"name:${var.name%S} reason:${var.reason%S}",ConstString("NSException"),appkit_flags);
-
+
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
@@ -562,11 +567,6 @@ LoadObjCFormatters(TypeCategoryImplSP objc_category_sp)
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSDecimalNumber summary provider", ConstString("NSDecimalNumber"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSHost summary provider", ConstString("NSHost"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSTask summary provider", ConstString("NSTask"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSValue summary provider", ConstString("NSValue"), appkit_flags);
-
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("NSURL"), appkit_flags);
AddCXXSummary(objc_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("CFURLRef"), appkit_flags);
@@ -732,7 +732,7 @@ ObjCLanguage::GetTypeScavenger ()
ConstString key_cs(key);
if (clang_modules_decl_vendor->FindDecls(key_cs, false, UINT32_MAX, decls) > 0 &&
- decls.size() > 0)
+ !decls.empty())
{
CompilerType module_type = ClangASTContext::GetTypeForDecl(decls.front());
result = true;
diff --git a/source/Plugins/Language/ObjC/ObjCLanguage.h b/source/Plugins/Language/ObjC/ObjCLanguage.h
index e30aa18c0443..b1435d26429a 100644
--- a/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -12,6 +12,7 @@
// C Includes
// C++ Includes
+#include <cstring>
#include <vector>
// Other libraries and framework includes
@@ -187,7 +188,7 @@ public:
if (!name)
return false;
- if (strchr(name, ':') == NULL)
+ if (strchr(name, ':') == nullptr)
return true;
else if (name[strlen(name) - 1] == ':')
return true;
diff --git a/source/Plugins/Language/ObjCPlusPlus/Makefile b/source/Plugins/Language/ObjCPlusPlus/Makefile
deleted file mode 100644
index 74e1a14bcf4d..000000000000
--- a/source/Plugins/Language/ObjCPlusPlus/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Language/ObjCPlusPlus ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginObjCPlusPlusLanguage
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/LanguageRuntime/CMakeLists.txt b/source/Plugins/LanguageRuntime/CMakeLists.txt
index 66b17a4af229..2cf579212ec1 100644
--- a/source/Plugins/LanguageRuntime/CMakeLists.txt
+++ b/source/Plugins/LanguageRuntime/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(CPlusPlus)
add_subdirectory(ObjC)
add_subdirectory(Go)
+add_subdirectory(Java)
add_subdirectory(RenderScript)
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 8e2cfb5570d9..c49feb07200e 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -13,13 +13,18 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/Mangled.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -43,68 +48,26 @@ ItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value)
return in_value.GetCompilerType().IsPossibleDynamicType (NULL, check_cxx, check_objc);
}
-bool
-ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
- lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &dynamic_address,
- Value::ValueType &value_type)
+TypeAndOrName
+ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(ValueObject &in_value, lldb::addr_t original_ptr,
+ lldb::addr_t vtable_load_addr)
{
- // For Itanium, if the type has a vtable pointer in the object, it will be at offset 0
- // in the object. That will point to the "address point" within the vtable (not the beginning of the
- // vtable.) We can then look up the symbol containing this "address point" and that symbol's name
- // demangled will contain the full class name.
- // The second pointer above the "address point" is the "offset_to_top". We'll use that to get the
- // start of the value object which holds the dynamic type.
- //
-
- class_type_or_name.Clear();
- value_type = Value::ValueType::eValueTypeScalar;
-
- // Only a pointer or reference type can have a different dynamic and static type:
- if (CouldHaveDynamicValue (in_value))
+ if (m_process && vtable_load_addr != LLDB_INVALID_ADDRESS)
{
- // First job, pull out the address at 0 offset from the object.
- AddressType address_type;
- lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
- if (original_ptr == LLDB_INVALID_ADDRESS)
- return false;
-
- ExecutionContext exe_ctx (in_value.GetExecutionContextRef());
-
- Target *target = exe_ctx.GetTargetPtr();
- Process *process = exe_ctx.GetProcessPtr();
-
- char memory_buffer[16];
- DataExtractor data(memory_buffer, sizeof(memory_buffer),
- process->GetByteOrder(),
- process->GetAddressByteSize());
- size_t address_byte_size = process->GetAddressByteSize();
- Error error;
- size_t bytes_read = process->ReadMemory (original_ptr,
- memory_buffer,
- address_byte_size,
- error);
- if (!error.Success() || (bytes_read != address_byte_size))
- {
- return false;
- }
-
- lldb::offset_t offset = 0;
- lldb::addr_t vtable_address_point = data.GetAddress (&offset);
-
- if (offset == 0)
- return false;
-
- // Now find the symbol that contains this address:
-
- SymbolContext sc;
- Address address_point_address;
- if (target && !target->GetSectionLoadList().IsEmpty())
+ // Find the symbol that contains the "vtable_load_addr" address
+ Address vtable_addr;
+ Target &target = m_process->GetTarget();
+ if (!target.GetSectionLoadList().IsEmpty())
{
- if (target->GetSectionLoadList().ResolveLoadAddress (vtable_address_point, address_point_address))
+ if (target.GetSectionLoadList().ResolveLoadAddress(vtable_load_addr, vtable_addr))
{
- target->GetImages().ResolveSymbolContextForAddress (address_point_address, eSymbolContextSymbol, sc);
+ // See if we have cached info for this type already
+ TypeAndOrName type_info = GetDynamicTypeInfo(vtable_addr);
+ if (type_info)
+ return type_info;
+
+ SymbolContext sc;
+ target.GetImages().ResolveSymbolContextForAddress(vtable_addr, eSymbolContextSymbol, sc);
Symbol *symbol = sc.symbol;
if (symbol != NULL)
{
@@ -119,52 +82,56 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
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);
- class_type_or_name.SetName (class_name);
+ type_info.SetName(class_name);
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 (sc,
ConstString(class_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 (sc,
- ConstString(class_name),
- exact_match,
- UINT32_MAX,
- class_types);
+ num_matches = target.GetImages().FindTypes(sc, ConstString(class_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);
- return false;
+ return TypeAndOrName();
}
if (num_matches == 1)
{
type_sp = class_types.GetTypeAtIndex(0);
- 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());
-
- class_type_or_name.SetTypeSP(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());
+ type_info.SetTypeSP(type_sp);
+ }
+ }
}
else if (num_matches > 1)
{
@@ -191,7 +158,7 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
type_sp = class_types.GetTypeAtIndex(i);
if (type_sp)
{
- if (ClangASTContext::IsCXXClassType(type_sp->GetFullCompilerType ()))
+ 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",
@@ -199,74 +166,112 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
in_value.GetTypeName().AsCString(),
type_sp->GetID(),
type_sp->GetName().GetCString());
- class_type_or_name.SetTypeSP(type_sp);
- break;
+ type_info.SetTypeSP(type_sp);
}
}
}
-
- if (i == num_matches)
- {
- if (log)
- 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());
- return false;
- }
- }
-
- // There can only be one type with a given name,
- // so we've just found duplicate definitions, and this
- // one will do as well as any other.
- // We don't consider something to have a dynamic type if
- // it is the same as the static type. So compare against
- // the value we were handed.
- if (type_sp)
- {
- if (ClangASTContext::AreTypesSame (in_value.GetCompilerType(),
- type_sp->GetFullCompilerType ()))
- {
- // The dynamic type we found was the same type,
- // so we don't have a dynamic type here...
- return false;
- }
- // The offset_to_top is two pointers above the address.
- Address offset_to_top_address = address_point_address;
- int64_t slide = -2 * ((int64_t) target->GetArchitecture().GetAddressByteSize());
- offset_to_top_address.Slide (slide);
-
- Error error;
- lldb::addr_t offset_to_top_location = offset_to_top_address.GetLoadAddress(target);
-
- size_t bytes_read = process->ReadMemory (offset_to_top_location,
- memory_buffer,
- address_byte_size,
- error);
-
- if (!error.Success() || (bytes_read != address_byte_size))
- {
- return false;
- }
-
- offset = 0;
- int64_t offset_to_top = data.GetMaxS64(&offset, process->GetAddressByteSize());
-
- // So the dynamic type is a value that starts at offset_to_top
- // above the original address.
- lldb::addr_t dynamic_addr = original_ptr + offset_to_top;
- if (!target->GetSectionLoadList().ResolveLoadAddress (dynamic_addr, dynamic_address))
+ if (log && i == num_matches)
{
- dynamic_address.SetRawAddress(dynamic_addr);
+ 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());
}
- return true;
}
+ if (type_info)
+ SetDynamicTypeInfo(vtable_addr, type_info);
+ return type_info;
}
}
}
}
}
-
+ return TypeAndOrName();
+}
+
+bool
+ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &dynamic_address,
+ Value::ValueType &value_type)
+{
+ // For Itanium, if the type has a vtable pointer in the object, it will be at offset 0
+ // in the object. That will point to the "address point" within the vtable (not the beginning of the
+ // vtable.) We can then look up the symbol containing this "address point" and that symbol's name
+ // demangled will contain the full class name.
+ // The second pointer above the "address point" is the "offset_to_top". We'll use that to get the
+ // start of the value object which holds the dynamic type.
+ //
+
+ class_type_or_name.Clear();
+ value_type = Value::ValueType::eValueTypeScalar;
+
+ // Only a pointer or reference type can have a different dynamic and static type:
+ if (CouldHaveDynamicValue(in_value))
+ {
+ // First job, pull out the address at 0 offset from the object.
+ AddressType address_type;
+ lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
+ if (original_ptr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
+
+ Process *process = exe_ctx.GetProcessPtr();
+
+ if (process == nullptr)
+ return false;
+
+ Error error;
+ const lldb::addr_t vtable_address_point = process->ReadPointerFromMemory(original_ptr, error);
+
+ if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS)
+ {
+ return false;
+ }
+
+ class_type_or_name = GetTypeInfoFromVTableAddress(in_value, original_ptr, vtable_address_point);
+
+ if (class_type_or_name)
+ {
+ TypeSP type_sp = class_type_or_name.GetTypeSP();
+ // There can only be one type with a given name,
+ // so we've just found duplicate definitions, and this
+ // one will do as well as any other.
+ // We don't consider something to have a dynamic type if
+ // it is the same as the static type. So compare against
+ // the value we were handed.
+ if (type_sp)
+ {
+ if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(), type_sp->GetForwardCompilerType()))
+ {
+ // The dynamic type we found was the same type,
+ // so we don't have a dynamic type here...
+ return false;
+ }
+
+ // The offset_to_top is two pointers above the vtable pointer.
+ const uint32_t addr_byte_size = process->GetAddressByteSize();
+ const lldb::addr_t offset_to_top_location = vtable_address_point - 2 * addr_byte_size;
+ // Watch for underflow, offset_to_top_location should be less than vtable_address_point
+ if (offset_to_top_location >= vtable_address_point)
+ return false;
+ const int64_t offset_to_top =
+ process->ReadSignedIntegerFromMemory(offset_to_top_location, addr_byte_size, INT64_MIN, error);
+
+ if (offset_to_top == INT64_MIN)
+ return false;
+ // So the dynamic type is a value that starts at offset_to_top
+ // above the original address.
+ lldb::addr_t dynamic_addr = original_ptr + offset_to_top;
+ if (!process->GetTarget().GetSectionLoadList().ResolveLoadAddress(dynamic_addr, dynamic_address))
+ {
+ dynamic_address.SetRawAddress(dynamic_addr);
+ }
+ return true;
+ }
+ }
+ }
+
return class_type_or_name.IsEmpty() == false;
}
@@ -336,12 +341,94 @@ ItaniumABILanguageRuntime::CreateInstance (Process *process, lldb::LanguageType
return NULL;
}
+class CommandObjectMultiwordItaniumABI_Demangle : public CommandObjectParsed
+{
+public:
+ CommandObjectMultiwordItaniumABI_Demangle (CommandInterpreter &interpreter) :
+ CommandObjectParsed (interpreter,
+ "demangle",
+ "Demangle a C++ mangled name.",
+ "language cplusplus demangle")
+ {
+ CommandArgumentEntry arg;
+ CommandArgumentData index_arg;
+
+ // Define the first (and only) variant of this arg.
+ index_arg.arg_type = eArgTypeSymbol;
+ index_arg.arg_repetition = eArgRepeatPlus;
+
+ // There is only one variant this argument could be; put it into the argument entry.
+ arg.push_back (index_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back (arg);
+ }
+
+ ~CommandObjectMultiwordItaniumABI_Demangle() override = default;
+
+protected:
+ bool
+ DoExecute(Args& command, CommandReturnObject &result) override
+ {
+ bool demangled_any = false;
+ bool error_any = false;
+ for (size_t i = 0; i < command.GetArgumentCount(); i++)
+ {
+ auto arg = command.GetArgumentAtIndex(i);
+ if (arg && *arg)
+ {
+ ConstString mangled_cs(arg);
+
+ // the actual Mangled class should be strict about this, but on the command line
+ // if you're copying mangled names out of 'nm' on Darwin, 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
+ if (mangled_cs.GetStringRef().startswith("__Z"))
+ mangled_cs.SetCString(arg+1);
+
+ Mangled mangled(mangled_cs, true);
+ if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus)
+ {
+ ConstString demangled(mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus));
+ demangled_any = true;
+ result.AppendMessageWithFormat("%s ---> %s\n", arg, demangled.GetCString());
+ }
+ else
+ {
+ error_any = true;
+ result.AppendErrorWithFormat("%s is not a valid C++ mangled name\n", arg);
+ }
+ }
+ }
+
+ result.SetStatus(error_any ? lldb::eReturnStatusFailed :
+ (demangled_any ? lldb::eReturnStatusSuccessFinishResult : lldb::eReturnStatusSuccessFinishNoResult));
+ return result.Succeeded();
+ }
+};
+
+class CommandObjectMultiwordItaniumABI : public CommandObjectMultiword
+{
+public:
+ CommandObjectMultiwordItaniumABI(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "cplusplus", "Commands for operating on the C++ language runtime.",
+ "cplusplus <subcommand> [<subcommand-options>]")
+ {
+ LoadSubCommand ("demangle", CommandObjectSP (new CommandObjectMultiwordItaniumABI_Demangle (interpreter)));
+ }
+
+ ~CommandObjectMultiwordItaniumABI() override = default;
+};
+
void
ItaniumABILanguageRuntime::Initialize()
{
PluginManager::RegisterPlugin (GetPluginNameStatic(),
"Itanium ABI for the C++ language",
- CreateInstance);
+ CreateInstance,
+ [] (CommandInterpreter& interpreter) -> lldb::CommandObjectSP {
+ return CommandObjectSP(new CommandObjectMultiwordItaniumABI(interpreter));
+ });
}
void
@@ -408,6 +495,7 @@ ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch
exception_names.size(),
eFunctionNameTypeBase,
eLanguageTypeUnknown,
+ 0,
eLazyBoolNo));
return resolver_sp;
@@ -510,3 +598,21 @@ ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop (lldb::StopInfoSP sto
m_cxx_exception_bp_sp->GetID());
}
+
+TypeAndOrName
+ItaniumABILanguageRuntime::GetDynamicTypeInfo(const lldb_private::Address &vtable_addr)
+{
+ std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
+ DynamicTypeCache::const_iterator pos = m_dynamic_type_map.find(vtable_addr);
+ if (pos == m_dynamic_type_map.end())
+ return TypeAndOrName();
+ else
+ return pos->second;
+}
+
+void
+ItaniumABILanguageRuntime::SetDynamicTypeInfo(const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info)
+{
+ std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
+ m_dynamic_type_map[vtable_addr] = type_info;
+}
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
index c06b9863a9bf..86bd728d6c6f 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
@@ -12,12 +12,15 @@
// C Includes
// C++ Includes
+#include <map>
+#include <mutex>
#include <vector>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Symbol/Type.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Core/Value.h"
@@ -100,9 +103,29 @@ namespace lldb_private {
bool is_internal);
private:
- ItaniumABILanguageRuntime(Process *process) : lldb_private::CPPLanguageRuntime(process) { } // Call CreateInstance instead.
-
- lldb::BreakpointSP m_cxx_exception_bp_sp;
+ typedef std::map<lldb_private::Address, TypeAndOrName> DynamicTypeCache;
+
+ ItaniumABILanguageRuntime(Process *process)
+ : // Call CreateInstance instead.
+ lldb_private::CPPLanguageRuntime(process),
+ m_cxx_exception_bp_sp(),
+ m_dynamic_type_map(),
+ m_dynamic_type_map_mutex()
+ {
+ }
+
+ lldb::BreakpointSP m_cxx_exception_bp_sp;
+ DynamicTypeCache m_dynamic_type_map;
+ std::mutex m_dynamic_type_map_mutex;
+
+ TypeAndOrName
+ GetTypeInfoFromVTableAddress(ValueObject &in_value, lldb::addr_t original_ptr, lldb::addr_t vtable_addr);
+
+ TypeAndOrName
+ GetDynamicTypeInfo(const lldb_private::Address &vtable_addr);
+
+ void
+ SetDynamicTypeInfo(const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info);
};
} // namespace lldb_private
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/Makefile b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/Makefile
deleted file mode 100644
index ac87437f9d2a..000000000000
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/LangRuntime/C++/ItaniumABI/Makefile --*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../../..
-LIBRARYNAME := lldbPluginCXXItaniumABI
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
index d59f292e7a08..c752971e7a09 100644
--- a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
@@ -20,6 +20,7 @@
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/Symbol/GoASTContext.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -117,10 +118,12 @@ LookupRuntimeType(ValueObjectSP type, ExecutionContext* exe_ctx, bool* is_direct
SymbolContext sc;
TypeList type_list;
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
uint32_t num_matches = target->GetImages().FindTypes (sc,
const_typename,
false,
2,
+ searched_symbol_files,
type_list);
if (num_matches > 0) {
return type_list.GetTypeAtIndex(0)->GetFullCompilerType();
diff --git a/source/Plugins/LanguageRuntime/Go/Makefile b/source/Plugins/LanguageRuntime/Go/Makefile
deleted file mode 100644
index 1c8114e421c1..000000000000
--- a/source/Plugins/LanguageRuntime/Go/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- Source/Plugins/LangRuntime/Go/Makefile ----*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginLanguageRuntimeGo
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/LanguageRuntime/Java/CMakeLists.txt b/source/Plugins/LanguageRuntime/Java/CMakeLists.txt
new file mode 100644
index 000000000000..4cfd71c2e242
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/Java/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_lldb_library(lldbPluginLanguageRuntimeJava
+ JavaLanguageRuntime.cpp
+ )
diff --git a/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp
new file mode 100644
index 000000000000..07312a8af0d6
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp
@@ -0,0 +1,176 @@
+//===-- JavaLanguageRuntime.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "JavaLanguageRuntime.h"
+
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Symbol/JavaASTContext.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/TypeList.h"
+#include "lldb/Target/SectionLoadList.h"
+#include "lldb/Target/Target.h"
+#include "llvm/ADT/StringRef.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+JavaLanguageRuntime::JavaLanguageRuntime(Process *process) : LanguageRuntime(process)
+{
+}
+
+LanguageRuntime *
+JavaLanguageRuntime::CreateInstance(Process *process, lldb::LanguageType language)
+{
+ if (language == eLanguageTypeJava)
+ return new JavaLanguageRuntime(process);
+ return nullptr;
+}
+
+void
+JavaLanguageRuntime::Initialize()
+{
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java language runtime", CreateInstance);
+}
+
+void
+JavaLanguageRuntime::Terminate()
+{
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString
+JavaLanguageRuntime::GetPluginNameStatic()
+{
+ static ConstString g_name("java");
+ return g_name;
+}
+
+lldb_private::ConstString
+JavaLanguageRuntime::GetPluginName()
+{
+ return GetPluginNameStatic();
+}
+
+uint32_t
+JavaLanguageRuntime::GetPluginVersion()
+{
+ return 1;
+}
+
+bool
+JavaLanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value)
+{
+ return true;
+}
+
+static ConstString
+GetDynamicTypeId(ExecutionContext *exe_ctx, Target *target, ValueObject &in_value)
+{
+ SymbolContext sc;
+ TypeList class_types;
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ size_t num_matches = target->GetImages().FindTypes(sc, ConstString("Object"),
+ true, // name_is_fully_qualified
+ UINT32_MAX, searched_symbol_files, class_types);
+ for (size_t i = 0; i < num_matches; ++i)
+ {
+ TypeSP type_sp = class_types.GetTypeAtIndex(i);
+ CompilerType compiler_type = type_sp->GetFullCompilerType();
+
+ if (compiler_type.GetMinimumLanguage() != eLanguageTypeJava ||
+ compiler_type.GetTypeName() != ConstString("java::lang::Object"))
+ continue;
+
+ if (compiler_type.GetCompleteType() && compiler_type.IsCompleteType())
+ {
+ uint64_t type_id = JavaASTContext::CalculateDynamicTypeId(exe_ctx, compiler_type, in_value);
+ if (type_id != UINT64_MAX)
+ {
+ char id[32];
+ snprintf(id, sizeof(id), "0x%" PRIX64, type_id);
+ return ConstString(id);
+ }
+ }
+ }
+ return ConstString();
+}
+
+bool
+JavaLanguageRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &dynamic_address,
+ Value::ValueType &value_type)
+{
+ class_type_or_name.Clear();
+
+ // null references don't have a dynamic type
+ if (in_value.IsNilReference())
+ return false;
+
+ ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
+ Target *target = exe_ctx.GetTargetPtr();
+ if (!target)
+ return false;
+
+ ConstString linkage_name;
+ CompilerType in_type = in_value.GetCompilerType();
+ if (in_type.IsPossibleDynamicType(nullptr, false, false))
+ linkage_name = GetDynamicTypeId(&exe_ctx, target, in_value);
+ else
+ linkage_name = JavaASTContext::GetLinkageName(in_type);
+
+ if (!linkage_name)
+ return false;
+
+ class_type_or_name.SetName(in_type.GetNonReferenceType().GetTypeName());
+
+ SymbolContext sc;
+ TypeList class_types;
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ size_t num_matches = target->GetImages().FindTypes(sc, linkage_name,
+ true, // name_is_fully_qualified
+ UINT32_MAX, searched_symbol_files, class_types);
+
+ for (size_t i = 0; i < num_matches; ++i)
+ {
+ TypeSP type_sp = class_types.GetTypeAtIndex(i);
+ CompilerType compiler_type = type_sp->GetFullCompilerType();
+
+ if (compiler_type.GetMinimumLanguage() != eLanguageTypeJava)
+ continue;
+
+ if (compiler_type.GetCompleteType() && compiler_type.IsCompleteType())
+ {
+ class_type_or_name.SetTypeSP(type_sp);
+
+ Value &value = in_value.GetValue();
+ value_type = value.GetValueType();
+ dynamic_address.SetRawAddress(value.GetScalar().ULongLong(0));
+ return true;
+ }
+ }
+ return false;
+}
+
+TypeAndOrName
+JavaLanguageRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value)
+{
+ CompilerType static_type(static_value.GetCompilerType());
+
+ TypeAndOrName ret(type_and_or_name);
+ if (type_and_or_name.HasType())
+ {
+ CompilerType orig_type = type_and_or_name.GetCompilerType();
+ if (static_type.IsReferenceType())
+ ret.SetCompilerType(orig_type.GetLValueReferenceType());
+ }
+ return ret;
+}
diff --git a/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h
new file mode 100644
index 000000000000..83ed35dbb59d
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h
@@ -0,0 +1,90 @@
+//===-- JavaLanguageRuntime.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_JavaLanguageRuntime_h_
+#define liblldb_JavaLanguageRuntime_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private
+{
+
+class JavaLanguageRuntime : public LanguageRuntime
+{
+public:
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb_private::LanguageRuntime *
+ CreateInstance(Process *process, lldb::LanguageType language);
+
+ static lldb_private::ConstString
+ GetPluginNameStatic();
+
+ lldb_private::ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
+
+ lldb::LanguageType
+ GetLanguageType() const override
+ {
+ return lldb::eLanguageTypeJava;
+ }
+
+ bool
+ GetObjectDescription(Stream &str, ValueObject &object) override
+ {
+ return false;
+ }
+
+ bool
+ GetObjectDescription(Stream &str, Value &value, ExecutionContextScope *exe_scope) override
+ {
+ return false;
+ }
+
+ lldb::BreakpointResolverSP
+ CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override
+ {
+ return nullptr;
+ }
+
+ TypeAndOrName
+ FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value) override;
+
+ bool
+ CouldHaveDynamicValue(ValueObject &in_value) override;
+
+ bool
+ GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &address,
+ Value::ValueType &value_type) override;
+
+protected:
+ JavaLanguageRuntime(Process *process);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(JavaLanguageRuntime);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_JavaLanguageRuntime_h_
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index 711d324d8aa7..5cf99a573d86 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -499,11 +499,9 @@ ClassDescriptorV2::GetInstanceSize ()
return 0;
}
-ClassDescriptorV2::iVarsStorage::iVarsStorage ():
-m_filled(false),
-m_ivars(),
-m_mutex(Mutex::eMutexTypeRecursive)
-{}
+ClassDescriptorV2::iVarsStorage::iVarsStorage() : m_filled(false), m_ivars(), m_mutex()
+{
+}
size_t
ClassDescriptorV2::iVarsStorage::size ()
@@ -522,7 +520,7 @@ ClassDescriptorV2::iVarsStorage::fill (AppleObjCRuntimeV2& runtime, ClassDescrip
{
if (m_filled)
return;
- Mutex::Locker lock(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES | LIBLLDB_LOG_VERBOSE));
if (log)
log->Printf("[ClassDescriptorV2::iVarsStorage::fill] class_name = %s", descriptor.GetClassName().AsCString("<unknown"));
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
index 18591ecd6e93..f5fc8bc0644b 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
@@ -12,10 +12,11 @@
// C Includes
// C++ Includes
+#include <mutex>
+
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "AppleObjCRuntimeV2.h"
@@ -247,7 +248,7 @@ private:
private:
bool m_filled;
std::vector<iVarDescriptor> m_ivars;
- Mutex m_mutex;
+ std::recursive_mutex m_mutex;
};
// The constructor should only be invoked by the runtime as it builds its caches
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index cd6ece297ed1..0c0e4f1ce8cc 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -9,10 +9,11 @@
#include "AppleObjCDeclVendor.h"
+#include "Plugins/ExpressionParser/Clang/ASTDumper.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
-#include "Plugins/ExpressionParser/Clang/ASTDumper.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -356,9 +357,10 @@ public:
}
clang::Selector sel = ast_ctx.Selectors.getSelector(is_zero_argument ? 0 : selector_components.size(), selector_components.data());
-
- clang::QualType ret_type = ClangASTContext::GetQualType(type_realizer_sp->RealizeType(interface_decl->getASTContext(), m_type_vector[0].c_str(), for_expression));
-
+
+ clang::QualType ret_type = ClangUtil::GetQualType(
+ type_realizer_sp->RealizeType(interface_decl->getASTContext(), m_type_vector[0].c_str(), for_expression));
+
if (ret_type.isNull())
return NULL;
@@ -384,8 +386,9 @@ public:
++ai)
{
const bool for_expression = true;
- clang::QualType arg_type = ClangASTContext::GetQualType(type_realizer_sp->RealizeType(ast_ctx, m_type_vector[ai].c_str(), for_expression));
-
+ clang::QualType arg_type = ClangUtil::GetQualType(
+ type_realizer_sp->RealizeType(ast_ctx, m_type_vector[ai].c_str(), for_expression));
+
if (arg_type.isNull())
return NULL; // well, we just wasted a bunch of time. Wish we could delete the stuff we'd just made!
@@ -404,6 +407,24 @@ public:
return ret;
}
+
+ explicit operator bool ()
+ {
+ return m_is_valid;
+ }
+
+ size_t
+ GetNumTypes ()
+ {
+ return m_type_vector.size();
+ }
+
+ const char*
+ GetTypeAtIndex (size_t idx)
+ {
+ return m_type_vector[idx].c_str();
+ }
+
private:
typedef std::vector <std::string> TypeVector;
@@ -502,17 +523,12 @@ AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl)
{
clang::TypeSourceInfo * const type_source_info = nullptr;
const bool is_synthesized = false;
- clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create (*m_ast_ctx.getASTContext(),
- interface_decl,
- clang::SourceLocation(),
- clang::SourceLocation(),
- &m_ast_ctx.getASTContext()->Idents.get(name),
- ClangASTContext::GetQualType(ivar_type),
- type_source_info, // TypeSourceInfo *
- clang::ObjCIvarDecl::Public,
- 0,
- is_synthesized);
-
+ clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create(
+ *m_ast_ctx.getASTContext(), interface_decl, clang::SourceLocation(), clang::SourceLocation(),
+ &m_ast_ctx.getASTContext()->Idents.get(name), ClangUtil::GetQualType(ivar_type),
+ type_source_info, // TypeSourceInfo *
+ clang::ObjCIvarDecl::Public, 0, is_synthesized);
+
if (ivar_decl)
{
interface_decl->addDecl(ivar_decl);
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 2810b24cb7a4..6d83f7a7c5e1 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -23,6 +23,7 @@
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -151,10 +152,10 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon
exe_ctx.SetFrameSP(thread->GetSelectedFrame());
}
}
-
+
// Now we're ready to call the function:
-
- StreamString error_stream;
+
+ DiagnosticManager diagnostics;
lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
if (!m_print_object_caller_up)
@@ -172,30 +173,22 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon
strm.Printf("Could not get function runner to call print for debugger function: %s.", error.AsCString());
return false;
}
- m_print_object_caller_up->InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
+ m_print_object_caller_up->InsertFunction(exe_ctx, wrapper_struct_addr, diagnostics);
}
else
{
- m_print_object_caller_up->WriteFunctionArguments(exe_ctx,
- wrapper_struct_addr,
- arg_value_list,
- error_stream);
+ m_print_object_caller_up->WriteFunctionArguments(exe_ctx, wrapper_struct_addr, arg_value_list, diagnostics);
}
-
-
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
options.SetTryAllThreads(true);
options.SetStopOthers(true);
options.SetIgnoreBreakpoints(true);
options.SetTimeoutUsec(PO_FUNCTION_TIMEOUT_USEC);
-
- ExpressionResults results = m_print_object_caller_up->ExecuteFunction (exe_ctx,
- &wrapper_struct_addr,
- options,
- error_stream,
- ret);
+
+ ExpressionResults results =
+ m_print_object_caller_up->ExecuteFunction(exe_ctx, &wrapper_struct_addr, options, diagnostics, ret);
if (results != eExpressionCompleted)
{
strm.Printf("Error evaluating Print Object function: %d.\n", results);
@@ -401,8 +394,8 @@ AppleObjCRuntime::GetObjCVersion (Process *process, ModuleSP &objc_module_sp)
return ObjCRuntimeVersions::eObjC_VersionUnknown;
const ModuleList &target_modules = target.GetImages();
- Mutex::Locker modules_locker(target_modules.GetMutex());
-
+ std::lock_guard<std::recursive_mutex> gaurd(target_modules.GetMutex());
+
size_t num_images = target_modules.GetSize();
for (size_t i = 0; i < num_images; i++)
{
@@ -531,7 +524,7 @@ AppleObjCRuntime::ReadObjCLibraryIfNeeded (const ModuleList &module_list)
{
if (!HasReadObjCLibrary ())
{
- Mutex::Locker locker (module_list.GetMutex ());
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
size_t num_modules = module_list.GetSize();
for (size_t i = 0; i < num_modules; i++)
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 59b28b63f6b3..805fca7a31b9 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -136,6 +136,7 @@ AppleObjCRuntimeV1::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bo
eFunctionNameTypeBase,
eLanguageTypeUnknown,
Breakpoint::Exact,
+ 0,
eLazyBoolNo));
// FIXME: don't do catch yet.
return resolver_sp;
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 584449430829..e9a799bb3651 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -36,12 +36,14 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionValueBoolean.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
@@ -60,9 +62,6 @@
#include "AppleObjCDeclVendor.h"
#include "AppleObjCTrampolineHandler.h"
-#if defined(__APPLE__)
-#include "Plugins/Platform/MacOSX/PlatformiOSSimulator.h"
-#endif
using namespace lldb;
using namespace lldb_private;
@@ -81,12 +80,7 @@ extern "C"
char *strncpy (char * s1, const char * s2, size_t n);
int printf(const char * format, ...);
}
-//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
-#ifdef ENABLE_DEBUG_PRINTF
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
-#else
-#define DEBUG_PRINTF(fmt, ...)
-#endif
+#define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
typedef struct _NXMapTable {
void *prototype;
@@ -112,7 +106,8 @@ struct ClassInfo
uint32_t
__lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr,
void *class_infos_ptr,
- uint32_t class_infos_byte_size)
+ uint32_t class_infos_byte_size,
+ uint32_t should_log)
{
DEBUG_PRINTF ("gdb_objc_realized_classes_ptr = %p\n", gdb_objc_realized_classes_ptr);
DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
@@ -170,12 +165,7 @@ extern "C"
int printf(const char * format, ...);
}
-// #define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
-#ifdef ENABLE_DEBUG_PRINTF
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
-#else
-#define DEBUG_PRINTF(fmt, ...)
-#endif
+#define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
struct objc_classheader_t {
@@ -224,12 +214,13 @@ struct ClassInfo
uint32_t
__lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
void *class_infos_ptr,
- uint32_t class_infos_byte_size)
+ uint32_t class_infos_byte_size,
+ uint32_t should_log)
{
uint32_t idx = 0;
DEBUG_PRINTF ("objc_opt_ro_ptr = %p\n", objc_opt_ro_ptr);
DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
- DEBUG_PRINTF ("class_infos_byte_size = %u (%" PRIu64 " class infos)\n", class_infos_byte_size, (size_t)(class_infos_byte_size/sizeof(ClassInfo)));
+ DEBUG_PRINTF ("class_infos_byte_size = %u (%llu class infos)\n", class_infos_byte_size, (uint64_t)(class_infos_byte_size/sizeof(ClassInfo)));
if (objc_opt_ro_ptr)
{
const objc_opt_t *objc_opt = (objc_opt_t *)objc_opt_ro_ptr;
@@ -250,7 +241,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
DEBUG_PRINTF ("objc_opt->headeropt_offset = %d\n", objc_opt->headeropt_offset);
DEBUG_PRINTF ("objc_opt->clsopt_offset = %d\n", objc_opt->clsopt_offset);
}
- if (objc_opt->version == 12 || objc_opt->version == 13 || objc_opt->version == 14)
+ if (objc_opt->version == 12 || objc_opt->version == 13 || objc_opt->version == 14 || objc_opt->version == 15)
{
const objc_clsopt_t* clsopt = NULL;
if (is_v14_format)
@@ -258,6 +249,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
else
clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt + objc_opt->clsopt_offset);
const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
+ DEBUG_PRINTF("max_class_infos = %llu\n", (uint64_t)max_class_infos);
ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
int32_t invalidEntryOffset = 0;
// this is safe to do because the version field order is invariant
@@ -269,13 +261,21 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
DEBUG_PRINTF ("clsopt->capacity = %u\n", clsopt->capacity);
DEBUG_PRINTF ("clsopt->mask = 0x%8.8x\n", clsopt->mask);
DEBUG_PRINTF ("classOffsets = %p\n", classOffsets);
+ DEBUG_PRINTF("invalidEntryOffset = %d\n", invalidEntryOffset);
for (uint32_t i=0; i<clsopt->capacity; ++i)
{
const int32_t clsOffset = classOffsets[i].clsOffset;
+ DEBUG_PRINTF("clsOffset[%u] = %u\n", i, clsOffset);
if (clsOffset & 1)
+ {
+ DEBUG_PRINTF("clsOffset & 1\n");
continue; // duplicate
+ }
else if (clsOffset == invalidEntryOffset)
+ {
+ DEBUG_PRINTF("clsOffset == invalidEntryOffset\n");
continue; // invalid offset
+ }
if (class_infos && idx < max_class_infos)
{
@@ -289,6 +289,10 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
h = ((h << 5) + h) + c;
class_infos[idx].hash = h;
}
+ else
+ {
+ DEBUG_PRINTF("not(class_infos && idx < max_class_infos)\n");
+ }
++idx;
}
@@ -375,27 +379,27 @@ ExtractRuntimeGlobalSymbol (Process* process,
}
}
-AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process,
- const ModuleSP &objc_module_sp) :
- AppleObjCRuntime (process),
- m_get_class_info_code(),
- m_get_class_info_args (LLDB_INVALID_ADDRESS),
- m_get_class_info_args_mutex (Mutex::eMutexTypeNormal),
- m_get_shared_cache_class_info_code(),
- m_get_shared_cache_class_info_args (LLDB_INVALID_ADDRESS),
- m_get_shared_cache_class_info_args_mutex (Mutex::eMutexTypeNormal),
- m_decl_vendor_ap (),
- m_isa_hash_table_ptr (LLDB_INVALID_ADDRESS),
- m_hash_signature (),
- m_has_object_getClass (false),
- m_loaded_objc_opt (false),
- m_non_pointer_isa_cache_ap(NonPointerISACache::CreateInstance(*this,objc_module_sp)),
- m_tagged_pointer_vendor_ap(TaggedPointerVendorV2::CreateInstance(*this,objc_module_sp)),
- m_encoding_to_type_sp(),
- m_noclasses_warning_emitted(false)
+AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process, const ModuleSP &objc_module_sp)
+ : AppleObjCRuntime(process),
+ m_get_class_info_code(),
+ m_get_class_info_args(LLDB_INVALID_ADDRESS),
+ m_get_class_info_args_mutex(),
+ m_get_shared_cache_class_info_code(),
+ m_get_shared_cache_class_info_args(LLDB_INVALID_ADDRESS),
+ m_get_shared_cache_class_info_args_mutex(),
+ m_decl_vendor_ap(),
+ m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS),
+ m_hash_signature(),
+ m_has_object_getClass(false),
+ m_loaded_objc_opt(false),
+ m_non_pointer_isa_cache_ap(NonPointerISACache::CreateInstance(*this, objc_module_sp)),
+ m_tagged_pointer_vendor_ap(TaggedPointerVendorV2::CreateInstance(*this, objc_module_sp)),
+ m_encoding_to_type_sp(),
+ m_noclasses_warning_emitted(false)
{
static const ConstString g_gdb_object_getClass("gdb_object_getClass");
- m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass, eSymbolTypeCode) != NULL);
+ m_has_object_getClass =
+ (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass, eSymbolTypeCode) != NULL);
}
bool
@@ -485,6 +489,52 @@ AppleObjCRuntimeV2::CreateInstance (Process *process, LanguageType language)
class CommandObjectObjC_ClassTable_Dump : public CommandObjectParsed
{
public:
+ class CommandOptions : public Options
+ {
+ public:
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options(interpreter),
+ m_verbose(false,false)
+ {}
+
+ ~CommandOptions() override = default;
+
+ Error
+ SetOptionValue(uint32_t option_idx, const char *option_arg) override
+ {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ switch (short_option)
+ {
+ case 'v':
+ m_verbose.SetCurrentValue(true);
+ m_verbose.SetOptionWasSet();
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ OptionParsingStarting() override
+ {
+ m_verbose.Clear();
+ }
+
+ const OptionDefinition*
+ GetDefinitions() override
+ {
+ return g_option_table;
+ }
+
+ OptionValueBoolean m_verbose;
+ static OptionDefinition g_option_table[];
+ };
+
CommandObjectObjC_ClassTable_Dump (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"dump",
@@ -492,39 +542,116 @@ public:
"language objc class-table dump",
eCommandRequiresProcess |
eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused )
+ eCommandProcessMustBePaused ),
+ m_options(interpreter)
{
+ CommandArgumentEntry arg;
+ CommandArgumentData index_arg;
+
+ // Define the first (and only) variant of this arg.
+ index_arg.arg_type = eArgTypeRegularExpression;
+ index_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the argument entry.
+ arg.push_back (index_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back (arg);
}
~CommandObjectObjC_ClassTable_Dump() override = default;
+ Options *
+ GetOptions() override
+ {
+ return &m_options;
+ }
+
protected:
bool
DoExecute(Args& command, CommandReturnObject &result) override
{
+ std::unique_ptr<RegularExpression> regex_up;
+ switch(command.GetArgumentCount())
+ {
+ case 0:
+ break;
+ case 1:
+ {
+ regex_up.reset(new RegularExpression());
+ if (!regex_up->Compile(command.GetArgumentAtIndex(0)))
+ {
+ result.AppendError("invalid argument - please provide a valid regular expression");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
+ }
+ break;
+ }
+ default:
+ {
+ result.AppendError("please provide 0 or 1 arguments");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
+ }
+ }
+
Process *process = m_exe_ctx.GetProcessPtr();
ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
if (objc_runtime)
{
auto iterators_pair = objc_runtime->GetDescriptorIteratorPair();
auto iterator = iterators_pair.first;
+ auto &std_out = result.GetOutputStream();
for(; iterator != iterators_pair.second; iterator++)
{
- result.GetOutputStream().Printf("isa = 0x%" PRIx64, iterator->first);
if (iterator->second)
{
- result.GetOutputStream().Printf(" name = %s", iterator->second->GetClassName().AsCString("<unknown>"));
- result.GetOutputStream().Printf(" instance size = %" PRIu64, iterator->second->GetInstanceSize());
- result.GetOutputStream().Printf(" num ivars = %" PRIuPTR, (uintptr_t)iterator->second->GetNumIVars());
+ const char* class_name = iterator->second->GetClassName().AsCString("<unknown>");
+ if (regex_up && class_name && !regex_up->Execute(class_name))
+ continue;
+ std_out.Printf("isa = 0x%" PRIx64, iterator->first);
+ std_out.Printf(" name = %s", class_name);
+ std_out.Printf(" instance size = %" PRIu64, iterator->second->GetInstanceSize());
+ std_out.Printf(" num ivars = %" PRIuPTR, (uintptr_t)iterator->second->GetNumIVars());
if (auto superclass = iterator->second->GetSuperclass())
{
- result.GetOutputStream().Printf(" superclass = %s", superclass->GetClassName().AsCString("<unknown>"));
+ std_out.Printf(" superclass = %s", superclass->GetClassName().AsCString("<unknown>"));
+ }
+ std_out.Printf("\n");
+ if (m_options.m_verbose)
+ {
+ for(size_t i = 0;
+ i < iterator->second->GetNumIVars();
+ i++)
+ {
+ auto ivar = iterator->second->GetIVarAtIndex(i);
+ std_out.Printf(" ivar name = %s type = %s size = %" PRIu64 " offset = %" PRId32 "\n",
+ ivar.m_name.AsCString("<unknown>"),
+ ivar.m_type.GetDisplayTypeName().AsCString("<unknown>"),
+ ivar.m_size,
+ ivar.m_offset);
+ }
+ iterator->second->Describe(nullptr,
+ [objc_runtime, &std_out] (const char* name, const char* type) -> bool {
+ std_out.Printf(" instance method name = %s type = %s\n",
+ name,
+ type);
+ return false;
+ },
+ [objc_runtime, &std_out] (const char* name, const char* type) -> bool {
+ std_out.Printf(" class method name = %s type = %s\n",
+ name,
+ type);
+ return false;
+ },
+ nullptr);
}
- result.GetOutputStream().Printf("\n");
}
else
{
- result.GetOutputStream().Printf(" has no associated class.\n");
+ if (regex_up && !regex_up->Execute(""))
+ continue;
+ std_out.Printf("isa = 0x%" PRIx64 " has no associated class.\n", iterator->first);
}
}
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
@@ -537,6 +664,15 @@ protected:
return false;
}
}
+
+ CommandOptions m_options;
+};
+
+OptionDefinition
+CommandObjectObjC_ClassTable_Dump::CommandOptions::g_option_table[] =
+{
+ { LLDB_OPT_SET_ALL, false, "verbose" , 'v', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Print ivar and method information in detail"},
+ { 0 , false, nullptr , 0, 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
class CommandObjectMultiwordObjC_TaggedPointer_Info : public CommandObjectParsed
@@ -639,11 +775,9 @@ protected:
class CommandObjectMultiwordObjC_ClassTable : public CommandObjectMultiword
{
public:
- CommandObjectMultiwordObjC_ClassTable (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "class-table",
- "A set of commands for operating on the Objective-C class table.",
- "class-table <subcommand> [<subcommand-options>]")
+ CommandObjectMultiwordObjC_ClassTable(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "class-table", "Commands for operating on the Objective-C class table.",
+ "class-table <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("dump", CommandObjectSP (new CommandObjectObjC_ClassTable_Dump (interpreter)));
}
@@ -654,12 +788,10 @@ public:
class CommandObjectMultiwordObjC_TaggedPointer : public CommandObjectMultiword
{
public:
-
- CommandObjectMultiwordObjC_TaggedPointer (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "tagged-pointer",
- "A set of commands for operating on Objective-C tagged pointers.",
- "class-table <subcommand> [<subcommand-options>]")
+ CommandObjectMultiwordObjC_TaggedPointer(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "tagged-pointer",
+ "Commands for operating on Objective-C tagged pointers.",
+ "class-table <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("info", CommandObjectSP (new CommandObjectMultiwordObjC_TaggedPointer_Info (interpreter)));
}
@@ -670,11 +802,9 @@ public:
class CommandObjectMultiwordObjC : public CommandObjectMultiword
{
public:
- CommandObjectMultiwordObjC (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "objc",
- "A set of commands for operating on the Objective-C Language Runtime.",
- "objc <subcommand> [<subcommand-options>]")
+ CommandObjectMultiwordObjC(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "objc", "Commands for operating on the Objective-C language runtime.",
+ "objc <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("class-table", CommandObjectSP (new CommandObjectMultiwordObjC_ClassTable (interpreter)));
LoadSubCommand ("tagged-pointer", CommandObjectSP (new CommandObjectMultiwordObjC_TaggedPointer (interpreter)));
@@ -733,6 +863,7 @@ AppleObjCRuntimeV2::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bo
eFunctionNameTypeBase,
eLanguageTypeUnknown,
Breakpoint::Exact,
+ 0,
eLazyBoolNo));
// FIXME: We don't do catch breakpoints for ObjC yet.
// Should there be some way for the runtime to specify what it can do in this regard?
@@ -1231,7 +1362,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
ExecutionContext exe_ctx;
- ThreadSP thread_sp = process->GetThreadList().GetSelectedThread();
+ ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
if (!thread_sp)
return false;
@@ -1241,13 +1372,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
if (!ast)
return false;
-
+
Address function_address;
-
- StreamString errors;
-
+
+ DiagnosticManager diagnostics;
+
const uint32_t addr_size = process->GetAddressByteSize();
-
+
Error err;
// Read the total number of classes from the hash table
@@ -1281,12 +1412,15 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
}
else
{
- errors.Clear();
-
- if (!m_get_class_info_code->Install(errors, exe_ctx))
+ diagnostics.Clear();
+
+ if (!m_get_class_info_code->Install(diagnostics, exe_ctx))
{
if (log)
- log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ {
+ log->Printf("Failed to install implementation lookup");
+ diagnostics.Dump(log);
+ }
m_get_class_info_code.reset();
}
}
@@ -1303,9 +1437,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
value.SetValueType (Value::eValueTypeScalar);
value.SetCompilerType (clang_uint32_t_type);
arguments.PushValue (value);
+ arguments.PushValue (value);
get_class_info_function = m_get_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
arguments,
+ thread_sp,
error);
if (error.Fail())
@@ -1321,14 +1457,18 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
if (!get_class_info_function)
{
if (log)
- log->Printf ("Failed to get implementation lookup function caller: %s.", errors.GetData());
+ {
+ log->Printf("Failed to get implementation lookup function caller.");
+ diagnostics.Dump(log);
+ }
+
return false;
}
arguments = get_class_info_function->GetArgumentValues();
}
- errors.Clear();
-
+ diagnostics.Clear();
+
const uint32_t class_info_byte_size = addr_size + 4;
const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
lldb::addr_t class_infos_addr = process->AllocateMemory(class_infos_byte_size,
@@ -1337,23 +1477,22 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
if (class_infos_addr == LLDB_INVALID_ADDRESS)
return false;
-
- Mutex::Locker locker(m_get_class_info_args_mutex);
-
+
+ std::lock_guard<std::mutex> guard(m_get_class_info_args_mutex);
+
// Fill in our function argument values
arguments.GetValueAtIndex(0)->GetScalar() = hash_table.GetTableLoadAddress();
arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+ arguments.GetValueAtIndex(3)->GetScalar() = (GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES) == nullptr ? 0 : 1);
+
bool success = false;
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Write our function arguments into the process so we can run our function
- if (get_class_info_function->WriteFunctionArguments (exe_ctx,
- m_get_class_info_args,
- arguments,
- errors))
+ if (get_class_info_function->WriteFunctionArguments(exe_ctx, m_get_class_info_args, arguments, diagnostics))
{
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
@@ -1365,18 +1504,15 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
Value return_value;
return_value.SetValueType (Value::eValueTypeScalar);
//return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
- return_value.SetCompilerType (clang_uint32_t_type);
+ return_value.SetCompilerType(clang_uint32_t_type);
return_value.GetScalar() = 0;
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Run the function
- ExpressionResults results = get_class_info_function->ExecuteFunction (exe_ctx,
- &m_get_class_info_args,
- options,
- errors,
- return_value);
-
+ ExpressionResults results = get_class_info_function->ExecuteFunction(exe_ctx, &m_get_class_info_args, options,
+ diagnostics, return_value);
+
if (results == eExpressionCompleted)
{
// The result is the number of ClassInfo structures that were filled in
@@ -1401,15 +1537,21 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
else
{
if (log)
- log->Printf("Error evaluating our find class name function: %s.\n", errors.GetData());
+ {
+ log->Printf("Error evaluating our find class name function.");
+ diagnostics.Dump(log);
+ }
}
}
else
{
if (log)
- log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+ {
+ log->Printf("Error writing function arguments.");
+ diagnostics.Dump(log);
+ }
}
-
+
// Deallocate the memory we allocated for the ClassInfo array
process->DeallocateMemory(class_infos_addr);
@@ -1475,7 +1617,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
ExecutionContext exe_ctx;
- ThreadSP thread_sp = process->GetThreadList().GetSelectedThread();
+ ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
if (!thread_sp)
return DescriptorMapUpdateResult::Fail();
@@ -1485,13 +1627,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
if (!ast)
return DescriptorMapUpdateResult::Fail();
-
+
Address function_address;
-
- StreamString errors;
-
+
+ DiagnosticManager diagnostics;
+
const uint32_t addr_size = process->GetAddressByteSize();
-
+
Error err;
const lldb::addr_t objc_opt_ptr = GetSharedCacheReadOnlyAddress();
@@ -1530,16 +1672,19 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
}
else
{
- errors.Clear();
-
- if (!m_get_shared_cache_class_info_code->Install(errors, exe_ctx))
+ diagnostics.Clear();
+
+ if (!m_get_shared_cache_class_info_code->Install(diagnostics, exe_ctx))
{
if (log)
- log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ {
+ log->Printf("Failed to install implementation lookup.");
+ diagnostics.Dump(log);
+ }
m_get_shared_cache_class_info_code.reset();
}
}
-
+
if (!m_get_shared_cache_class_info_code.get())
return DescriptorMapUpdateResult::Fail();
@@ -1555,9 +1700,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
//value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
value.SetCompilerType (clang_uint32_t_type);
arguments.PushValue (value);
+ arguments.PushValue (value);
get_shared_cache_class_info_function = m_get_shared_cache_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
arguments,
+ thread_sp,
error);
if (get_shared_cache_class_info_function == nullptr)
@@ -1571,9 +1718,9 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
return DescriptorMapUpdateResult::Fail();
arguments = get_shared_cache_class_info_function->GetArgumentValues();
}
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
const uint32_t class_info_byte_size = addr_size + 4;
const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
lldb::addr_t class_infos_addr = process->AllocateMemory (class_infos_byte_size,
@@ -1582,24 +1729,24 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
if (class_infos_addr == LLDB_INVALID_ADDRESS)
return DescriptorMapUpdateResult::Fail();
-
- Mutex::Locker locker(m_get_shared_cache_class_info_args_mutex);
-
+
+ std::lock_guard<std::mutex> guard(m_get_shared_cache_class_info_args_mutex);
+
// Fill in our function argument values
arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+ arguments.GetValueAtIndex(3)->GetScalar() = (GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES) == nullptr ? 0 : 1);
+
bool success = false;
bool any_found = false;
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Write our function arguments into the process so we can run our function
- if (get_shared_cache_class_info_function->WriteFunctionArguments (exe_ctx,
- m_get_shared_cache_class_info_args,
- arguments,
- errors))
+ if (get_shared_cache_class_info_function->WriteFunctionArguments(exe_ctx, m_get_shared_cache_class_info_args,
+ arguments, diagnostics))
{
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
@@ -1611,18 +1758,15 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
Value return_value;
return_value.SetValueType (Value::eValueTypeScalar);
//return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
- return_value.SetCompilerType (clang_uint32_t_type);
+ return_value.SetCompilerType(clang_uint32_t_type);
return_value.GetScalar() = 0;
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Run the function
- ExpressionResults results = get_shared_cache_class_info_function->ExecuteFunction (exe_ctx,
- &m_get_shared_cache_class_info_args,
- options,
- errors,
- return_value);
-
+ ExpressionResults results = get_shared_cache_class_info_function->ExecuteFunction(
+ exe_ctx, &m_get_shared_cache_class_info_args, options, diagnostics, return_value);
+
if (results == eExpressionCompleted)
{
// The result is the number of ClassInfo structures that were filled in
@@ -1668,15 +1812,21 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
else
{
if (log)
- log->Printf("Error evaluating our find class name function: %s.\n", errors.GetData());
+ {
+ log->Printf("Error evaluating our find class name function.");
+ diagnostics.Dump(log);
+ }
}
}
else
{
if (log)
- log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+ {
+ log->Printf("Error writing function arguments.");
+ diagnostics.Dump(log);
+ }
}
-
+
// Deallocate the memory we allocated for the ClassInfo array
process->DeallocateMemory(class_infos_addr);
@@ -1803,17 +1953,14 @@ AppleObjCRuntimeV2::WarnIfNoClassesCached ()
if (m_noclasses_warning_emitted)
return;
-#if defined(__APPLE__)
if (m_process &&
m_process->GetTarget().GetPlatform() &&
- m_process->GetTarget().GetPlatform()->GetPluginName() == PlatformiOSSimulator::GetPluginNameStatic())
+ m_process->GetTarget().GetPlatform()->GetPluginName().GetStringRef().endswith("-simulator"))
{
- // the iOS simulator does not have the objc_opt_ro class table
- // so don't actually complain to the user
+ // Simulators do not have the objc_opt_ro class table so don't actually complain to the user
m_noclasses_warning_emitted = true;
return;
}
-#endif
Debugger &debugger(GetProcess()->GetTarget().GetDebugger());
@@ -2025,6 +2172,74 @@ AppleObjCRuntimeV2::TaggedPointerVendorV2::CreateInstance (AppleObjCRuntimeV2& r
if (error.Fail())
return new TaggedPointerVendorLegacy(runtime);
+ // try to detect the "extended tagged pointer" variables - if any are missing, use the non-extended vendor
+ do
+ {
+ auto objc_debug_taggedpointer_ext_mask = ExtractRuntimeGlobalSymbol(process,
+ ConstString("objc_debug_taggedpointer_ext_mask"),
+ objc_module_sp,
+ error);
+ if (error.Fail())
+ break;
+
+ auto objc_debug_taggedpointer_ext_slot_shift = ExtractRuntimeGlobalSymbol(process,
+ ConstString("objc_debug_taggedpointer_ext_slot_shift"),
+ objc_module_sp,
+ error,
+ true,
+ 4);
+ if (error.Fail())
+ break;
+
+ auto objc_debug_taggedpointer_ext_slot_mask = ExtractRuntimeGlobalSymbol(process,
+ ConstString("objc_debug_taggedpointer_ext_slot_mask"),
+ objc_module_sp,
+ error,
+ true,
+ 4);
+ if (error.Fail())
+ break;
+
+ auto objc_debug_taggedpointer_ext_classes = ExtractRuntimeGlobalSymbol(process,
+ ConstString("objc_debug_taggedpointer_ext_classes"),
+ objc_module_sp,
+ error,
+ false);
+ if (error.Fail())
+ break;
+
+ auto objc_debug_taggedpointer_ext_payload_lshift = ExtractRuntimeGlobalSymbol(process,
+ ConstString("objc_debug_taggedpointer_ext_payload_lshift"),
+ objc_module_sp,
+ error,
+ true,
+ 4);
+ if (error.Fail())
+ break;
+
+ auto objc_debug_taggedpointer_ext_payload_rshift = ExtractRuntimeGlobalSymbol(process,
+ ConstString("objc_debug_taggedpointer_ext_payload_rshift"),
+ objc_module_sp,
+ error,
+ true,
+ 4);
+ if (error.Fail())
+ break;
+
+ return new TaggedPointerVendorExtended(runtime,
+ objc_debug_taggedpointer_mask,
+ objc_debug_taggedpointer_ext_mask,
+ objc_debug_taggedpointer_slot_shift,
+ objc_debug_taggedpointer_ext_slot_shift,
+ objc_debug_taggedpointer_slot_mask,
+ objc_debug_taggedpointer_ext_slot_mask,
+ objc_debug_taggedpointer_payload_lshift,
+ objc_debug_taggedpointer_payload_rshift,
+ objc_debug_taggedpointer_ext_payload_lshift,
+ objc_debug_taggedpointer_ext_payload_rshift,
+ objc_debug_taggedpointer_classes,
+ objc_debug_taggedpointer_ext_classes);
+ } while(false);
// we might want to have some rules to outlaw these values (e.g if the table's address is zero)
@@ -2164,6 +2379,87 @@ AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor (lldb
return ClassDescriptorSP(new ClassDescriptorV2Tagged(actual_class_descriptor_sp,data_payload));
}
+AppleObjCRuntimeV2::TaggedPointerVendorExtended::TaggedPointerVendorExtended (AppleObjCRuntimeV2& runtime,
+ uint64_t objc_debug_taggedpointer_mask,
+ uint64_t objc_debug_taggedpointer_ext_mask,
+ uint32_t objc_debug_taggedpointer_slot_shift,
+ uint32_t objc_debug_taggedpointer_ext_slot_shift,
+ uint32_t objc_debug_taggedpointer_slot_mask,
+ uint32_t objc_debug_taggedpointer_ext_slot_mask,
+ uint32_t objc_debug_taggedpointer_payload_lshift,
+ uint32_t objc_debug_taggedpointer_payload_rshift,
+ uint32_t objc_debug_taggedpointer_ext_payload_lshift,
+ uint32_t objc_debug_taggedpointer_ext_payload_rshift,
+ lldb::addr_t objc_debug_taggedpointer_classes,
+ lldb::addr_t objc_debug_taggedpointer_ext_classes) :
+TaggedPointerVendorRuntimeAssisted(runtime,
+ objc_debug_taggedpointer_mask,
+ objc_debug_taggedpointer_slot_shift,
+ objc_debug_taggedpointer_slot_mask,
+ objc_debug_taggedpointer_payload_lshift,
+ objc_debug_taggedpointer_payload_rshift,
+ objc_debug_taggedpointer_classes),
+m_ext_cache(),
+m_objc_debug_taggedpointer_ext_mask(objc_debug_taggedpointer_ext_mask),
+m_objc_debug_taggedpointer_ext_slot_shift(objc_debug_taggedpointer_ext_slot_shift),
+m_objc_debug_taggedpointer_ext_slot_mask(objc_debug_taggedpointer_ext_slot_mask),
+m_objc_debug_taggedpointer_ext_payload_lshift(objc_debug_taggedpointer_ext_payload_lshift),
+m_objc_debug_taggedpointer_ext_payload_rshift(objc_debug_taggedpointer_ext_payload_rshift),
+m_objc_debug_taggedpointer_ext_classes(objc_debug_taggedpointer_ext_classes)
+{
+}
+
+bool
+AppleObjCRuntimeV2::TaggedPointerVendorExtended::IsPossibleExtendedTaggedPointer (lldb::addr_t ptr)
+{
+ if (!IsPossibleTaggedPointer(ptr))
+ return false;
+
+ if (m_objc_debug_taggedpointer_ext_mask == 0)
+ return false;
+
+ return ((ptr & m_objc_debug_taggedpointer_ext_mask) == m_objc_debug_taggedpointer_ext_mask);
+}
+
+ObjCLanguageRuntime::ClassDescriptorSP
+AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor (lldb::addr_t ptr)
+{
+ ClassDescriptorSP actual_class_descriptor_sp;
+ uint64_t data_payload;
+
+ if (!IsPossibleTaggedPointer(ptr))
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+
+ if (!IsPossibleExtendedTaggedPointer(ptr))
+ return this->TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(ptr);
+
+ uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_ext_slot_shift) & m_objc_debug_taggedpointer_ext_slot_mask;
+
+ CacheIterator iterator = m_ext_cache.find(slot),
+ end = m_ext_cache.end();
+ if (iterator != end)
+ {
+ actual_class_descriptor_sp = iterator->second;
+ }
+ else
+ {
+ Process* process(m_runtime.GetProcess());
+ uintptr_t slot_ptr = slot*process->GetAddressByteSize()+m_objc_debug_taggedpointer_ext_classes;
+ Error error;
+ uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
+ if (error.Fail() || slot_data == 0 || slot_data == uintptr_t(LLDB_INVALID_ADDRESS))
+ return nullptr;
+ actual_class_descriptor_sp = m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data);
+ if (!actual_class_descriptor_sp)
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+ m_ext_cache[slot] = actual_class_descriptor_sp;
+ }
+
+ data_payload = (((uint64_t)ptr << m_objc_debug_taggedpointer_ext_payload_lshift) >> m_objc_debug_taggedpointer_ext_payload_rshift);
+
+ return ClassDescriptorSP(new ClassDescriptorV2Tagged(actual_class_descriptor_sp,data_payload));
+}
+
AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache (AppleObjCRuntimeV2& runtime,
uint64_t objc_debug_isa_class_mask,
uint64_t objc_debug_isa_magic_mask,
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index 96b47e8770f9..4b27c7400481 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -14,6 +14,7 @@
// C++ Includes
#include <map>
#include <memory>
+#include <mutex>
// Other libraries and framework includes
// Project includes
@@ -234,6 +235,45 @@ private:
DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted);
};
+ class TaggedPointerVendorExtended : public TaggedPointerVendorRuntimeAssisted
+ {
+ public:
+ ObjCLanguageRuntime::ClassDescriptorSP
+ GetClassDescriptor(lldb::addr_t ptr) override;
+
+ protected:
+ TaggedPointerVendorExtended (AppleObjCRuntimeV2& runtime,
+ uint64_t objc_debug_taggedpointer_mask,
+ uint64_t objc_debug_taggedpointer_ext_mask,
+ uint32_t objc_debug_taggedpointer_slot_shift,
+ uint32_t objc_debug_taggedpointer_ext_slot_shift,
+ uint32_t objc_debug_taggedpointer_slot_mask,
+ uint32_t objc_debug_taggedpointer_ext_slot_mask,
+ uint32_t objc_debug_taggedpointer_payload_lshift,
+ uint32_t objc_debug_taggedpointer_payload_rshift,
+ uint32_t objc_debug_taggedpointer_ext_payload_lshift,
+ uint32_t objc_debug_taggedpointer_ext_payload_rshift,
+ lldb::addr_t objc_debug_taggedpointer_classes,
+ lldb::addr_t objc_debug_taggedpointer_ext_classes);
+
+ bool
+ IsPossibleExtendedTaggedPointer (lldb::addr_t ptr);
+
+ typedef std::map<uint8_t,ObjCLanguageRuntime::ClassDescriptorSP> Cache;
+ typedef Cache::iterator CacheIterator;
+ Cache m_ext_cache;
+ uint64_t m_objc_debug_taggedpointer_ext_mask;
+ uint32_t m_objc_debug_taggedpointer_ext_slot_shift;
+ uint32_t m_objc_debug_taggedpointer_ext_slot_mask;
+ uint32_t m_objc_debug_taggedpointer_ext_payload_lshift;
+ uint32_t m_objc_debug_taggedpointer_ext_payload_rshift;
+ lldb::addr_t m_objc_debug_taggedpointer_ext_classes;
+
+ friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
+
+ DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorExtended);
+ };
+
class TaggedPointerVendorLegacy : public TaggedPointerVendorV2
{
public:
@@ -314,11 +354,11 @@ private:
std::unique_ptr<UtilityFunction> m_get_class_info_code;
lldb::addr_t m_get_class_info_args;
- Mutex m_get_class_info_args_mutex;
+ std::mutex m_get_class_info_args_mutex;
std::unique_ptr<UtilityFunction> m_get_shared_cache_class_info_code;
lldb::addr_t m_get_shared_cache_class_info_args;
- Mutex m_get_shared_cache_class_info_args_mutex;
+ std::mutex m_get_shared_cache_class_info_args_mutex;
std::unique_ptr<DeclVendor> m_decl_vendor_ap;
lldb::addr_t m_isa_hash_table_ptr;
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index d38a076ad5d7..5fedb80e29a6 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -22,19 +22,20 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Value.h"
-#include "lldb/Expression/UserExpression.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "llvm/ADT/STLExtras.h"
@@ -43,7 +44,6 @@ using namespace lldb;
using namespace lldb_private;
const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_name = "__lldb_objc_find_implementation_for_selector";
-const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_code = NULL;
const char *AppleObjCTrampolineHandler::g_lookup_implementation_with_stret_function_code = " \n\
extern \"C\" \n\
{ \n\
@@ -461,7 +461,7 @@ AppleObjCTrampolineHandler::AppleObjCVTables::InitializeVTableSymbols ()
Target &target = process_sp->GetTarget();
const ModuleList &target_modules = target.GetImages();
- Mutex::Locker modules_locker(target_modules.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
size_t num_modules = target_modules.GetSize();
if (!m_objc_module_sp)
{
@@ -657,6 +657,7 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process
const ModuleSP &objc_module_sp) :
m_process_wp (),
m_objc_module_sp (objc_module_sp),
+ m_lookup_implementation_function_code(nullptr),
m_impl_fn_addr (LLDB_INVALID_ADDRESS),
m_impl_stret_fn_addr (LLDB_INVALID_ADDRESS),
m_msg_forward_addr (LLDB_INVALID_ADDRESS)
@@ -703,11 +704,11 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process
// It there is no stret return lookup function, assume that it is the same as the straight lookup:
m_impl_stret_fn_addr = m_impl_fn_addr;
// Also we will use the version of the lookup code that doesn't rely on the stret version of the function.
- g_lookup_implementation_function_code = g_lookup_implementation_no_stret_function_code;
+ m_lookup_implementation_function_code = g_lookup_implementation_no_stret_function_code;
}
else
{
- g_lookup_implementation_function_code = g_lookup_implementation_with_stret_function_code;
+ m_lookup_implementation_function_code = g_lookup_implementation_with_stret_function_code;
}
// Look up the addresses for the objc dispatch functions and cache them. For now I'm inspecting the symbol
@@ -738,26 +739,28 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process
}
lldb::addr_t
-AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &dispatch_values)
+AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, ValueList &dispatch_values)
{
- ExecutionContext exe_ctx (thread.shared_from_this());
- StreamString errors;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ ThreadSP thread_sp(thread.shared_from_this());
+ ExecutionContext exe_ctx (thread_sp);
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
FunctionCaller *impl_function_caller = nullptr;
// Scope for mutex locker:
{
- Mutex::Locker locker(m_impl_function_mutex);
-
+ std::lock_guard<std::mutex> guard(m_impl_function_mutex);
+
// First stage is to make the ClangUtility to hold our injected function:
if (!m_impl_code.get())
{
- if (g_lookup_implementation_function_code != NULL)
+ if (m_lookup_implementation_function_code != NULL)
{
Error error;
- m_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_lookup_implementation_function_code,
+ m_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (m_lookup_implementation_function_code,
eLanguageTypeObjC,
g_lookup_implementation_function_name,
error));
@@ -768,11 +771,14 @@ AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &di
m_impl_code.reset();
return args_addr;
}
-
- if (!m_impl_code->Install(errors, exe_ctx))
+
+ if (!m_impl_code->Install(diagnostics, exe_ctx))
{
if (log)
- log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ {
+ log->Printf("Failed to install implementation lookup.");
+ diagnostics.Dump(log);
+ }
m_impl_code.reset();
return args_addr;
}
@@ -781,10 +787,8 @@ AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &di
{
if (log)
log->Printf("No method lookup implementation code.");
- errors.Printf ("No method lookup implementation code found.");
return LLDB_INVALID_ADDRESS;
}
-
// Next make the runner function for our implementation utility function.
ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
@@ -793,6 +797,7 @@ AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &di
impl_function_caller = m_impl_code->MakeFunctionCaller(clang_void_ptr_type,
dispatch_values,
+ thread_sp,
error);
if (error.Fail())
{
@@ -806,20 +811,23 @@ AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &di
impl_function_caller = m_impl_code->GetFunctionCaller();
}
}
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Now write down the argument values for this particular call. This looks like it might be a race condition
// if other threads were calling into here, but actually it isn't because we allocate a new args structure for
// this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (impl_function_caller->WriteFunctionArguments (exe_ctx, args_addr, dispatch_values, errors))
+ if (!impl_function_caller->WriteFunctionArguments(exe_ctx, args_addr, dispatch_values, diagnostics))
{
if (log)
- log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+ {
+ log->Printf("Error writing function arguments.");
+ diagnostics.Dump(log);
+ }
return args_addr;
}
-
+
return args_addr;
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
index 42d3461ddfa5..c0d1944a7f2f 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
@@ -13,12 +13,12 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
#include <vector>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Expression/UtilityFunction.h"
namespace lldb_private
@@ -65,7 +65,6 @@ public:
private:
static const char *g_lookup_implementation_function_name;
- static const char *g_lookup_implementation_function_code;
static const char *g_lookup_implementation_with_stret_function_code;
static const char *g_lookup_implementation_no_stret_function_code;
@@ -195,8 +194,9 @@ private:
MsgsendMap m_msgSend_map;
lldb::ProcessWP m_process_wp;
lldb::ModuleSP m_objc_module_sp;
+ const char *m_lookup_implementation_function_code;
std::unique_ptr<UtilityFunction> m_impl_code;
- Mutex m_impl_function_mutex;
+ std::mutex m_impl_function_mutex;
lldb::addr_t m_impl_fn_addr;
lldb::addr_t m_impl_stret_fn_addr;
lldb::addr_t m_msg_forward_addr;
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index 9308c7a668d2..d4adc094bc1b 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -10,6 +10,7 @@
#include "AppleObjCTypeEncodingParser.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -155,7 +156,7 @@ AppleObjCTypeEncodingParser::BuildAggregate (clang::ASTContext &ast_ctx, lldb_ut
}
ClangASTContext::CompleteTagDeclarationDefinition(union_type);
}
- return ClangASTContext::GetQualType(union_type);
+ return ClangUtil::GetQualType(union_type);
}
clang::QualType
@@ -171,7 +172,7 @@ AppleObjCTypeEncodingParser::BuildArray (clang::ASTContext &ast_ctx, lldb_utilit
if (!lldb_ctx)
return clang::QualType();
CompilerType array_type(lldb_ctx->CreateArrayType(CompilerType(&ast_ctx, element_type), size, false));
- return ClangASTContext::GetQualType(array_type);
+ return ClangUtil::GetQualType(array_type);
}
// the runtime can emit these in the form of @"SomeType", giving more specifics
@@ -261,8 +262,8 @@ AppleObjCTypeEncodingParser::BuildObjCObjectPointerType (clang::ASTContext &ast_
if (!num_types)
return ast_ctx.getObjCIdType();
#endif
-
- return ClangASTContext::GetQualType(ClangASTContext::GetTypeForDecl(decls[0]).GetPointerType());
+
+ return ClangUtil::GetQualType(ClangASTContext::GetTypeForDecl(decls[0]).GetPointerType());
}
else
{
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index 285786a09dbb..a2101c927b4d 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -13,16 +13,16 @@
// Project includes
#include "AppleThreadPlanStepThroughObjCTrampoline.h"
#include "AppleObjCTrampolineHandler.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Thread.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "lldb/Target/ThreadPlanStepOut.h"
-#include "lldb/Core/Log.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -75,9 +75,9 @@ AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller ()
{
if (!m_func_sp)
{
- StreamString errors;
+ DiagnosticManager diagnostics;
m_args_addr = m_trampoline_handler->SetupDispatchFunction(m_thread, m_input_values);
-
+
if (m_args_addr == LLDB_INVALID_ADDRESS)
{
return false;
@@ -89,12 +89,9 @@ AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller ()
options.SetIgnoreBreakpoints(true);
options.SetStopOthers(m_stop_others);
m_thread.CalculateExecutionContext(exc_ctx);
- m_func_sp = m_impl_function->GetThreadPlanToCallFunction (exc_ctx,
- m_args_addr,
- options,
- errors);
+ m_func_sp = m_impl_function->GetThreadPlanToCallFunction(exc_ctx, m_args_addr, options, diagnostics);
m_func_sp->SetOkayToDiscard(true);
- m_thread.QueueThreadPlan (m_func_sp, false);
+ m_thread.QueueThreadPlan(m_func_sp, false);
}
return true;
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/Makefile b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/Makefile
deleted file mode 100644
index 485fe75b3f88..000000000000
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/LangRuntime/ObjC/AppleRT/Makefile ----*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../../..
-LIBRARYNAME := lldbPluginAppleObjCRuntime
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/Makefile b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/Makefile
deleted file mode 100644
index eeb50ae3fcae..000000000000
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- Source/Plugins/LangRuntime/RenderScript/RenderScriptRuntime/Makefile ----*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../../..
-LIBRARYNAME := lldbPluginRenderScriptRuntime
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index 8e5d31b66350..7441fd991511 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -13,50 +13,49 @@
// Project includes
#include "RenderScriptRuntime.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/DumpValueObjectOptions.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Interpreter/Args.h"
-#include "lldb/Interpreter/Options.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/CommandObjectMultiword.h"
-#include "lldb/Breakpoint/StoppointCallbackContext.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Expression/UserExpression.h"
-#include "lldb/Symbol/VariableList.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_renderscript;
-namespace {
+namespace
+{
// The empirical_type adds a basic level of validation to arbitrary data
// allowing us to track if data has been discovered and stored or not.
// An empirical_type will be marked as valid only if it has been explicitly assigned to.
-template <typename type_t>
-class empirical_type
+template <typename type_t> class empirical_type
{
public:
// Ctor. Contents is invalid when constructed.
- empirical_type()
- : valid(false)
- {}
+ empirical_type() : valid(false) {}
// Return true and copy contents to out if valid, else return false.
- bool get(type_t& out) const
+ bool
+ get(type_t &out) const
{
if (valid)
out = data;
@@ -64,32 +63,37 @@ public:
}
// Return a pointer to the contents or nullptr if it was not valid.
- const type_t* get() const
+ const type_t *
+ get() const
{
return valid ? &data : nullptr;
}
// Assign data explicitly.
- void set(const type_t in)
+ void
+ set(const type_t in)
{
data = in;
valid = true;
}
// Mark contents as invalid.
- void invalidate()
+ void
+ invalidate()
{
valid = false;
}
// Returns true if this type contains valid data.
- bool isValid() const
+ bool
+ isValid() const
{
return valid;
}
// Assignment operator.
- empirical_type<type_t>& operator = (const type_t in)
+ empirical_type<type_t> &
+ operator=(const type_t in)
{
set(in);
return *this;
@@ -97,7 +101,7 @@ public:
// Dereference operator returns contents.
// Warning: Will assert if not valid so use only when you know data is valid.
- const type_t& operator * () const
+ const type_t &operator*() const
{
assert(valid);
return data;
@@ -108,6 +112,378 @@ protected:
type_t data;
};
+// ArgItem is used by the GetArgs() function when reading function arguments from the target.
+struct ArgItem
+{
+ enum
+ {
+ ePointer,
+ eInt32,
+ eInt64,
+ eLong,
+ eBool
+ } type;
+
+ uint64_t value;
+
+ explicit operator uint64_t() const { return value; }
+};
+
+// Context structure to be passed into GetArgsXXX(), argument reading functions below.
+struct GetArgsCtx
+{
+ RegisterContext *reg_ctx;
+ Process *process;
+};
+
+bool
+GetArgsX86(const GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
+{
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ Error error;
+
+ // get the current stack pointer
+ uint64_t sp = ctx.reg_ctx->GetSP();
+
+ for (size_t i = 0; i < num_args; ++i)
+ {
+ ArgItem &arg = arg_list[i];
+ // advance up the stack by one argument
+ sp += sizeof(uint32_t);
+ // get the argument type size
+ size_t arg_size = sizeof(uint32_t);
+ // read the argument from memory
+ arg.value = 0;
+ Error error;
+ size_t read = ctx.process->ReadMemory(sp, &arg.value, sizeof(uint32_t), error);
+ if (read != arg_size || !error.Success())
+ {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64 " '%s'", __FUNCTION__, uint64_t(i),
+ error.AsCString());
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
+{
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ // number of arguments passed in registers
+ static const uint32_t c_args_in_reg = 6;
+ // register passing order
+ static const std::array<const char *, c_args_in_reg> c_reg_names{{"rdi", "rsi", "rdx", "rcx", "r8", "r9"}};
+ // argument type to size mapping
+ static const std::array<size_t, 5> arg_size{{
+ 8, // ePointer,
+ 4, // eInt32,
+ 8, // eInt64,
+ 8, // eLong,
+ 4, // eBool,
+ }};
+
+ Error error;
+
+ // get the current stack pointer
+ uint64_t sp = ctx.reg_ctx->GetSP();
+ // step over the return address
+ sp += sizeof(uint64_t);
+
+ // check the stack alignment was correct (16 byte aligned)
+ if ((sp & 0xf) != 0x0)
+ {
+ if (log)
+ log->Printf("%s - stack misaligned", __FUNCTION__);
+ return false;
+ }
+
+ // find the start of arguments on the stack
+ uint64_t sp_offset = 0;
+ for (uint32_t i = c_args_in_reg; i < num_args; ++i)
+ {
+ sp_offset += arg_size[arg_list[i].type];
+ }
+ // round up to multiple of 16
+ sp_offset = (sp_offset + 0xf) & 0xf;
+ sp += sp_offset;
+
+ for (size_t i = 0; i < num_args; ++i)
+ {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < c_args_in_reg)
+ {
+ const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoByName(c_reg_names[i]);
+ RegisterValue rVal;
+ if (ctx.reg_ctx->ReadRegister(rArg, rVal))
+ arg.value = rVal.GetAsUInt64(0, &success);
+ }
+ // arguments passed on the stack
+ else
+ {
+ // get the argument type size
+ const size_t size = arg_size[arg_list[i].type];
+ // read the argument from memory
+ arg.value = 0;
+ // note: due to little endian layout reading 4 or 8 bytes will give the correct value.
+ size_t read = ctx.process->ReadMemory(sp, &arg.value, size, error);
+ success = (error.Success() && read==size);
+ // advance past this argument
+ sp -= size;
+ }
+ // 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), error.AsCString("n/a"));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GetArgsArm(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
+{
+ // number of arguments passed in registers
+ static const uint32_t c_args_in_reg = 4;
+
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ Error error;
+
+ // get the current stack pointer
+ uint64_t sp = ctx.reg_ctx->GetSP();
+
+ for (size_t i = 0; i < num_args; ++i)
+ {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < c_args_in_reg)
+ {
+ const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoAtIndex(i);
+ RegisterValue rVal;
+ if (ctx.reg_ctx->ReadRegister(rArg, rVal))
+ arg.value = rVal.GetAsUInt32(0, &success);
+ }
+ // arguments passed on the stack
+ else
+ {
+ // get the argument type size
+ const size_t arg_size = sizeof(uint32_t);
+ // clear all 64bits
+ arg.value = 0;
+ // read this argument from memory
+ size_t bytes_read = ctx.process->ReadMemory(sp, &arg.value, arg_size, error);
+ success = (error.Success() && bytes_read == arg_size);
+ // advance the stack pointer
+ sp += sizeof(uint32_t);
+ }
+ // 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), error.AsCString("n/a"));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GetArgsAarch64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
+{
+ // number of arguments passed in registers
+ static const uint32_t c_args_in_reg = 8;
+
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ for (size_t i = 0; i < num_args; ++i)
+ {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < c_args_in_reg)
+ {
+ const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoAtIndex(i);
+ RegisterValue rVal;
+ if (ctx.reg_ctx->ReadRegister(rArg, rVal))
+ arg.value = rVal.GetAsUInt64(0, &success);
+ }
+ // arguments passed on the stack
+ else
+ {
+ if (log)
+ log->Printf("%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));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GetArgsMipsel(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
+{
+ // number of arguments passed in registers
+ static const uint32_t c_args_in_reg = 4;
+ // register file offset to first argument
+ static const uint32_t c_reg_offset = 4;
+
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ Error error;
+
+ // find offset to arguments on the stack (+16 to skip over a0-a3 shadow space)
+ uint64_t sp = ctx.reg_ctx->GetSP() + 16;
+
+ for (size_t i = 0; i < num_args; ++i)
+ {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < c_args_in_reg)
+ {
+ const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoAtIndex(i + c_reg_offset);
+ RegisterValue rVal;
+ if (ctx.reg_ctx->ReadRegister(rArg, rVal))
+ arg.value = rVal.GetAsUInt64(0, &success);
+ }
+ // arguments passed on the stack
+ else
+ {
+ const size_t arg_size = sizeof(uint32_t);
+ arg.value = 0;
+ size_t bytes_read = ctx.process->ReadMemory(sp, &arg.value, arg_size, error);
+ success = (error.Success() && bytes_read == arg_size);
+ // advance the stack pointer
+ sp += arg_size;
+ }
+ // 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), error.AsCString("n/a"));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GetArgsMips64el(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
+{
+ // number of arguments passed in registers
+ static const uint32_t c_args_in_reg = 8;
+ // register file offset to first argument
+ static const uint32_t c_reg_offset = 4;
+
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ Error error;
+
+ // get the current stack pointer
+ uint64_t sp = ctx.reg_ctx->GetSP();
+
+ for (size_t i = 0; i < num_args; ++i)
+ {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < c_args_in_reg)
+ {
+ const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoAtIndex(i + c_reg_offset);
+ RegisterValue rVal;
+ if (ctx.reg_ctx->ReadRegister(rArg, rVal))
+ arg.value = rVal.GetAsUInt64(0, &success);
+ }
+ // arguments passed on the stack
+ else
+ {
+ // get the argument type size
+ const size_t arg_size = sizeof(uint64_t);
+ // clear all 64bits
+ arg.value = 0;
+ // read this argument from memory
+ size_t bytes_read = ctx.process->ReadMemory(sp, &arg.value, arg_size, error);
+ success = (error.Success() && bytes_read == arg_size);
+ // advance the stack pointer
+ sp += arg_size;
+ }
+ // 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), error.AsCString("n/a"));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GetArgs(ExecutionContext &context, ArgItem *arg_list, size_t num_args)
+{
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ // verify that we have a target
+ if (!context.GetTargetPtr())
+ {
+ if (log)
+ log->Printf("%s - invalid target", __FUNCTION__);
+ return false;
+ }
+
+ GetArgsCtx ctx = {context.GetRegisterContext(), context.GetProcessPtr()};
+ assert(ctx.reg_ctx && ctx.process);
+
+ // dispatch based on architecture
+ switch (context.GetTargetPtr()->GetArchitecture().GetMachine())
+ {
+ case llvm::Triple::ArchType::x86:
+ return GetArgsX86(ctx, arg_list, num_args);
+
+ case llvm::Triple::ArchType::x86_64:
+ return GetArgsX86_64(ctx, arg_list, num_args);
+
+ case llvm::Triple::ArchType::arm:
+ return GetArgsArm(ctx, arg_list, num_args);
+
+ case llvm::Triple::ArchType::aarch64:
+ return GetArgsAarch64(ctx, arg_list, num_args);
+
+ case llvm::Triple::ArchType::mipsel:
+ return GetArgsMipsel(ctx, arg_list, num_args);
+
+ case llvm::Triple::ArchType::mips64el:
+ return GetArgsMips64el(ctx, arg_list, num_args);
+
+ default:
+ // unsupported architecture
+ if (log)
+ {
+ log->Printf("%s - architecture not supported: '%s'", __FUNCTION__,
+ context.GetTargetRef().GetArchitecture().GetArchitectureName());
+ }
+ return false;
+ }
+}
} // anonymous namespace
// The ScriptDetails class collects data associated with a single script instance.
@@ -193,21 +569,23 @@ struct RenderScriptRuntime::Element
RS_TYPE_INVALID = 10000
};
- std::vector<Element> children; // Child Element fields for structs
- empirical_type<lldb::addr_t> element_ptr; // Pointer to the RS Element of the Type
- empirical_type<DataType> type; // Type of each data pointer stored by the allocation
- empirical_type<DataKind> type_kind; // Defines pixel type if Allocation is created from an image
- empirical_type<uint32_t> type_vec_size; // Vector size of each data point, e.g '4' for uchar4
- empirical_type<uint32_t> field_count; // Number of Subelements
- empirical_type<uint32_t> datum_size; // Size of a single Element with padding
- empirical_type<uint32_t> padding; // Number of padding bytes
- empirical_type<uint32_t> array_size; // Number of items in array, only needed for strucrs
- ConstString type_name; // Name of type, only needed for structs
-
- static const ConstString &GetFallbackStructName(); // Print this as the type name of a struct Element
- // If we can't resolve the actual struct name
+ std::vector<Element> children; // Child Element fields for structs
+ empirical_type<lldb::addr_t> element_ptr; // Pointer to the RS Element of the Type
+ empirical_type<DataType> type; // Type of each data pointer stored by the allocation
+ empirical_type<DataKind> type_kind; // Defines pixel type if Allocation is created from an image
+ empirical_type<uint32_t> type_vec_size; // Vector size of each data point, e.g '4' for uchar4
+ empirical_type<uint32_t> field_count; // Number of Subelements
+ empirical_type<uint32_t> datum_size; // Size of a single Element with padding
+ empirical_type<uint32_t> padding; // Number of padding bytes
+ empirical_type<uint32_t> array_size; // Number of items in array, only needed for strucrs
+ ConstString type_name; // Name of type, only needed for structs
+
+ static const ConstString &
+ GetFallbackStructName(); // Print this as the type name of a struct Element
+ // If we can't resolve the actual struct name
- bool shouldRefresh() const
+ bool
+ shouldRefresh() const
{
const bool valid_ptr = element_ptr.isValid() && *element_ptr.get() != 0x0;
const bool valid_type = type.isValid() && type_vec_size.isValid() && type_kind.isValid();
@@ -228,10 +606,10 @@ struct RenderScriptRuntime::AllocationDetails
Dimension()
{
- dim_1 = 0;
- dim_2 = 0;
- dim_3 = 0;
- cubeMap = 0;
+ dim_1 = 0;
+ dim_2 = 0;
+ dim_3 = 0;
+ cubeMap = 0;
}
};
@@ -245,52 +623,51 @@ struct RenderScriptRuntime::AllocationDetails
// These offsets are 4 bytes in size, and the 0 offset signifies no more children.
struct FileHeader
{
- uint8_t ident[4]; // ASCII 'RSAD' identifying the file
- uint32_t dims[3]; // Dimensions
- uint16_t hdr_size; // Header size in bytes, including all element headers
+ uint8_t ident[4]; // ASCII 'RSAD' identifying the file
+ uint32_t dims[3]; // Dimensions
+ uint16_t hdr_size; // Header size in bytes, including all element headers
};
struct ElementHeader
{
- uint16_t type; // DataType enum
- uint32_t kind; // DataKind enum
- uint32_t element_size; // Size of a single element, including padding
- uint16_t vector_size; // Vector width
- uint32_t array_size; // Number of elements in array
+ uint16_t type; // DataType enum
+ uint32_t kind; // DataKind enum
+ uint32_t element_size; // Size of a single element, including padding
+ uint16_t vector_size; // Vector width
+ uint32_t array_size; // Number of elements in array
};
// Monotonically increasing from 1
- static unsigned int ID;
+ static uint32_t ID;
// Maps Allocation DataType enum and vector size to printable strings
// using mapping from RenderScript numerical types summary documentation
- static const char* RsDataTypeToString[][4];
+ static const char *RsDataTypeToString[][4];
// Maps Allocation DataKind enum to printable strings
- static const char* RsDataKindToString[];
+ static const char *RsDataKindToString[];
// Maps allocation types to format sizes for printing.
- static const unsigned int RSTypeToFormat[][3];
+ static const uint32_t RSTypeToFormat[][3];
// Give each allocation an ID as a way
// for commands to reference it.
- const unsigned int id;
+ const uint32_t id;
- RenderScriptRuntime::Element element; // Allocation Element type
- empirical_type<Dimension> dimension; // Dimensions of the Allocation
- empirical_type<lldb::addr_t> address; // Pointer to address of the RS Allocation
- empirical_type<lldb::addr_t> data_ptr; // Pointer to the data held by the Allocation
- empirical_type<lldb::addr_t> type_ptr; // Pointer to the RS Type of the Allocation
- empirical_type<lldb::addr_t> context; // Pointer to the RS Context of the Allocation
- empirical_type<uint32_t> size; // Size of the allocation
- empirical_type<uint32_t> stride; // Stride between rows of the allocation
+ RenderScriptRuntime::Element element; // Allocation Element type
+ empirical_type<Dimension> dimension; // Dimensions of the Allocation
+ empirical_type<lldb::addr_t> address; // Pointer to address of the RS Allocation
+ empirical_type<lldb::addr_t> data_ptr; // Pointer to the data held by the Allocation
+ empirical_type<lldb::addr_t> type_ptr; // Pointer to the RS Type of the Allocation
+ empirical_type<lldb::addr_t> context; // Pointer to the RS Context of the Allocation
+ empirical_type<uint32_t> size; // Size of the allocation
+ empirical_type<uint32_t> stride; // Stride between rows of the allocation
// Give each allocation an id, so we can reference it in user commands.
- AllocationDetails(): id(ID++)
- {
- }
+ AllocationDetails() : id(ID++) {}
- bool shouldRefresh() const
+ bool
+ shouldRefresh() const
{
bool valid_ptrs = data_ptr.isValid() && *data_ptr.get() != 0x0;
valid_ptrs = valid_ptrs && type_ptr.isValid() && *type_ptr.get() != 0x0;
@@ -305,24 +682,15 @@ RenderScriptRuntime::Element::GetFallbackStructName()
return FallbackStructName;
}
-unsigned int RenderScriptRuntime::AllocationDetails::ID = 1;
+uint32_t RenderScriptRuntime::AllocationDetails::ID = 1;
-const char* RenderScriptRuntime::AllocationDetails::RsDataKindToString[] =
-{
- "User",
- "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7
- "Undefined", "Undefined", "Undefined",
- "L Pixel",
- "A Pixel",
- "LA Pixel",
- "RGB Pixel",
- "RGBA Pixel",
- "Pixel Depth",
- "YUV Pixel"
-};
+const char *RenderScriptRuntime::AllocationDetails::RsDataKindToString[] = {
+ "User",
+ "Undefined", "Undefined", "Undefined", "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7
+ "L Pixel", "A Pixel", "LA Pixel", "RGB Pixel",
+ "RGBA Pixel", "Pixel Depth", "YUV Pixel"};
-const char* RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] =
-{
+const char *RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] = {
{"None", "None", "None", "None"},
{"half", "half2", "half3", "half4"},
{"float", "float2", "float3", "float4"},
@@ -356,38 +724,37 @@ const char* RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] =
{"RS Program Vertex", "RS Program Vertex", "RS Program Vertex", "RS Program Vertex"},
{"RS Program Raster", "RS Program Raster", "RS Program Raster", "RS Program Raster"},
{"RS Program Store", "RS Program Store", "RS Program Store", "RS Program Store"},
- {"RS Font", "RS Font", "RS Font", "RS Font"}
-};
+ {"RS Font", "RS Font", "RS Font", "RS Font"}};
// Used as an index into the RSTypeToFormat array elements
-enum TypeToFormatIndex {
- eFormatSingle = 0,
- eFormatVector,
- eElementSize
+enum TypeToFormatIndex
+{
+ eFormatSingle = 0,
+ eFormatVector,
+ eElementSize
};
// { format enum of single element, format enum of element vector, size of element}
-const unsigned int RenderScriptRuntime::AllocationDetails::RSTypeToFormat[][3] =
-{
- {eFormatHex, eFormatHex, 1}, // RS_TYPE_NONE
- {eFormatFloat, eFormatVectorOfFloat16, 2}, // RS_TYPE_FLOAT_16
- {eFormatFloat, eFormatVectorOfFloat32, sizeof(float)}, // RS_TYPE_FLOAT_32
- {eFormatFloat, eFormatVectorOfFloat64, sizeof(double)}, // RS_TYPE_FLOAT_64
- {eFormatDecimal, eFormatVectorOfSInt8, sizeof(int8_t)}, // RS_TYPE_SIGNED_8
- {eFormatDecimal, eFormatVectorOfSInt16, sizeof(int16_t)}, // RS_TYPE_SIGNED_16
- {eFormatDecimal, eFormatVectorOfSInt32, sizeof(int32_t)}, // RS_TYPE_SIGNED_32
- {eFormatDecimal, eFormatVectorOfSInt64, sizeof(int64_t)}, // RS_TYPE_SIGNED_64
- {eFormatDecimal, eFormatVectorOfUInt8, sizeof(uint8_t)}, // RS_TYPE_UNSIGNED_8
- {eFormatDecimal, eFormatVectorOfUInt16, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_16
- {eFormatDecimal, eFormatVectorOfUInt32, sizeof(uint32_t)}, // RS_TYPE_UNSIGNED_32
- {eFormatDecimal, eFormatVectorOfUInt64, sizeof(uint64_t)}, // RS_TYPE_UNSIGNED_64
- {eFormatBoolean, eFormatBoolean, 1}, // RS_TYPE_BOOL
- {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_5_6_5
- {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_5_5_5_1
- {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_4_4_4_4
+const uint32_t RenderScriptRuntime::AllocationDetails::RSTypeToFormat[][3] = {
+ {eFormatHex, eFormatHex, 1}, // RS_TYPE_NONE
+ {eFormatFloat, eFormatVectorOfFloat16, 2}, // RS_TYPE_FLOAT_16
+ {eFormatFloat, eFormatVectorOfFloat32, sizeof(float)}, // RS_TYPE_FLOAT_32
+ {eFormatFloat, eFormatVectorOfFloat64, sizeof(double)}, // RS_TYPE_FLOAT_64
+ {eFormatDecimal, eFormatVectorOfSInt8, sizeof(int8_t)}, // RS_TYPE_SIGNED_8
+ {eFormatDecimal, eFormatVectorOfSInt16, sizeof(int16_t)}, // RS_TYPE_SIGNED_16
+ {eFormatDecimal, eFormatVectorOfSInt32, sizeof(int32_t)}, // RS_TYPE_SIGNED_32
+ {eFormatDecimal, eFormatVectorOfSInt64, sizeof(int64_t)}, // RS_TYPE_SIGNED_64
+ {eFormatDecimal, eFormatVectorOfUInt8, sizeof(uint8_t)}, // RS_TYPE_UNSIGNED_8
+ {eFormatDecimal, eFormatVectorOfUInt16, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_16
+ {eFormatDecimal, eFormatVectorOfUInt32, sizeof(uint32_t)}, // RS_TYPE_UNSIGNED_32
+ {eFormatDecimal, eFormatVectorOfUInt64, sizeof(uint64_t)}, // RS_TYPE_UNSIGNED_64
+ {eFormatBoolean, eFormatBoolean, 1}, // RS_TYPE_BOOL
+ {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_5_6_5
+ {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_5_5_5_1
+ {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_4_4_4_4
{eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 16}, // RS_TYPE_MATRIX_4X4
- {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 9}, // RS_TYPE_MATRIX_3X3
- {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 4} // RS_TYPE_MATRIX_2X2
+ {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 9}, // RS_TYPE_MATRIX_3X3
+ {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 4} // RS_TYPE_MATRIX_2X2
};
//------------------------------------------------------------------
@@ -400,7 +767,7 @@ RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType languag
if (language == eLanguageTypeExtRenderScript)
return new RenderScriptRuntime(process);
else
- return NULL;
+ return nullptr;
}
// Callback with a module to search for matching symbols.
@@ -408,10 +775,7 @@ RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType languag
// Then look for a symbol which matches our kernel name.
// The breakpoint address is finally set using the address of this symbol.
Searcher::CallbackReturn
-RSBreakpointResolver::SearchCallback(SearchFilter &filter,
- SymbolContext &context,
- Address*,
- bool)
+RSBreakpointResolver::SearchCallback(SearchFilter &filter, SymbolContext &context, Address *, bool)
{
ModuleSP module = context.module_sp;
@@ -426,7 +790,7 @@ RSBreakpointResolver::SearchCallback(SearchFilter &filter,
// If it's not found, it's likely debug info is unavailable - try to set a
// breakpoint on <name>.expand.
- const Symbol* kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
+ const Symbol *kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
if (!kernel_sym)
{
std::string kernel_name_expanded(m_kernel_name.AsCString());
@@ -447,7 +811,8 @@ RSBreakpointResolver::SearchCallback(SearchFilter &filter,
void
RenderScriptRuntime::Initialize()
{
- PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject);
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance,
+ GetCommandObject);
}
void
@@ -493,7 +858,6 @@ RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp)
{
return eModuleKindImpl;
}
-
}
return eModuleKindIgnored;
}
@@ -505,15 +869,15 @@ RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp)
}
void
-RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list )
+RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list)
{
- Mutex::Locker locker (module_list.GetMutex ());
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
size_t num_modules = module_list.GetSize();
for (size_t i = 0; i < num_modules; i++)
{
- auto mod = module_list.GetModuleAtIndex (i);
- if (IsRenderScriptModule (mod))
+ auto mod = module_list.GetModuleAtIndex(i);
+ if (IsRenderScriptModule(mod))
{
LoadModule(mod);
}
@@ -550,8 +914,7 @@ RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::Dynam
}
TypeAndOrName
-RenderScriptRuntime::FixUpDynamicType (const TypeAndOrName& type_and_or_name,
- ValueObject& static_value)
+RenderScriptRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value)
{
return type_and_or_name;
}
@@ -569,86 +932,71 @@ RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bo
return resolver_sp;
}
-const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] =
-{
- //rsdScript
- {
- "rsdScriptInit", //name
- "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", // symbol name 32 bit
- "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj", // symbol name 64 bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- &lldb_private::RenderScriptRuntime::CaptureScriptInit1 // handler
- },
- {
- "rsdScriptInvokeForEach", // name
- "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvjPK12RsScriptCall", // symbol name 32bit
- "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvmPK12RsScriptCall", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- nullptr // handler
- },
+const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] = {
+ // rsdScript
{
- "rsdScriptInvokeForEachMulti", // name
- "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", // symbol name 32bit
- "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- nullptr // handler
+ "rsdScriptInit",
+ "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj",
+ "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj",
+ 0,
+ RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureScriptInit
},
{
- "rsdScriptInvokeFunction", // name
- "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvj", // symbol name 32bit
- "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvm", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- nullptr // handler
+ "rsdScriptInvokeForEachMulti",
+ "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall",
+ "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall",
+ 0,
+ RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureScriptInvokeForEachMulti
},
{
- "rsdScriptSetGlobalVar", // name
- "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", // symbol name 32bit
- "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1 // handler
+ "rsdScriptSetGlobalVar",
+ "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj",
+ "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm",
+ 0,
+ RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar
},
- //rsdAllocation
+ // rsdAllocation
{
- "rsdAllocationInit", // name
- "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 32bit
- "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- &lldb_private::RenderScriptRuntime::CaptureAllocationInit1 // handler
+ "rsdAllocationInit",
+ "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb",
+ "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb",
+ 0,
+ RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureAllocationInit
},
{
- "rsdAllocationRead2D", //name
- "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", // symbol name 32bit
- "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- nullptr // handler
+ "rsdAllocationRead2D",
+ "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj",
+ "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm",
+ 0,
+ RenderScriptRuntime::eModuleKindDriver,
+ nullptr
},
{
- "rsdAllocationDestroy", // name
- "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_10AllocationE", // symbol name 32bit
- "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_10AllocationE", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- &lldb_private::RenderScriptRuntime::CaptureAllocationDestroy // handler
+ "rsdAllocationDestroy",
+ "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_10AllocationE",
+ "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_10AllocationE",
+ 0,
+ RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureAllocationDestroy
},
};
-const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]);
+const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns) / sizeof(s_runtimeHookDefns[0]);
bool
-RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
+RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id)
{
- RuntimeHook* hook_info = (RuntimeHook*)baton;
+ RuntimeHook *hook_info = (RuntimeHook *)baton;
ExecutionContext context(ctx->exe_ctx_ref);
- RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
+ RenderScriptRuntime *lang_rt =
+ (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
lang_rt->HookCallback(hook_info, context);
@@ -656,12 +1004,12 @@ RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, ll
}
void
-RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context)
+RenderScriptRuntime::HookCallback(RuntimeHook *hook_info, ExecutionContext &context)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (log)
- log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name);
+ log->Printf("%s - '%s'", __FUNCTION__, hook_info->defn->name);
if (hook_info->defn->grabber)
{
@@ -669,435 +1017,320 @@ RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& cont
}
}
-bool
-RenderScriptRuntime::GetArgSimple(ExecutionContext &context, uint32_t arg, uint64_t *data)
-{
- // Get a positional integer argument.
- // Given an ExecutionContext, ``context`` which should be a RenderScript
- // frame, get the value of the positional argument ``arg`` and save its value
- // to the address pointed to by ``data``.
- // returns true on success, false otherwise.
- // If unsuccessful, the value pointed to by ``data`` is undefined. Otherwise,
- // ``data`` will be set to the value of the the given ``arg``.
- // NOTE: only natural width integer arguments for the machine are supported.
- // Behaviour with non primitive arguments is undefined.
-
- if (!data)
- return false;
-
+void
+RenderScriptRuntime::CaptureScriptInvokeForEachMulti(RuntimeHook* hook_info,
+ ExecutionContext& context)
+{
Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- Error error;
- RegisterContext* reg_ctx = context.GetRegisterContext();
- Process* process = context.GetProcessPtr();
- bool success = false; // return value
- if (!context.GetTargetPtr())
+ enum
+ {
+ eRsContext = 0,
+ eRsScript,
+ eRsSlot,
+ eRsAIns,
+ eRsInLen,
+ eRsAOut,
+ eRsUsr,
+ eRsUsrLen,
+ eRsSc,
+ };
+
+ std::array<ArgItem, 9> args{{
+ ArgItem{ArgItem::ePointer, 0}, // const Context *rsc
+ ArgItem{ArgItem::ePointer, 0}, // Script *s
+ ArgItem{ArgItem::eInt32, 0}, // uint32_t slot
+ ArgItem{ArgItem::ePointer, 0}, // const Allocation **aIns
+ ArgItem{ArgItem::eInt32, 0}, // size_t inLen
+ ArgItem{ArgItem::ePointer, 0}, // Allocation *aout
+ ArgItem{ArgItem::ePointer, 0}, // const void *usr
+ ArgItem{ArgItem::eInt32, 0}, // size_t usrLen
+ ArgItem{ArgItem::ePointer, 0}, // const RsScriptCall *sc
+ }};
+
+ bool success = GetArgs(context, &args[0], args.size());
+ if (!success)
{
if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - Invalid target");
-
- return false;
+ log->Printf("%s - Error while reading the function parameters", __FUNCTION__);
+ return;
}
- switch (context.GetTargetPtr()->GetArchitecture().GetMachine())
+ const uint32_t target_ptr_size = m_process->GetAddressByteSize();
+ Error error;
+ std::vector<uint64_t> allocs;
+
+ // traverse allocation list
+ for (uint64_t i = 0; i < uint64_t(args[eRsInLen]); ++i)
{
- case llvm::Triple::ArchType::x86:
- {
- uint64_t sp = reg_ctx->GetSP();
- uint32_t offset = (1 + arg) * sizeof(uint32_t);
- uint32_t result = 0;
- process->ReadMemory(sp + offset, &result, sizeof(uint32_t), error);
- if (error.Fail())
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - error reading X86 stack: %s.", error.AsCString());
- }
- else
- {
- *data = result;
- success = true;
- }
- break;
- }
- case llvm::Triple::ArchType::x86_64:
+ // calculate offest to allocation pointer
+ const addr_t addr = addr_t(args[eRsAIns]) + i * target_ptr_size;
+
+ // Note: due to little endian layout, reading 32bits or 64bits into res64 will
+ // give the correct results.
+
+ uint64_t res64 = 0;
+ size_t read = m_process->ReadMemory(addr, &res64, target_ptr_size, error);
+ if (read != target_ptr_size || !error.Success())
{
- // amd64 has 6 integer registers, and 8 XMM registers for parameter passing.
- // Surplus args are spilled onto the stack.
- // rdi, rsi, rdx, rcx, r8, r9, (zmm0 - 7 for vectors)
- // ref: AMD64 ABI Draft 0.99.6 – October 7, 2013 – 10:35; Figure 3.4. Retrieved from
- // http://www.x86-64.org/documentation/abi.pdf
- if (arg > 5)
- {
- if (log)
- log->Warning("X86_64 register spill is not supported.");
- break;
- }
- const char * regnames[] = {"rdi", "rsi", "rdx", "rcx", "r8", "r9"};
- assert((sizeof(regnames) / sizeof(const char *)) > arg);
- const RegisterInfo *rArg = reg_ctx->GetRegisterInfoByName(regnames[arg]);
- RegisterValue rVal;
- success = reg_ctx->ReadRegister(rArg, rVal);
- if (success)
- {
- *data = rVal.GetAsUInt64(0u, &success);
- }
- else
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - error reading x86_64 register: %d.", arg);
- }
- break;
+ if (log)
+ log->Printf("%s - Error while reading allocation list argument %" PRIu64, __FUNCTION__, i);
}
- case llvm::Triple::ArchType::arm:
+ else
{
- // arm 32 bit
- // first 4 arguments are passed via registers
- if (arg < 4)
- {
- const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
- RegisterValue rVal;
- success = reg_ctx->ReadRegister(rArg, rVal);
- if (success)
- {
- (*data) = rVal.GetAsUInt32(0u, &success);
- }
- else
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - error reading ARM register: %d.", arg);
- }
- }
- else
- {
- uint64_t sp = reg_ctx->GetSP();
- uint32_t offset = (arg-4) * sizeof(uint32_t);
- uint32_t value = 0;
- size_t bytes_read = process->ReadMemory(sp + offset, &value, sizeof(value), error);
- if (error.Fail() || bytes_read != sizeof(value))
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - error reading ARM stack: %s.", error.AsCString());
- }
- else
- {
- *data = value;
- success = true;
- }
- }
- break;
+ allocs.push_back(res64);
}
- case llvm::Triple::ArchType::aarch64:
+ }
+
+ // if there is an output allocation track it
+ if (uint64_t aOut = uint64_t(args[eRsAOut]))
+ {
+ allocs.push_back(aOut);
+ }
+
+ // for all allocations we have found
+ for (const uint64_t alloc_addr : allocs)
+ {
+ AllocationDetails* alloc = LookUpAllocation(alloc_addr, true);
+ if (alloc)
{
- // arm 64 bit
- // first 8 arguments are in the registers
- if (arg < 8)
+ // save the allocation address
+ if (alloc->address.isValid())
{
- const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
- RegisterValue rVal;
- success = reg_ctx->ReadRegister(rArg, rVal);
- if (success)
- {
- *data = rVal.GetAsUInt64(0u, &success);
- }
- else
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple() - AARCH64 - Error while reading the argument #%d", arg);
- }
+ // check the allocation address we already have matches
+ assert(*alloc->address.get() == alloc_addr);
}
else
{
- // @TODO: need to find the argument in the stack
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - AARCH64 - FOR #ARG >= 8 NOT IMPLEMENTED YET. Argument number: %d", arg);
- }
- break;
- }
- case llvm::Triple::ArchType::mipsel:
- {
- // read from the registers
- // first 4 arguments are passed in registers
- if (arg < 4){
- const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg + 4);
- RegisterValue rVal;
- success = reg_ctx->ReadRegister(rArg, rVal);
- if (success)
- {
- *data = rVal.GetAsUInt64(0u, &success);
- }
- else
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple() - Mips - Error while reading the argument #%d", arg);
- }
- }
- // arguments > 4 are read from the stack
- else
- {
- uint64_t sp = reg_ctx->GetSP();
- uint32_t offset = arg * sizeof(uint32_t);
- uint32_t value = 0;
- size_t bytes_read = process->ReadMemory(sp + offset, &value, sizeof(value), error);
- if (error.Fail() || bytes_read != sizeof(value))
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - error reading Mips stack: %s.", error.AsCString());
- }
- else
- {
- *data = value;
- success = true;
- }
- }
- break;
- }
- case llvm::Triple::ArchType::mips64el:
- {
- // read from the registers
- if (arg < 8)
- {
- const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg + 4);
- RegisterValue rVal;
- success = reg_ctx->ReadRegister(rArg, rVal);
- if (success)
- {
- (*data) = rVal.GetAsUInt64(0u, &success);
- }
- else
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - Mips64 - Error reading the argument #%d", arg);
- }
+ alloc->address = alloc_addr;
}
- // arguments > 8 are read from the stack
- else
+
+ // save the context
+ if (log)
{
- uint64_t sp = reg_ctx->GetSP();
- uint32_t offset = (arg - 8) * sizeof(uint64_t);
- uint64_t value = 0;
- size_t bytes_read = process->ReadMemory(sp + offset, &value, sizeof(value), error);
- if (error.Fail() || bytes_read != sizeof(value))
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - Mips64 - Error reading Mips64 stack: %s.", error.AsCString());
- }
- else
- {
- *data = value;
- success = true;
- }
+ if (alloc->context.isValid() && *alloc->context.get() != addr_t(args[eRsContext]))
+ log->Printf("%s - Allocation used by multiple contexts", __FUNCTION__);
}
- break;
- }
- default:
- {
- // invalid architecture
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - Architecture not supported");
+ alloc->context = addr_t(args[eRsContext]);
}
}
- if (!success)
+ // make sure we track this script object
+ if (lldb_private::RenderScriptRuntime::ScriptDetails *script = LookUpScript(addr_t(args[eRsScript]), true))
{
if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - failed to get argument at index %" PRIu32, arg);
+ {
+ if (script->context.isValid() && *script->context.get() != addr_t(args[eRsContext]))
+ log->Printf("%s - Script used by multiple contexts", __FUNCTION__);
+ }
+ script->context = addr_t(args[eRsContext]);
}
- return success;
}
void
-RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context)
+RenderScriptRuntime::CaptureSetGlobalVar(RuntimeHook *hook_info, ExecutionContext &context)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- //Context, Script, int, data, length
-
- uint64_t rs_context_u64 = 0U;
- uint64_t rs_script_u64 = 0U;
- uint64_t rs_id_u64 = 0U;
- uint64_t rs_data_u64 = 0U;
- uint64_t rs_length_u64 = 0U;
+ enum
+ {
+ eRsContext,
+ eRsScript,
+ eRsId,
+ eRsData,
+ eRsLength,
+ };
- bool success =
- GetArgSimple(context, 0, &rs_context_u64) &&
- GetArgSimple(context, 1, &rs_script_u64) &&
- GetArgSimple(context, 2, &rs_id_u64) &&
- GetArgSimple(context, 3, &rs_data_u64) &&
- GetArgSimple(context, 4, &rs_length_u64);
+ std::array<ArgItem, 5> args{{
+ ArgItem{ArgItem::ePointer, 0}, // eRsContext
+ ArgItem{ArgItem::ePointer, 0}, // eRsScript
+ ArgItem{ArgItem::eInt32, 0}, // eRsId
+ ArgItem{ArgItem::ePointer, 0}, // eRsData
+ ArgItem{ArgItem::eInt32, 0}, // eRsLength
+ }};
+ bool success = GetArgs(context, &args[0], args.size());
if (!success)
{
if (log)
- log->Printf("RenderScriptRuntime::CaptureSetGlobalVar1 - Error while reading the function parameters");
+ log->Printf("%s - error reading the function parameters.", __FUNCTION__);
return;
}
if (log)
{
- log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.",
- rs_context_u64, rs_script_u64, rs_id_u64, rs_data_u64, rs_length_u64);
+ 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]));
- addr_t script_addr = (addr_t)rs_script_u64;
- if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end())
+ addr_t script_addr = addr_t(args[eRsScript]);
+ if (m_scriptMappings.find(script_addr) != m_scriptMappings.end())
{
auto rsm = m_scriptMappings[script_addr];
- if (rs_id_u64 < rsm->m_globals.size())
+ if (uint64_t(args[eRsId]) < rsm->m_globals.size())
{
- auto rsg = rsm->m_globals[rs_id_u64];
- log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(),
- rsm->m_module->GetFileSpec().GetFilename().AsCString());
+ 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());
}
}
}
}
void
-RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context)
+RenderScriptRuntime::CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- //Context, Alloc, bool
+ enum
+ {
+ eRsContext,
+ eRsAlloc,
+ eRsForceZero
+ };
- uint64_t rs_context_u64 = 0U;
- uint64_t rs_alloc_u64 = 0U;
- uint64_t rs_forceZero_u64 = 0U;
+ std::array<ArgItem, 3> args{{
+ ArgItem{ArgItem::ePointer, 0}, // eRsContext
+ ArgItem{ArgItem::ePointer, 0}, // eRsAlloc
+ ArgItem{ArgItem::eBool, 0}, // eRsForceZero
+ }};
- bool success =
- GetArgSimple(context, 0, &rs_context_u64) &&
- GetArgSimple(context, 1, &rs_alloc_u64) &&
- GetArgSimple(context, 2, &rs_forceZero_u64);
+ bool success = GetArgs(context, &args[0], args.size());
if (!success) // error case
{
if (log)
- log->Printf("RenderScriptRuntime::CaptureAllocationInit1 - Error while reading the function parameters");
+ log->Printf("%s - error while reading the function parameters", __FUNCTION__);
return; // abort
}
if (log)
- log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
- rs_context_u64, rs_alloc_u64, rs_forceZero_u64);
+ log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .", __FUNCTION__, uint64_t(args[eRsContext]),
+ uint64_t(args[eRsAlloc]), uint64_t(args[eRsForceZero]));
- AllocationDetails* alloc = LookUpAllocation(rs_alloc_u64, true);
+ AllocationDetails *alloc = LookUpAllocation(uint64_t(args[eRsAlloc]), true);
if (alloc)
- alloc->context = rs_context_u64;
+ alloc->context = uint64_t(args[eRsContext]);
}
void
-RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook* hook_info, ExecutionContext& context)
+RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook *hook_info, ExecutionContext &context)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- // Context, Alloc
- uint64_t rs_context_u64 = 0U;
- uint64_t rs_alloc_u64 = 0U;
+ enum
+ {
+ eRsContext,
+ eRsAlloc,
+ };
- bool success = GetArgSimple(context, 0, &rs_context_u64) && GetArgSimple(context, 1, &rs_alloc_u64);
- if (!success) // error case
+ std::array<ArgItem, 2> args{{
+ ArgItem{ArgItem::ePointer, 0}, // eRsContext
+ ArgItem{ArgItem::ePointer, 0}, // eRsAlloc
+ }};
+
+ bool success = GetArgs(context, &args[0], args.size());
+ if (!success)
{
if (log)
- log->Printf("RenderScriptRuntime::CaptureAllocationDestroy - Error while reading the function parameters");
- return; // abort
+ log->Printf("%s - error while reading the function parameters.", __FUNCTION__);
+ return;
}
if (log)
- log->Printf("RenderScriptRuntime::CaptureAllocationDestroy - 0x%" PRIx64 ", 0x%" PRIx64 ".",
- rs_context_u64, rs_alloc_u64);
+ log->Printf("%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_ap = *iter; // get the unique pointer
- if (allocation_ap->address.isValid() && *allocation_ap->address.get() == rs_alloc_u64)
+ auto &allocation_ap = *iter; // get the unique pointer
+ if (allocation_ap->address.isValid() && *allocation_ap->address.get() == addr_t(args[eRsAlloc]))
{
m_allocations.erase(iter);
if (log)
- log->Printf("RenderScriptRuntime::CaptureAllocationDestroy - Deleted allocation entry");
+ log->Printf("%s - deleted allocation entry.", __FUNCTION__);
return;
}
}
if (log)
- log->Printf("RenderScriptRuntime::CaptureAllocationDestroy - Couldn't find destroyed allocation");
+ log->Printf("%s - couldn't find destroyed allocation.", __FUNCTION__);
}
void
-RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context)
+RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- //Context, Script, resname Str, cachedir Str
Error error;
- Process* process = context.GetProcessPtr();
-
- uint64_t rs_context_u64 = 0U;
- uint64_t rs_script_u64 = 0U;
- uint64_t rs_resnameptr_u64 = 0U;
- uint64_t rs_cachedirptr_u64 = 0U;
-
- std::string resname;
- std::string cachedir;
+ Process *process = context.GetProcessPtr();
- // read the function parameters
- bool success =
- GetArgSimple(context, 0, &rs_context_u64) &&
- GetArgSimple(context, 1, &rs_script_u64) &&
- GetArgSimple(context, 2, &rs_resnameptr_u64) &&
- GetArgSimple(context, 3, &rs_cachedirptr_u64);
+ enum
+ {
+ eRsContext,
+ eRsScript,
+ eRsResNamePtr,
+ eRsCachedDirPtr
+ };
+ std::array<ArgItem, 4> args{{ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0},
+ ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0}}};
+ bool success = GetArgs(context, &args[0], args.size());
if (!success)
{
if (log)
- log->Printf("RenderScriptRuntime::CaptureScriptInit1 - Error while reading the function parameters");
+ log->Printf("%s - error while reading the function parameters.", __FUNCTION__);
return;
}
- process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u64, resname, error);
+ std::string resname;
+ process->ReadCStringFromMemory(addr_t(args[eRsResNamePtr]), resname, error);
if (error.Fail())
{
if (log)
- log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString());
-
+ log->Printf("%s - error reading resname: %s.", __FUNCTION__, error.AsCString());
}
- process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u64, cachedir, error);
+ std::string cachedir;
+ process->ReadCStringFromMemory(addr_t(args[eRsCachedDirPtr]), cachedir, error);
if (error.Fail())
{
if (log)
- log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString());
+ log->Printf("%s - error reading cachedir: %s.", __FUNCTION__, error.AsCString());
}
if (log)
- log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
- rs_context_u64, rs_script_u64, resname.c_str(), cachedir.c_str());
+ log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .", __FUNCTION__, uint64_t(args[eRsContext]),
+ uint64_t(args[eRsScript]), resname.c_str(), cachedir.c_str());
if (resname.size() > 0)
{
StreamString strm;
strm.Printf("librs.%s.so", resname.c_str());
- ScriptDetails* script = LookUpScript(rs_script_u64, true);
+ ScriptDetails *script = LookUpScript(addr_t(args[eRsScript]), true);
if (script)
{
script->type = ScriptDetails::eScriptC;
script->cacheDir = cachedir;
script->resName = resname;
script->scriptDyLib = strm.GetData();
- script->context = addr_t(rs_context_u64);
+ script->context = addr_t(args[eRsContext]);
}
if (log)
- log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".",
- strm.GetData(), rs_context_u64, rs_script_u64);
+ log->Printf("%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 ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged");
+ log->Printf("%s - resource name invalid, Script not tagged.", __FUNCTION__);
}
}
void
RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!module)
{
@@ -1107,17 +1340,15 @@ RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
Target &target = GetProcess()->GetTarget();
llvm::Triple::ArchType targetArchType = target.GetArchitecture().GetMachine();
- if (targetArchType != llvm::Triple::ArchType::x86
- && targetArchType != llvm::Triple::ArchType::arm
- && targetArchType != llvm::Triple::ArchType::aarch64
- && targetArchType != llvm::Triple::ArchType::mipsel
- && targetArchType != llvm::Triple::ArchType::mips64el
- && targetArchType != llvm::Triple::ArchType::x86_64
- )
+ if (targetArchType != llvm::Triple::ArchType::x86 &&
+ targetArchType != llvm::Triple::ArchType::arm &&
+ targetArchType != llvm::Triple::ArchType::aarch64 &&
+ targetArchType != llvm::Triple::ArchType::mipsel &&
+ targetArchType != llvm::Triple::ArchType::mips64el &&
+ targetArchType != llvm::Triple::ArchType::x86_64)
{
if (log)
- log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM, Mips supported currently.");
-
+ log->Printf("%s - unable to hook runtime functions.", __FUNCTION__);
return;
}
@@ -1125,17 +1356,21 @@ RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
for (size_t idx = 0; idx < s_runtimeHookCount; idx++)
{
- const HookDefn* hook_defn = &s_runtimeHookDefns[idx];
- if (hook_defn->kind != kind) {
+ const HookDefn *hook_defn = &s_runtimeHookDefns[idx];
+ if (hook_defn->kind != kind)
+ {
continue;
}
- const char* symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64;
+ const char *symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64;
const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(symbol_name), eSymbolTypeCode);
- if (!sym){
- if (log){
- log->Printf("RenderScriptRuntime::LoadRuntimeHooks - ERROR: Symbol '%s' related to the function %s not found", symbol_name, hook_defn->name);
+ if (!sym)
+ {
+ if (log)
+ {
+ log->Printf("%s - symbol '%s' related to the function %s not found",
+ __FUNCTION__, symbol_name, hook_defn->name);
}
continue;
}
@@ -1144,14 +1379,15 @@ RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
if (addr == LLDB_INVALID_ADDRESS)
{
if (log)
- log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.",
- hook_defn->name, symbol_name);
+ log->Printf("%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("RenderScriptRuntime::LoadRuntimeHooks - Function %s, address resolved at 0x%" PRIx64, hook_defn->name, addr);
+ log->Printf("%s - function %s, address resolved at 0x%" PRIx64,
+ __FUNCTION__, hook_defn->name, addr);
}
RuntimeHookSP hook(new RuntimeHook());
@@ -1162,8 +1398,9 @@ RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
m_runtimeHooks[addr] = hook;
if (log)
{
- log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".",
- hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr);
+ 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);
}
}
}
@@ -1174,14 +1411,14 @@ RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
if (!rsmodule_sp)
return;
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
const ModuleSP module = rsmodule_sp->m_module;
- const FileSpec& file = module->GetPlatformFileSpec();
+ const FileSpec &file = module->GetPlatformFileSpec();
// Iterate over all of the scripts that we currently know of.
// Note: We cant push or pop to m_scripts here or it may invalidate rs_script.
- for (const auto & rs_script : m_scripts)
+ for (const auto &rs_script : m_scripts)
{
// Extract the expected .so file path for this script.
std::string dylib;
@@ -1204,8 +1441,8 @@ RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
if (m_scriptMappings[script] != rsmodule_sp)
{
if (log)
- log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
- (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
+ log->Printf("%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.
@@ -1219,8 +1456,8 @@ RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
// Add Script/Module pair to map.
m_scriptMappings[script] = rsmodule_sp;
if (log)
- log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.",
- (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
+ log->Printf("%s - script %" PRIx64 " associated with rsmodule '%s'.", __FUNCTION__,
+ (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
}
}
}
@@ -1229,21 +1466,23 @@ RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
// The result of that expression is returned an unsigned 64 bit int, via the result* paramter.
// Function returns true on success, and false on failure
bool
-RenderScriptRuntime::EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result)
+RenderScriptRuntime::EvalRSExpression(const char *expression, StackFrame *frame_ptr, uint64_t *result)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (log)
- log->Printf("RenderScriptRuntime::EvalRSExpression(%s)", expression);
+ log->Printf("%s(%s)", __FUNCTION__, expression);
ValueObjectSP expr_result;
+ EvaluateExpressionOptions options;
+ options.SetLanguage(lldb::eLanguageTypeC_plus_plus);
// Perform the actual expression evaluation
- GetProcess()->GetTarget().EvaluateExpression(expression, frame_ptr, expr_result);
+ GetProcess()->GetTarget().EvaluateExpression(expression, frame_ptr, expr_result, options);
if (!expr_result)
{
- if (log)
- log->Printf("RenderScriptRuntime::EvalRSExpression - Error: Couldn't evaluate expression");
- return false;
+ if (log)
+ log->Printf("%s: couldn't evaluate expression.", __FUNCTION__);
+ return false;
}
// The result of the expression is invalid
@@ -1253,159 +1492,104 @@ RenderScriptRuntime::EvalRSExpression(const char* expression, StackFrame* frame_
if (err.GetError() == UserExpression::kNoResult) // Expression returned void, so this is actually a success
{
if (log)
- log->Printf("RenderScriptRuntime::EvalRSExpression - Expression returned void");
+ log->Printf("%s - expression returned void.", __FUNCTION__);
result = nullptr;
return true;
}
if (log)
- log->Printf("RenderScriptRuntime::EvalRSExpression - Error evaluating expression result: %s", err.AsCString());
+ log->Printf("%s - error evaluating expression result: %s", __FUNCTION__,
+ err.AsCString());
return false;
}
bool success = false;
- *result = expr_result->GetValueAsUnsigned(0, &success); // We only read the result as an unsigned int.
+ *result = expr_result->GetValueAsUnsigned(0, &success); // We only read the result as an uint32_t.
if (!success)
{
- if (log)
- log->Printf("RenderScriptRuntime::EvalRSExpression - Error: Couldn't convert expression result to unsigned int");
- return false;
+ if (log)
+ log->Printf("%s - couldn't convert expression result to uint32_t", __FUNCTION__);
+ return false;
}
return true;
}
-namespace // anonymous
+namespace
+{
+// Used to index expression format strings
+enum ExpressionStrings
{
- // max length of an expanded expression
- const int jit_max_expr_size = 768;
+ eExprGetOffsetPtr = 0,
+ eExprAllocGetType,
+ eExprTypeDimX,
+ eExprTypeDimY,
+ eExprTypeDimZ,
+ eExprTypeElemPtr,
+ eExprElementType,
+ eExprElementKind,
+ eExprElementVec,
+ eExprElementFieldCount,
+ eExprSubelementsId,
+ eExprSubelementsName,
+ eExprSubelementsArrSize,
+
+ _eExprLast // keep at the end, implicit size of the array runtimeExpressions
+};
+
+// max length of an expanded expression
+const int jit_max_expr_size = 512;
+// Retrieve the string to JIT for the given expression
+const char*
+JITTemplate(ExpressionStrings e)
+{
// Format strings containing the expressions we may need to evaluate.
- const char runtimeExpressions[][256] =
- {
+ static std::array<const char*, _eExprLast> runtimeExpressions = {{
// Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap)
- "(int*)_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace(0x%lx, %u, %u, %u, 0, 0)",
+ "(int*)_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace"
+ "(0x%" PRIx64 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", 0, 0)",
// Type* rsaAllocationGetType(Context*, Allocation*)
- "(void*)rsaAllocationGetType(0x%lx, 0x%lx)",
+ "(void*)rsaAllocationGetType(0x%" PRIx64 ", 0x%" PRIx64 ")",
// rsaTypeGetNativeData(Context*, Type*, void* typeData, size)
// Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
// mHal.state.lodCount; mHal.state.faces; mElement; into typeData
// Need to specify 32 or 64 bit for uint_t since this differs between devices
- "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[0]", // X dim
- "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[1]", // Y dim
- "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[2]", // Z dim
- "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[5]", // Element ptr
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 6); data[0]", // X dim
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 6); data[1]", // Y dim
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 6); data[2]", // Z dim
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 6); data[5]", // Element ptr
// rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
// Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[0]", // Type
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[1]", // Kind
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[3]", // Vector Size
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[4]", // Field Count
-
- // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t *ids, const char **names,
- // size_t *arraySizes, uint32_t dataSize)
- // Needed for Allocations of structs to gather details about fields/Subelements
- "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
- "(void*)rsaElementGetSubElements(0x%lx, 0x%lx, ids, names, arr_size, %u); ids[%u]", // Element* of field
-
- "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
- "(void*)rsaElementGetSubElements(0x%lx, 0x%lx, ids, names, arr_size, %u); names[%u]", // Name of field
-
- "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
- "(void*)rsaElementGetSubElements(0x%lx, 0x%lx, ids, names, arr_size, %u); arr_size[%u]" // Array size of field
- };
-
-
- // Temporary workaround for MIPS, until the compiler emits the JAL instruction when invoking directly the function.
- // At the moment, when evaluating an expression involving a function call, the LLVM codegen for Mips emits a JAL
- // instruction, which is able to jump in the range +/- 128MB with respect to the current program counter ($pc). If
- // the requested function happens to reside outside the above region, the function address will be truncated and the
- // function invocation will fail. This is a problem in the RS plugin as we rely on the RS API to probe the number and
- // the nature of allocations. A proper solution in the MIPS compiler is currently being investigated. As temporary
- // work around for this context, we'll invoke the RS API through function pointers, which cause the compiler to emit a
- // register based JALR instruction.
- const char runtimeExpressions_mips[][512] =
- {
- // Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap)
- "int* (*f) (void*, int, int, int, int, int) = (int* (*) (void*, int, int, int, int, int)) "
- "_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace; "
- "(int*) f((void*) 0x%lx, %u, %u, %u, 0, 0)",
-
- // Type* rsaAllocationGetType(Context*, Allocation*)
- "void* (*f) (void*, void*) = (void* (*) (void*, void*)) rsaAllocationGetType; (void*) f((void*) 0x%lx, (void*) 0x%lx)",
-
- // rsaTypeGetNativeData(Context*, Type*, void* typeData, size)
- // Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
- // mHal.state.lodCount; mHal.state.faces; mElement; into typeData
- // Need to specify 32 or 64 bit for uint_t since this differs between devices
- "uint%u_t data[6]; void* (*f)(void*, void*, uintptr_t*, uint32_t) = (void* (*)(void*, void*, uintptr_t*, uint32_t)) "
- "rsaTypeGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 6); data[0]",
- "uint%u_t data[6]; void* (*f)(void*, void*, uintptr_t*, uint32_t) = (void* (*)(void*, void*, uintptr_t*, uint32_t)) "
- "rsaTypeGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 6); data[1]",
- "uint%u_t data[6]; void* (*f)(void*, void*, uintptr_t*, uint32_t) = (void* (*)(void*, void*, uintptr_t*, uint32_t)) "
- "rsaTypeGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 6); data[2]",
- "uint%u_t data[6]; void* (*f)(void*, void*, uintptr_t*, uint32_t) = (void* (*)(void*, void*, uintptr_t*, uint32_t)) "
- "rsaTypeGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 6); data[5]",
-
- // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
- // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData
- "uint32_t data[5]; void* (*f)(void*, void*, uint32_t*, uint32_t) = (void* (*)(void*, void*, uint32_t*, uint32_t)) "
- "rsaElementGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 5); data[0]", // Type
- "uint32_t data[5]; void* (*f)(void*, void*, uint32_t*, uint32_t) = (void* (*)(void*, void*, uint32_t*, uint32_t)) "
- "rsaElementGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 5); data[1]", // Kind
- "uint32_t data[5]; void* (*f)(void*, void*, uint32_t*, uint32_t) = (void* (*)(void*, void*, uint32_t*, uint32_t)) "
- "rsaElementGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 5); data[3]", // Vector size
- "uint32_t data[5]; void* (*f)(void*, void*, uint32_t*, uint32_t) = (void* (*)(void*, void*, uint32_t*, uint32_t)) "
- "rsaElementGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 5); data[4]", // Field count
-
- // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t *ids, const char **names,
- // size_t *arraySizes, uint32_t dataSize)
- // Needed for Allocations of structs to gather details about fields/Subelements
- "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
- "void* (*f) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t) = "
- "(void* (*) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t)) rsaElementGetSubElements;"
- "(void*) f((void*) 0x%lx, (void*) 0x%lx, (uintptr_t*) ids, names, arr_size, (uint32_t) %u);"
- "ids[%u]", // Element* of field
- "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
- "void* (*f) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t) = "
- "(void* (*) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t)) rsaElementGetSubElements;"
- "(void*) f((void*) 0x%lx, (void*) 0x%lx, (uintptr_t*) ids, names, arr_size, (uint32_t) %u);"
- "names[%u]", // Name of field
- "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
- "void* (*f) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t) = "
- "(void* (*) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t)) rsaElementGetSubElements;"
- "(void*) f((void*) 0x%lx, (void*) 0x%lx, (uintptr_t*) ids, names, arr_size, (uint32_t) %u);"
- "arr_size[%u]" // Array size of field
- };
-
-} // end of the anonymous namespace
-
-
-// Retrieve the string to JIT for the given expression
-const char*
-RenderScriptRuntime::JITTemplate(ExpressionStrings e)
-{
- // be nice to your Mips friend when adding new expression strings
- static_assert(sizeof(runtimeExpressions)/sizeof(runtimeExpressions[0]) ==
- sizeof(runtimeExpressions_mips)/sizeof(runtimeExpressions_mips[0]),
- "#runtimeExpressions != #runtimeExpressions_mips");
-
- assert((e >= eExprGetOffsetPtr && e <= eExprSubelementsArrSize) &&
- "Expression string out of bounds");
-
- llvm::Triple::ArchType arch = GetTargetRef().GetArchitecture().GetMachine();
-
- // mips JAL workaround
- if(arch == llvm::Triple::ArchType::mips64el || arch == llvm::Triple::ArchType::mipsel)
- return runtimeExpressions_mips[e];
- else
- return runtimeExpressions[e];
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 5); data[0]", // Type
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 5); data[1]", // Kind
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 5); data[3]", // Vector Size
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 5); data[4]", // Field Count
+
+ // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t *ids, const char **names,
+ // size_t *arraySizes, uint32_t dataSize)
+ // Needed for Allocations of structs to gather details about fields/Subelements
+ // Element* of field
+ "void* ids[%" PRIu32 "]; const char* names[%" PRIu32 "]; size_t arr_size[%" PRIu32 "];"
+ "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64 ", ids, names, arr_size, %" PRIu32 "); ids[%" PRIu32 "]",
+
+ // Name of field
+ "void* ids[%" PRIu32 "]; const char* names[%" PRIu32 "]; size_t arr_size[%" PRIu32 "];"
+ "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64 ", ids, names, arr_size, %" PRIu32 "); names[%" PRIu32 "]",
+
+ // Array size of field
+ "void* ids[%" PRIu32 "]; const char* names[%" PRIu32 "]; size_t arr_size[%" PRIu32 "];"
+ "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64 ", ids, names, arr_size, %" PRIu32 "); arr_size[%" PRIu32 "]"
+ }};
+
+ return runtimeExpressions[e];
}
+} // end of the anonymous namespace
// JITs the RS runtime for the internal data pointer of an allocation.
@@ -1413,32 +1597,32 @@ RenderScriptRuntime::JITTemplate(ExpressionStrings e)
// Then sets the data_ptr member in Allocation with the result.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr,
- unsigned int x, unsigned int y, unsigned int z)
+RenderScriptRuntime::JITDataPointer(AllocationDetails *allocation, StackFrame *frame_ptr, uint32_t x,
+ uint32_t y, uint32_t z)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!allocation->address.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITDataPointer - Failed to find allocation details");
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
return false;
}
- const char* expr_cstr = JITTemplate(eExprGetOffsetPtr);
+ const char *expr_cstr = JITTemplate(eExprGetOffsetPtr);
char buffer[jit_max_expr_size];
int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(), x, y, z);
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITDataPointer - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1456,31 +1640,32 @@ RenderScriptRuntime::JITDataPointer(AllocationDetails* allocation, StackFrame* f
// Then sets the type_ptr member in Allocation with the result.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr)
+RenderScriptRuntime::JITTypePointer(AllocationDetails *allocation, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!allocation->address.isValid() || !allocation->context.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITTypePointer - Failed to find allocation details");
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
return false;
}
- const char* expr_cstr = JITTemplate(eExprAllocGetType);
+ const char *expr_cstr = JITTemplate(eExprAllocGetType);
char buffer[jit_max_expr_size];
- int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->context.get(), *allocation->address.get());
+ int chars_written =
+ snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->context.get(), *allocation->address.get());
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITTypePointer - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1498,43 +1683,43 @@ RenderScriptRuntime::JITTypePointer(AllocationDetails* allocation, StackFrame* f
// Then sets dimension and element_ptr members in Allocation with the result.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr)
+RenderScriptRuntime::JITTypePacked(AllocationDetails *allocation, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!allocation->type_ptr.isValid() || !allocation->context.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITTypePacked - Failed to find allocation details");
+ log->Printf("%s - Failed to find allocation details.", __FUNCTION__);
return false;
}
// Expression is different depending on if device is 32 or 64 bit
uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
- const unsigned int bits = archByteSize == 4 ? 32 : 64;
+ const uint32_t bits = archByteSize == 4 ? 32 : 64;
// We want 4 elements from packed data
- const unsigned int num_exprs = 4;
+ const uint32_t num_exprs = 4;
assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1) && "Invalid number of expressions");
char buffer[num_exprs][jit_max_expr_size];
uint64_t results[num_exprs];
- for (unsigned int i = 0; i < num_exprs; ++i)
+ for (uint32_t i = 0; i < num_exprs; ++i)
{
- const char* expr_cstr = JITTemplate((ExpressionStrings) (eExprTypeDimX + i));
- int chars_written = snprintf(buffer[i], jit_max_expr_size, expr_cstr, bits,
- *allocation->context.get(), *allocation->type_ptr.get());
+ const char *expr_cstr = JITTemplate(ExpressionStrings(eExprTypeDimX + i));
+ int chars_written = snprintf(buffer[i], jit_max_expr_size, expr_cstr, bits, *allocation->context.get(),
+ *allocation->type_ptr.get());
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITTypePacked - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1554,7 +1739,7 @@ RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* fr
allocation->element.element_ptr = elem_ptr;
if (log)
- log->Printf("RenderScriptRuntime::JITTypePacked - dims (%u, %u, %u) Element*: 0x%" PRIx64,
+ log->Printf("%s - dims (%" PRIu32 ", %" PRIu32 ", %" PRIu32 ") Element*: 0x%" PRIx64 ".", __FUNCTION__,
dims.dim_1, dims.dim_2, dims.dim_3, elem_ptr);
return true;
@@ -1564,38 +1749,38 @@ RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* fr
// Then sets type, type_vec_size, field_count and type_kind members in Element with the result.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITElementPacked(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr)
+RenderScriptRuntime::JITElementPacked(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!elem.element_ptr.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITElementPacked - Failed to find allocation details");
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
return false;
}
// We want 4 elements from packed data
- const unsigned int num_exprs = 4;
+ const uint32_t num_exprs = 4;
assert(num_exprs == (eExprElementFieldCount - eExprElementType + 1) && "Invalid number of expressions");
char buffer[num_exprs][jit_max_expr_size];
uint64_t results[num_exprs];
- for (unsigned int i = 0; i < num_exprs; i++)
+ for (uint32_t i = 0; i < num_exprs; i++)
{
- const char* expr_cstr = JITTemplate((ExpressionStrings) (eExprElementType + i));
+ const char *expr_cstr = JITTemplate(ExpressionStrings(eExprElementType + i));
int chars_written = snprintf(buffer[i], jit_max_expr_size, expr_cstr, context, *elem.element_ptr.get());
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITElementPacked - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITElementPacked - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1611,8 +1796,8 @@ RenderScriptRuntime::JITElementPacked(Element& elem, const lldb::addr_t context,
elem.field_count = static_cast<uint32_t>(results[3]);
if (log)
- log->Printf("RenderScriptRuntime::JITElementPacked - data type %u, pixel type %u, vector size %u, field count %u",
- *elem.type.get(), *elem.type_kind.get(), *elem.type_vec_size.get(), *elem.field_count.get());
+ 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());
// If this Element has subelements then JIT rsaElementGetSubElements() for details about its fields
if (*elem.field_count.get() > 0 && !JITSubelements(elem, context, frame_ptr))
@@ -1625,14 +1810,14 @@ RenderScriptRuntime::JITElementPacked(Element& elem, const lldb::addr_t context,
// This is necessary for infering the struct type so we can pretty print the allocation's contents.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITSubelements(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr)
+RenderScriptRuntime::JITSubelements(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!elem.element_ptr.isValid() || !elem.field_count.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITSubelements - Failed to find allocation details");
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -1644,25 +1829,25 @@ RenderScriptRuntime::JITSubelements(Element& elem, const lldb::addr_t context, S
// Iterate over struct fields.
const uint32_t field_count = *elem.field_count.get();
- for (unsigned int field_index = 0; field_index < field_count; ++field_index)
+ for (uint32_t field_index = 0; field_index < field_count; ++field_index)
{
Element child;
- for (unsigned int expr_index = 0; expr_index < num_exprs; ++expr_index)
+ for (uint32_t expr_index = 0; expr_index < num_exprs; ++expr_index)
{
- const char* expr_cstr = JITTemplate((ExpressionStrings) (eExprSubelementsId + expr_index));
+ const char *expr_cstr = JITTemplate(ExpressionStrings(eExprSubelementsId + expr_index));
int chars_written = snprintf(expr_buffer, jit_max_expr_size, expr_cstr,
field_count, field_count, field_count,
context, *elem.element_ptr.get(), field_count, field_index);
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITSubelements - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITSubelements - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1671,9 +1856,9 @@ RenderScriptRuntime::JITSubelements(Element& elem, const lldb::addr_t context, S
return false;
if (log)
- log->Printf("RenderScriptRuntime::JITSubelements - Expr result 0x%" PRIx64, results);
+ log->Printf("%s - expr result 0x%" PRIx64 ".", __FUNCTION__, results);
- switch(expr_index)
+ switch (expr_index)
{
case 0: // Element* of child
child.element_ptr = static_cast<addr_t>(results);
@@ -1689,7 +1874,7 @@ RenderScriptRuntime::JITSubelements(Element& elem, const lldb::addr_t context, S
else
{
if (log)
- log->Printf("RenderScriptRuntime::JITSubelements - Warning: Couldn't read field name");
+ log->Printf("%s - warning: Couldn't read field name.", __FUNCTION__);
}
break;
}
@@ -1718,22 +1903,22 @@ RenderScriptRuntime::JITSubelements(Element& elem, const lldb::addr_t context, S
// Using this offset minus the starting address we can calculate the size of the allocation.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame* frame_ptr)
+RenderScriptRuntime::JITAllocationSize(AllocationDetails *allocation, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (!allocation->address.isValid() || !allocation->dimension.isValid()
- || !allocation->data_ptr.isValid() || !allocation->element.datum_size.isValid())
+ if (!allocation->address.isValid() || !allocation->dimension.isValid() || !allocation->data_ptr.isValid() ||
+ !allocation->element.datum_size.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationSize - Failed to find allocation details");
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
return false;
}
// Find dimensions
- unsigned int dim_x = allocation->dimension.get()->dim_1;
- unsigned int dim_y = allocation->dimension.get()->dim_2;
- unsigned int dim_z = allocation->dimension.get()->dim_3;
+ uint32_t dim_x = allocation->dimension.get()->dim_1;
+ uint32_t dim_y = allocation->dimension.get()->dim_2;
+ uint32_t dim_z = allocation->dimension.get()->dim_3;
// Our plan of jitting the last element address doesn't seem to work for struct Allocations
// Instead try to infer the size ourselves without any inter element padding.
@@ -1746,12 +1931,12 @@ RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame
allocation->size = dim_x * dim_y * dim_z * *allocation->element.datum_size.get();
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationSize - Infered size of struct allocation %u", *allocation->size.get());
-
+ log->Printf("%s - infered size of struct allocation %" PRIu32 ".", __FUNCTION__,
+ *allocation->size.get());
return true;
}
- const char* expr_cstr = JITTemplate(eExprGetOffsetPtr);
+ const char *expr_cstr = JITTemplate(eExprGetOffsetPtr);
char buffer[jit_max_expr_size];
// Calculate last element
@@ -1759,18 +1944,17 @@ RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame
dim_y = dim_y == 0 ? 0 : dim_y - 1;
dim_z = dim_z == 0 ? 0 : dim_z - 1;
- int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(),
- dim_x, dim_y, dim_z);
+ int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(), dim_x, dim_y, dim_z);
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationSize - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationSize - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1780,7 +1964,8 @@ RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame
addr_t mem_ptr = static_cast<lldb::addr_t>(result);
// Find pointer to last element and add on size of an element
- allocation->size = static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get()) + *allocation->element.datum_size.get();
+ allocation->size =
+ static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get()) + *allocation->element.datum_size.get();
return true;
}
@@ -1789,32 +1974,31 @@ RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame
// This is done to detect padding, since allocated memory is 16-byte aligned.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITAllocationStride(AllocationDetails* allocation, StackFrame* frame_ptr)
+RenderScriptRuntime::JITAllocationStride(AllocationDetails *allocation, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!allocation->address.isValid() || !allocation->data_ptr.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationStride - Failed to find allocation details");
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
return false;
}
- const char* expr_cstr = JITTemplate(eExprGetOffsetPtr);
+ const char *expr_cstr = JITTemplate(eExprGetOffsetPtr);
char buffer[jit_max_expr_size];
- int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(),
- 0, 1, 0);
+ int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(), 0, 1, 0);
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationStride - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationStride - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1830,7 +2014,7 @@ RenderScriptRuntime::JITAllocationStride(AllocationDetails* allocation, StackFra
// JIT all the current runtime info regarding an allocation
bool
-RenderScriptRuntime::RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr)
+RenderScriptRuntime::RefreshAllocation(AllocationDetails *allocation, StackFrame *frame_ptr)
{
// GetOffsetPointer()
if (!JITDataPointer(allocation, frame_ptr))
@@ -1862,9 +2046,9 @@ RenderScriptRuntime::RefreshAllocation(AllocationDetails* allocation, StackFrame
// This string should be the name of the struct type the Element represents.
// We need this string for pretty printing the Element to users.
void
-RenderScriptRuntime::FindStructTypeName(Element& elem, StackFrame* frame_ptr)
+RenderScriptRuntime::FindStructTypeName(Element &elem, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!elem.type_name.IsEmpty()) // Name already set
return;
@@ -1883,7 +2067,7 @@ RenderScriptRuntime::FindStructTypeName(Element& elem, StackFrame* frame_ptr)
{
const VariableSP var_sp(variable_list.GetVariableAtIndex(var_index));
if (!var_sp)
- continue;
+ continue;
ValueObjectSP valobj_sp = ValueObjectVariable::Create(frame_ptr, var_sp);
if (!valobj_sp)
@@ -1914,13 +2098,13 @@ RenderScriptRuntime::FindStructTypeName(Element& elem, StackFrame* frame_ptr)
// RS can add extra struct members for padding in the format '#rs_padding_[0-9]+'
if (found && num_children < elem.children.size())
{
- const unsigned int size_diff = elem.children.size() - num_children;
+ const uint32_t size_diff = elem.children.size() - num_children;
if (log)
- log->Printf("RenderScriptRuntime::FindStructTypeName - %u padding struct entries", size_diff);
+ log->Printf("%s - %" PRIu32 " padding struct entries", __FUNCTION__, size_diff);
- for (unsigned int padding_index = 0; padding_index < size_diff; ++padding_index)
+ for (uint32_t padding_index = 0; padding_index < size_diff; ++padding_index)
{
- const ConstString& name = elem.children[num_children + padding_index].type_name;
+ const ConstString &name = elem.children[num_children + padding_index].type_name;
if (strcmp(name.AsCString(), "#rs_padding") < 0)
found = false;
}
@@ -1941,7 +2125,7 @@ RenderScriptRuntime::FindStructTypeName(Element& elem, StackFrame* frame_ptr)
// Save name of variable in Element.
elem.type_name = valobj_sp->GetTypeName();
if (log)
- log->Printf("RenderScriptRuntime::FindStructTypeName - Element name set to %s", elem.type_name.AsCString());
+ log->Printf("%s - element name set to %s", __FUNCTION__, elem.type_name.AsCString());
return;
}
@@ -1951,29 +2135,30 @@ RenderScriptRuntime::FindStructTypeName(Element& elem, StackFrame* frame_ptr)
// Function sets the datum_size member of Element. Representing the size of a single instance including padding.
// Assumes the relevant allocation information has already been jitted.
void
-RenderScriptRuntime::SetElementSize(Element& elem)
+RenderScriptRuntime::SetElementSize(Element &elem)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
const Element::DataType type = *elem.type.get();
- assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT
- && "Invalid allocation type");
+ assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT && "Invalid allocation type");
- const unsigned int vec_size = *elem.type_vec_size.get();
- unsigned int data_size = 0;
- unsigned int padding = 0;
+ const uint32_t vec_size = *elem.type_vec_size.get();
+ uint32_t data_size = 0;
+ uint32_t padding = 0;
// Element is of a struct type, calculate size recursively.
if ((type == Element::RS_TYPE_NONE) && (elem.children.size() > 0))
{
- for (Element& child : elem.children)
+ for (Element &child : elem.children)
{
SetElementSize(child);
- const unsigned int array_size = child.array_size.isValid() ? *child.array_size.get() : 1;
+ const uint32_t array_size = child.array_size.isValid() ? *child.array_size.get() : 1;
data_size += *child.datum_size.get() * array_size;
}
}
- else if (type == Element::RS_TYPE_UNSIGNED_5_6_5 || type == Element::RS_TYPE_UNSIGNED_5_5_5_1 ||
- type == Element::RS_TYPE_UNSIGNED_4_4_4_4) // These have been packed already
+ // These have been packed already
+ else if (type == Element::RS_TYPE_UNSIGNED_5_6_5 ||
+ type == Element::RS_TYPE_UNSIGNED_5_5_5_1 ||
+ type == Element::RS_TYPE_UNSIGNED_4_4_4_4)
{
data_size = AllocationDetails::RSTypeToFormat[type][eElementSize];
}
@@ -1989,40 +2174,41 @@ RenderScriptRuntime::SetElementSize(Element& elem)
elem.padding = padding;
elem.datum_size = data_size + padding;
if (log)
- log->Printf("RenderScriptRuntime::SetElementSize - element size set to %u", data_size + padding);
+ log->Printf("%s - element size set to %" PRIu32, __FUNCTION__, data_size + padding);
}
// Given an allocation, this function copies the allocation contents from device into a buffer on the heap.
// Returning a shared pointer to the buffer containing the data.
std::shared_ptr<uint8_t>
-RenderScriptRuntime::GetAllocationData(AllocationDetails* allocation, StackFrame* frame_ptr)
+RenderScriptRuntime::GetAllocationData(AllocationDetails *allocation, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
// JIT all the allocation details
if (allocation->shouldRefresh())
{
if (log)
- log->Printf("RenderScriptRuntime::GetAllocationData - Allocation details not calculated yet, jitting info");
+ log->Printf("%s - allocation details not calculated yet, jitting info", __FUNCTION__);
if (!RefreshAllocation(allocation, frame_ptr))
{
if (log)
- log->Printf("RenderScriptRuntime::GetAllocationData - Couldn't JIT allocation details");
+ log->Printf("%s - couldn't JIT allocation details", __FUNCTION__);
return nullptr;
}
}
- assert(allocation->data_ptr.isValid() && allocation->element.type.isValid() && allocation->element.type_vec_size.isValid()
- && allocation->size.isValid() && "Allocation information not available");
+ assert(allocation->data_ptr.isValid() && allocation->element.type.isValid() &&
+ allocation->element.type_vec_size.isValid() && allocation->size.isValid() &&
+ "Allocation information not available");
// Allocate a buffer to copy data into
- const unsigned int size = *allocation->size.get();
+ const uint32_t size = *allocation->size.get();
std::shared_ptr<uint8_t> buffer(new uint8_t[size]);
if (!buffer)
{
if (log)
- log->Printf("RenderScriptRuntime::GetAllocationData - Couldn't allocate a %u byte buffer", size);
+ log->Printf("%s - couldn't allocate a %" PRIu32 " byte buffer", __FUNCTION__, size);
return nullptr;
}
@@ -2033,8 +2219,8 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails* allocation, StackFrame
if (error.Fail())
{
if (log)
- log->Printf("RenderScriptRuntime::GetAllocationData - '%s' Couldn't read %u bytes of allocation data from 0x%" PRIx64,
- error.AsCString(), size, data_ptr);
+ log->Printf("%s - '%s' Couldn't read %" PRIu32 " bytes of allocation data from 0x%" PRIx64,
+ __FUNCTION__, error.AsCString(), size, data_ptr);
return nullptr;
}
@@ -2045,34 +2231,34 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails* allocation, StackFrame
// There is a header at the start of the file, FileHeader, before the data content itself.
// Information from this header is used to display warnings to the user about incompatabilities
bool
-RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr)
+RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
// Find allocation with the given id
- AllocationDetails* alloc = FindAllocByID(strm, alloc_id);
+ AllocationDetails *alloc = FindAllocByID(strm, alloc_id);
if (!alloc)
return false;
if (log)
- log->Printf("RenderScriptRuntime::LoadAllocation - Found allocation 0x%" PRIx64, *alloc->address.get());
+ log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__, *alloc->address.get());
// JIT all the allocation details
if (alloc->shouldRefresh())
{
if (log)
- log->Printf("RenderScriptRuntime::LoadAllocation - Allocation details not calculated yet, jitting info");
+ log->Printf("%s - allocation details not calculated yet, jitting info.", __FUNCTION__);
if (!RefreshAllocation(alloc, frame_ptr))
{
if (log)
- log->Printf("RenderScriptRuntime::LoadAllocation - Couldn't JIT allocation details");
+ log->Printf("%s - couldn't JIT allocation details", __FUNCTION__);
return false;
}
}
- assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && alloc->element.type_vec_size.isValid()
- && alloc->size.isValid() && alloc->element.datum_size.isValid() && "Allocation information not available");
+ assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && alloc->element.type_vec_size.isValid() &&
+ alloc->size.isValid() && alloc->element.datum_size.isValid() && "Allocation information not available");
// Check we can read from file
FileSpec file(filename, true);
@@ -2094,19 +2280,18 @@ RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const
DataBufferSP data_sp(file.ReadFileContents());
// Cast start of buffer to FileHeader and use pointer to read metadata
- void* file_buffer = data_sp->GetBytes();
- if (file_buffer == NULL || data_sp->GetByteSize() <
- (sizeof(AllocationDetails::FileHeader) + sizeof(AllocationDetails::ElementHeader)))
+ void *file_buffer = data_sp->GetBytes();
+ if (file_buffer == nullptr ||
+ data_sp->GetByteSize() < (sizeof(AllocationDetails::FileHeader) + sizeof(AllocationDetails::ElementHeader)))
{
strm.Printf("Error: File %s does not contain enough data for header", filename);
strm.EOL();
return false;
}
- const AllocationDetails::FileHeader* file_header = static_cast<AllocationDetails::FileHeader*>(file_buffer);
+ const AllocationDetails::FileHeader *file_header = static_cast<AllocationDetails::FileHeader *>(file_buffer);
// Check file starts with ascii characters "RSAD"
- if (file_header->ident[0] != 'R' || file_header->ident[1] != 'S' || file_header->ident[2] != 'A'
- || file_header->ident[3] != 'D')
+ if (memcmp(file_header->ident, "RSAD", 4))
{
strm.Printf("Error: File doesn't contain identifier for an RS allocation dump. Are you sure this is the correct file?");
strm.EOL();
@@ -2115,24 +2300,24 @@ RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const
// Look at the type of the root element in the header
AllocationDetails::ElementHeader root_element_header;
- memcpy(&root_element_header, static_cast<uint8_t*>(file_buffer) + sizeof(AllocationDetails::FileHeader),
+ memcpy(&root_element_header, static_cast<uint8_t *>(file_buffer) + sizeof(AllocationDetails::FileHeader),
sizeof(AllocationDetails::ElementHeader));
if (log)
- log->Printf("RenderScriptRuntime::LoadAllocation - header type %u, element size %u",
+ log->Printf("%s - header type %" PRIu32 ", element size %" PRIu32, __FUNCTION__,
root_element_header.type, root_element_header.element_size);
// Check if the target allocation and file both have the same number of bytes for an Element
if (*alloc->element.datum_size.get() != root_element_header.element_size)
{
- strm.Printf("Warning: Mismatched Element sizes - file %u bytes, allocation %u bytes",
+ strm.Printf("Warning: Mismatched Element sizes - file %" PRIu32 " bytes, allocation %" PRIu32 " bytes",
root_element_header.element_size, *alloc->element.datum_size.get());
strm.EOL();
}
// Check if the target allocation and file both have the same type
- const unsigned int alloc_type = static_cast<unsigned int>(*alloc->element.type.get());
- const unsigned int file_type = root_element_header.type;
+ const uint32_t alloc_type = static_cast<uint32_t>(*alloc->element.type.get());
+ const uint32_t file_type = root_element_header.type;
if (file_type > Element::RS_TYPE_FONT)
{
@@ -2142,36 +2327,36 @@ RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const
else if (alloc_type != file_type)
{
// Enum value isn't monotonous, so doesn't always index RsDataTypeToString array
- unsigned int printable_target_type_index = alloc_type;
- unsigned int printable_head_type_index = file_type;
+ uint32_t printable_target_type_index = alloc_type;
+ uint32_t printable_head_type_index = file_type;
if (alloc_type >= Element::RS_TYPE_ELEMENT && alloc_type <= Element::RS_TYPE_FONT)
- printable_target_type_index = static_cast<Element::DataType>(
- (alloc_type - Element::RS_TYPE_ELEMENT) + Element::RS_TYPE_MATRIX_2X2 + 1);
+ printable_target_type_index = static_cast<Element::DataType>((alloc_type - Element::RS_TYPE_ELEMENT) +
+ Element::RS_TYPE_MATRIX_2X2 + 1);
if (file_type >= Element::RS_TYPE_ELEMENT && file_type <= Element::RS_TYPE_FONT)
- printable_head_type_index = static_cast<Element::DataType>(
- (file_type - Element::RS_TYPE_ELEMENT) + Element::RS_TYPE_MATRIX_2X2 + 1);
+ printable_head_type_index = static_cast<Element::DataType>((file_type - Element::RS_TYPE_ELEMENT) +
+ Element::RS_TYPE_MATRIX_2X2 + 1);
- const char* file_type_cstr = AllocationDetails::RsDataTypeToString[printable_head_type_index][0];
- const char* target_type_cstr = AllocationDetails::RsDataTypeToString[printable_target_type_index][0];
+ const char *file_type_cstr = AllocationDetails::RsDataTypeToString[printable_head_type_index][0];
+ const char *target_type_cstr = AllocationDetails::RsDataTypeToString[printable_target_type_index][0];
- strm.Printf("Warning: Mismatched Types - file '%s' type, allocation '%s' type",
- file_type_cstr, target_type_cstr);
+ strm.Printf("Warning: Mismatched Types - file '%s' type, allocation '%s' type", file_type_cstr,
+ target_type_cstr);
strm.EOL();
}
// Advance buffer past header
- file_buffer = static_cast<uint8_t*>(file_buffer) + file_header->hdr_size;
+ file_buffer = static_cast<uint8_t *>(file_buffer) + file_header->hdr_size;
// Calculate size of allocation data in file
size_t length = data_sp->GetByteSize() - file_header->hdr_size;
// Check if the target allocation and file both have the same total data size.
- const unsigned int alloc_size = *alloc->size.get();
+ const uint32_t alloc_size = *alloc->size.get();
if (alloc_size != length)
{
- strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64 " bytes, allocation 0x%x bytes",
- (uint64_t) length, alloc_size);
+ strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64 " bytes, allocation 0x%" PRIx32 " bytes",
+ (uint64_t)length, alloc_size);
strm.EOL();
length = alloc_size < length ? alloc_size : length; // Set length to copy to minimum
}
@@ -2187,7 +2372,7 @@ RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const
return false;
}
- strm.Printf("Contents of file '%s' read into allocation %u", filename, alloc->id);
+ strm.Printf("Contents of file '%s' read into allocation %" PRIu32, filename, alloc->id);
strm.EOL();
return true;
@@ -2196,9 +2381,11 @@ RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const
// Function takes as parameters a byte buffer, which will eventually be written to file as the element header,
// an offset into that buffer, and an Element that will be saved into the buffer at the parametrised offset.
// Return value is the new offset after writing the element into the buffer.
-// Elements are saved to the file as the ElementHeader struct followed by offsets to the structs of all the element's children.
+// Elements are saved to the file as the ElementHeader struct followed by offsets to the structs of all the element's
+// children.
size_t
-RenderScriptRuntime::PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset, const Element& elem)
+RenderScriptRuntime::PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset,
+ const Element &elem)
{
// File struct for an element header with all the relevant details copied from elem.
// We assume members are valid already.
@@ -2211,13 +2398,13 @@ RenderScriptRuntime::PopulateElementHeaders(const std::shared_ptr<uint8_t> heade
const size_t elem_header_size = sizeof(AllocationDetails::ElementHeader);
// Copy struct into buffer and advance offset
- // We assume that header_buffer has been checked for NULL before this method is called
+ // We assume that header_buffer has been checked for nullptr before this method is called
memcpy(header_buffer.get() + offset, &elem_header, elem_header_size);
offset += elem_header_size;
// Starting offset of child ElementHeader struct
size_t child_offset = offset + ((elem.children.size() + 1) * sizeof(uint32_t));
- for (const RenderScriptRuntime::Element& child : elem.children)
+ for (const RenderScriptRuntime::Element &child : elem.children)
{
// Recursively populate the buffer with the element header structs of children.
// Then save the offsets where they were set after the parent element header.
@@ -2233,17 +2420,18 @@ RenderScriptRuntime::PopulateElementHeaders(const std::shared_ptr<uint8_t> heade
return child_offset;
}
-// Given an Element object this function returns the total size needed in the file header to store the element's details.
+// Given an Element object this function returns the total size needed in the file header to store the element's
+// details.
// Taking into account the size of the element header struct, plus the offsets to all the element's children.
// Function is recursive so that the size of all ancestors is taken into account.
size_t
-RenderScriptRuntime::CalculateElementHeaderSize(const Element& elem)
+RenderScriptRuntime::CalculateElementHeaderSize(const Element &elem)
{
size_t size = (elem.children.size() + 1) * sizeof(uint32_t); // Offsets to children plus zero terminator
- size += sizeof(AllocationDetails::ElementHeader); // Size of header struct with type details
+ size += sizeof(AllocationDetails::ElementHeader); // Size of header struct with type details
// Calculate recursively for all descendants
- for (const Element& child : elem.children)
+ for (const Element &child : elem.children)
size += CalculateElementHeaderSize(child);
return size;
@@ -2253,34 +2441,35 @@ RenderScriptRuntime::CalculateElementHeaderSize(const Element& elem)
// This file can then be loaded later into a different allocation.
// There is a header, FileHeader, before the allocation data containing meta-data.
bool
-RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr)
+RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
// Find allocation with the given id
- AllocationDetails* alloc = FindAllocByID(strm, alloc_id);
+ AllocationDetails *alloc = FindAllocByID(strm, alloc_id);
if (!alloc)
return false;
if (log)
- log->Printf("RenderScriptRuntime::SaveAllocation - Found allocation 0x%" PRIx64, *alloc->address.get());
+ log->Printf("%s - found allocation 0x%" PRIx64 ".", __FUNCTION__, *alloc->address.get());
- // JIT all the allocation details
+ // JIT all the allocation details
if (alloc->shouldRefresh())
{
if (log)
- log->Printf("RenderScriptRuntime::SaveAllocation - Allocation details not calculated yet, jitting info");
+ log->Printf("%s - allocation details not calculated yet, jitting info.", __FUNCTION__);
if (!RefreshAllocation(alloc, frame_ptr))
{
if (log)
- log->Printf("RenderScriptRuntime::SaveAllocation - Couldn't JIT allocation details");
+ log->Printf("%s - couldn't JIT allocation details.", __FUNCTION__);
return false;
}
}
- assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && alloc->element.type_vec_size.isValid() && alloc->element.datum_size.get()
- && alloc->element.type_kind.isValid() && alloc->dimension.isValid() && "Allocation information not available");
+ assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && alloc->element.type_vec_size.isValid() &&
+ alloc->element.datum_size.get() && alloc->element.type_kind.isValid() && alloc->dimension.isValid() &&
+ "Allocation information not available");
// Check we can create writable file
FileSpec file_spec(filename, true);
@@ -2303,7 +2492,7 @@ RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const
// Create the file header
AllocationDetails::FileHeader head;
- head.ident[0] = 'R'; head.ident[1] = 'S'; head.ident[2] = 'A'; head.ident[3] = 'D';
+ memcpy(head.ident, "RSAD", 4);
head.dims[0] = static_cast<uint32_t>(alloc->dimension.get()->dim_1);
head.dims[1] = static_cast<uint32_t>(alloc->dimension.get()->dim_2);
head.dims[2] = static_cast<uint32_t>(alloc->dimension.get()->dim_3);
@@ -2315,7 +2504,7 @@ RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const
// Write the file header
size_t num_bytes = sizeof(AllocationDetails::FileHeader);
if (log)
- log->Printf("RenderScriptRuntime::SaveAllocation - Writing File Header, 0x%zX bytes", num_bytes);
+ log->Printf("%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__, (uint64_t)num_bytes);
Error err = file.Write(&head, num_bytes);
if (!err.Success())
@@ -2329,7 +2518,7 @@ RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const
std::shared_ptr<uint8_t> element_header_buffer(new uint8_t[element_header_size]);
if (element_header_buffer == nullptr)
{
- strm.Printf("Internal Error: Couldn't allocate %zu bytes on the heap", element_header_size);
+ strm.Printf("Internal Error: Couldn't allocate %" PRIu64 " bytes on the heap", (uint64_t)element_header_size);
strm.EOL();
return false;
}
@@ -2339,7 +2528,7 @@ RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const
// Write headers for allocation element type to file
num_bytes = element_header_size;
if (log)
- log->Printf("RenderScriptRuntime::SaveAllocation - Writing Element Headers, 0x%zX bytes", num_bytes);
+ log->Printf("%s - writing element headers, 0x%" PRIx64 " bytes.", __FUNCTION__, (uint64_t)num_bytes);
err = file.Write(element_header_buffer.get(), num_bytes);
if (!err.Success())
@@ -2352,7 +2541,7 @@ RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const
// Write allocation data to file
num_bytes = static_cast<size_t>(*alloc->size.get());
if (log)
- log->Printf("RenderScriptRuntime::SaveAllocation - Writing 0x%zX bytes", num_bytes);
+ log->Printf("%s - writing 0x%" PRIx64 " bytes", __FUNCTION__, (uint64_t)num_bytes);
err = file.Write(buffer.get(), num_bytes);
if (!err.Success())
@@ -2370,7 +2559,7 @@ RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const
bool
RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (module_sp)
{
@@ -2424,7 +2613,8 @@ RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
{
m_libRS = module_sp;
static ConstString gDbgPresentStr("gDebuggerPresent");
- const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
+ const Symbol *debug_present =
+ m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
if (debug_present)
{
Error error;
@@ -2432,21 +2622,22 @@ RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
Target &target = GetProcess()->GetTarget();
addr_t addr = debug_present->GetLoadAddress(&target);
GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error);
- if(error.Success())
+ if (error.Success())
{
if (log)
- log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee");
+ log->Printf("%s - debugger present flag set on debugee.", __FUNCTION__);
m_debuggerPresentFlagged = true;
}
else if (log)
{
- log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString());
+ log->Printf("%s - error writing debugger present flags '%s' ", __FUNCTION__,
+ error.AsCString());
}
}
else if (log)
{
- log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found");
+ log->Printf("%s - error writing debugger present flags - symbol not found", __FUNCTION__);
}
}
break;
@@ -2475,98 +2666,98 @@ RenderScriptRuntime::Update()
// The maximum line length of an .rs.info packet
#define MAXLINE 500
+#define STRINGIFY(x) #x
+#define MAXLINESTR_(x) "%" STRINGIFY(x) "s"
+#define MAXLINESTR MAXLINESTR_(MAXLINE)
// The .rs.info symbol in renderscript modules contains a string which needs to be parsed.
// The string is basic and is parsed on a line by line basis.
bool
RSModuleDescriptor::ParseRSInfo()
{
+ assert(m_module);
const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
- if (info_sym)
- {
- const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
- const addr_t size = info_sym->GetByteSize();
- const FileSpec fs = m_module->GetFileSpec();
+ if (!info_sym)
+ return false;
- DataBufferSP buffer = fs.ReadFileContents(addr, size);
+ const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
+ if (addr == LLDB_INVALID_ADDRESS)
+ return false;
- if (!buffer)
- return false;
+ const addr_t size = info_sym->GetByteSize();
+ const FileSpec fs = m_module->GetFileSpec();
- std::string info((const char *)buffer->GetBytes());
+ const DataBufferSP buffer = fs.ReadFileContents(addr, size);
+ if (!buffer)
+ return false;
- std::vector<std::string> info_lines;
- size_t lpos = info.find('\n');
- while (lpos != std::string::npos)
+ // split rs.info. contents into lines
+ std::vector<std::string> info_lines;
+ {
+ const std::string info((const char *)buffer->GetBytes());
+ for (size_t tail = 0; tail < info.size();)
{
- info_lines.push_back(info.substr(0, lpos));
- info = info.substr(lpos + 1);
- lpos = info.find('\n');
+ // find next new line or end of string
+ size_t head = info.find('\n', tail);
+ head = (head == std::string::npos) ? info.size() : head;
+ std::string line = info.substr(tail, head - tail);
+ // add to line list
+ info_lines.push_back(line);
+ tail = head + 1;
}
- size_t offset = 0;
- while (offset < info_lines.size())
+ }
+
+ std::array<char, MAXLINE> name{{'\0'}};
+ std::array<char, MAXLINE> value{{'\0'}};
+
+ // parse all text lines of .rs.info
+ for (auto line = info_lines.begin(); line != info_lines.end(); ++line)
+ {
+ uint32_t numDefns = 0;
+ if (sscanf(line->c_str(), "exportVarCount: %" PRIu32 "", &numDefns) == 1)
{
- std::string line = info_lines[offset];
- // Parse directives
- uint32_t numDefns = 0;
- if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1)
- {
- while (numDefns--)
- m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str()));
- }
- else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1)
- {
- }
- else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1)
+ while (numDefns--)
+ m_globals.push_back(RSGlobalDescriptor(this, (++line)->c_str()));
+ }
+ else if (sscanf(line->c_str(), "exportForEachCount: %" PRIu32 "", &numDefns) == 1)
+ {
+ while (numDefns--)
{
- char name[MAXLINE];
- while (numDefns--)
+ uint32_t slot = 0;
+ name[0] = '\0';
+ static const char *fmt_s = "%" PRIu32 " - " MAXLINESTR;
+ if (sscanf((++line)->c_str(), fmt_s, &slot, name.data()) == 2)
{
- uint32_t slot = 0;
- name[0] = '\0';
- if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2)
- {
- m_kernels.push_back(RSKernelDescriptor(this, name, slot));
- }
+ if (name[0] != '\0')
+ m_kernels.push_back(RSKernelDescriptor(this, name.data(), slot));
}
}
- else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1)
+ }
+ else if (sscanf(line->c_str(), "pragmaCount: %" PRIu32 "", &numDefns) == 1)
+ {
+ while (numDefns--)
{
- char name[MAXLINE];
- char value[MAXLINE];
- while (numDefns--)
+ name[0] = value[0] = '\0';
+ static const char *fmt_s = MAXLINESTR " - " MAXLINESTR;
+ if (sscanf((++line)->c_str(), fmt_s, name.data(), value.data()) != 0)
{
- name[0] = '\0';
- value[0] = '\0';
- if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0
- && (name[0] != '\0'))
- {
- m_pragmas[std::string(name)] = value;
- }
+ if (name[0] != '\0')
+ m_pragmas[std::string(name.data())] = value.data();
}
}
- else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1)
+ }
+ else
+ {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ if (log)
{
+ log->Printf("%s - skipping .rs.info field '%s'", __FUNCTION__, line->c_str());
}
-
- offset++;
}
- return m_kernels.size() > 0;
}
- return false;
-}
-bool
-RenderScriptRuntime::ProbeModules(const ModuleList module_list)
-{
- bool rs_found = false;
- size_t num_modules = module_list.GetSize();
- for (size_t i = 0; i < num_modules; i++)
- {
- auto module = module_list.GetModuleAtIndex(i);
- rs_found |= LoadModule(module);
- }
- return rs_found;
+ // 'root' kernel should always be present
+ return m_kernels.size() > 0;
}
void
@@ -2616,7 +2807,7 @@ RenderScriptRuntime::DumpContexts(Stream &strm) const
// Iterate over all of the currently discovered scripts.
// Note: We cant push or pop from m_scripts inside this loop or it may invalidate script.
- for (const auto & script : m_scripts)
+ for (const auto &script : m_scripts)
{
if (!script->context.isValid())
continue;
@@ -2632,7 +2823,7 @@ RenderScriptRuntime::DumpContexts(Stream &strm) const
}
}
- for (const auto& cRef : contextReferences)
+ for (const auto &cRef : contextReferences)
{
strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second);
strm.EOL();
@@ -2648,7 +2839,7 @@ RenderScriptRuntime::DumpKernels(Stream &strm) const
strm.IndentMore();
for (const auto &module : m_rsmodules)
{
- strm.Printf("Resource '%s':",module->m_resname.c_str());
+ strm.Printf("Resource '%s':", module->m_resname.c_str());
strm.EOL();
for (const auto &kernel : module->m_kernels)
{
@@ -2659,32 +2850,31 @@ RenderScriptRuntime::DumpKernels(Stream &strm) const
strm.IndentLess();
}
-RenderScriptRuntime::AllocationDetails*
+RenderScriptRuntime::AllocationDetails *
RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id)
{
- AllocationDetails* alloc = nullptr;
+ AllocationDetails *alloc = nullptr;
// See if we can find allocation using id as an index;
- if (alloc_id <= m_allocations.size() && alloc_id != 0
- && m_allocations[alloc_id-1]->id == alloc_id)
+ if (alloc_id <= m_allocations.size() && alloc_id != 0 && m_allocations[alloc_id - 1]->id == alloc_id)
{
- alloc = m_allocations[alloc_id-1].get();
+ alloc = m_allocations[alloc_id - 1].get();
return alloc;
}
// Fallback to searching
- for (const auto & a : m_allocations)
+ for (const auto &a : m_allocations)
{
- if (a->id == alloc_id)
- {
- alloc = a.get();
- break;
- }
+ if (a->id == alloc_id)
+ {
+ alloc = a.get();
+ break;
+ }
}
if (alloc == nullptr)
{
- strm.Printf("Error: Couldn't find allocation with id matching %u", alloc_id);
+ strm.Printf("Error: Couldn't find allocation with id matching %" PRIu32, alloc_id);
strm.EOL();
}
@@ -2693,23 +2883,23 @@ RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id)
// Prints the contents of an allocation to the output stream, which may be a file
bool
-RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const uint32_t id)
+RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
// Check we can find the desired allocation
- AllocationDetails* alloc = FindAllocByID(strm, id);
+ AllocationDetails *alloc = FindAllocByID(strm, id);
if (!alloc)
return false; // FindAllocByID() will print error message for us here
if (log)
- log->Printf("RenderScriptRuntime::DumpAllocation - Found allocation 0x%" PRIx64, *alloc->address.get());
+ log->Printf("%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("RenderScriptRuntime::DumpAllocation - Allocation details not calculated yet, jitting info");
+ log->Printf("%s - allocation details not calculated yet, jitting info.", __FUNCTION__);
// JIT all the allocation information
if (!RefreshAllocation(alloc, frame_ptr))
@@ -2721,11 +2911,10 @@ RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const u
}
// Establish format and size of each data element
- const unsigned int vec_size = *alloc->element.type_vec_size.get();
+ const uint32_t vec_size = *alloc->element.type_vec_size.get();
const Element::DataType type = *alloc->element.type.get();
- assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT
- && "Invalid allocation type");
+ assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT && "Invalid allocation type");
lldb::Format format;
if (type >= Element::RS_TYPE_ELEMENT)
@@ -2734,10 +2923,10 @@ RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const u
format = vec_size == 1 ? static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatSingle])
: static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatVector]);
- const unsigned int data_size = *alloc->element.datum_size.get();
+ const uint32_t data_size = *alloc->element.datum_size.get();
if (log)
- log->Printf("RenderScriptRuntime::DumpAllocation - Element size %u bytes, including padding", data_size);
+ log->Printf("%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);
@@ -2761,44 +2950,45 @@ RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const u
return false;
}
}
- const unsigned int stride = *alloc->stride.get();
- const unsigned int size = *alloc->size.get(); // Size of whole allocation
- const unsigned int padding = alloc->element.padding.isValid() ? *alloc->element.padding.get() : 0;
+ const uint32_t stride = *alloc->stride.get();
+ 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("RenderScriptRuntime::DumpAllocation - stride %u bytes, size %u bytes, padding %u", stride, size, padding);
+ log->Printf("%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
- unsigned int dim_x = alloc->dimension.get()->dim_1;
+ uint32_t dim_x = alloc->dimension.get()->dim_1;
dim_x = dim_x == 0 ? 1 : dim_x;
- unsigned int dim_y = alloc->dimension.get()->dim_2;
+ uint32_t dim_y = alloc->dimension.get()->dim_2;
dim_y = dim_y == 0 ? 1 : dim_y;
- unsigned int dim_z = alloc->dimension.get()->dim_3;
+ uint32_t dim_z = alloc->dimension.get()->dim_3;
dim_z = dim_z == 0 ? 1 : dim_z;
// Use data extractor to format output
const uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
DataExtractor alloc_data(buffer.get(), size, GetProcess()->GetByteOrder(), archByteSize);
- unsigned int offset = 0; // Offset in buffer to next element to be printed
- unsigned int prev_row = 0; // Offset to the start of the previous row
+ uint32_t offset = 0; // Offset in buffer to next element to be printed
+ uint32_t prev_row = 0; // Offset to the start of the previous row
// Iterate over allocation dimensions, printing results to user
strm.Printf("Data (X, Y, Z):");
- for (unsigned int z = 0; z < dim_z; ++z)
+ for (uint32_t z = 0; z < dim_z; ++z)
{
- for (unsigned int y = 0; y < dim_y; ++y)
+ for (uint32_t y = 0; y < dim_y; ++y)
{
// Use stride to index start of next row.
- if (!(y==0 && z==0))
+ if (!(y == 0 && z == 0))
offset = prev_row + stride;
prev_row = offset;
// Print each element in the row individually
- for (unsigned int x = 0; x < dim_x; ++x)
+ for (uint32_t x = 0; x < dim_x; ++x)
{
- strm.Printf("\n(%u, %u, %u) = ", x, y, z);
+ strm.Printf("\n(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ") = ", x, y, z);
if ((type == Element::RS_TYPE_NONE) && (alloc->element.children.size() > 0) &&
(alloc->element.type_name != Element::GetFallbackStructName()))
{
@@ -2812,12 +3002,12 @@ RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const u
// Setup expression as derefrencing a pointer cast to element address.
char expr_char_buffer[jit_max_expr_size];
int chars_written = snprintf(expr_char_buffer, jit_max_expr_size, "*(%s*) 0x%" PRIx64,
- alloc->element.type_name.AsCString(), *alloc->data_ptr.get() + offset);
+ alloc->element.type_name.AsCString(), *alloc->data_ptr.get() + offset);
if (chars_written < 0 || chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::DumpAllocation- Error in snprintf()");
+ log->Printf("%s - error in snprintf().", __FUNCTION__);
continue;
}
@@ -2841,10 +3031,35 @@ RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const u
return true;
}
-// Prints infomation regarding all the currently loaded allocations.
+// Function recalculates all our cached information about allocations by jitting the
+// RS runtime regarding each allocation we know about.
+// Returns true if all allocations could be recomputed, false otherwise.
+bool
+RenderScriptRuntime::RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr)
+{
+ bool success = true;
+ for (auto &alloc : m_allocations)
+ {
+ // JIT current allocation information
+ if (!RefreshAllocation(alloc.get(), frame_ptr))
+ {
+ strm.Printf("Error: Couldn't evaluate details for allocation %" PRIu32 "\n", alloc->id);
+ success = false;
+ }
+ }
+
+ if (success)
+ strm.Printf("All allocations successfully recomputed");
+ strm.EOL();
+
+ return success;
+}
+
+// Prints information regarding currently loaded allocations.
// These details are gathered by jitting the runtime, which has as latency.
+// Index parameter specifies a single allocation ID to print, or a zero value to print them all
void
-RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute)
+RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame *frame_ptr, const uint32_t index)
{
strm.Printf("RenderScript Allocations:");
strm.EOL();
@@ -2852,17 +3067,20 @@ RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool r
for (auto &alloc : m_allocations)
{
- // JIT the allocation info if we haven't done it, or the user forces us to.
- bool do_refresh = alloc->shouldRefresh() || recompute;
+ // index will only be zero if we want to print all allocations
+ if (index != 0 && index != alloc->id)
+ continue;
// JIT current allocation information
- if (do_refresh && !RefreshAllocation(alloc.get(), frame_ptr))
+ if (alloc->shouldRefresh() && !RefreshAllocation(alloc.get(), frame_ptr))
{
- strm.Printf("Error: Couldn't evaluate details for allocation %u\n", alloc->id);
+ strm.Printf("Error: Couldn't evaluate details for allocation %" PRIu32, alloc->id);
+ strm.EOL();
continue;
}
- strm.Printf("%u:\n",alloc->id);
+ strm.Printf("%" PRIu32 ":", alloc->id);
+ strm.EOL();
strm.IndentMore();
strm.Indent("Context: ");
@@ -2887,9 +3105,8 @@ RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool r
if (!alloc->dimension.isValid())
strm.Printf("unknown\n");
else
- strm.Printf("(%d, %d, %d)\n", alloc->dimension.get()->dim_1,
- alloc->dimension.get()->dim_2,
- alloc->dimension.get()->dim_3);
+ strm.Printf("(%" PRId32 ", %" PRId32 ", %" PRId32 ")\n",
+ alloc->dimension.get()->dim_1, alloc->dimension.get()->dim_2, alloc->dimension.get()->dim_3);
strm.Indent("Data Type: ");
if (!alloc->element.type.isValid() || !alloc->element.type_vec_size.isValid())
@@ -2905,13 +3122,16 @@ RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool r
{
// Enum value isn't monotonous, so doesn't always index RsDataTypeToString array
if (type >= Element::RS_TYPE_ELEMENT && type <= Element::RS_TYPE_FONT)
- type = static_cast<Element::DataType>((type - Element::RS_TYPE_ELEMENT) + Element::RS_TYPE_MATRIX_2X2 + 1);
+ type = static_cast<Element::DataType>((type - Element::RS_TYPE_ELEMENT) +
+ Element::RS_TYPE_MATRIX_2X2 + 1);
- if (type >= (sizeof(AllocationDetails::RsDataTypeToString) / sizeof(AllocationDetails::RsDataTypeToString[0]))
- || vector_size > 4 || vector_size < 1)
+ if (type >= (sizeof(AllocationDetails::RsDataTypeToString) /
+ sizeof(AllocationDetails::RsDataTypeToString[0])) ||
+ vector_size > 4 || vector_size < 1)
strm.Printf("invalid type\n");
else
- strm.Printf("%s\n", AllocationDetails::RsDataTypeToString[static_cast<unsigned int>(type)][vector_size-1]);
+ strm.Printf("%s\n", AllocationDetails::RsDataTypeToString[static_cast<uint32_t>(type)]
+ [vector_size - 1]);
}
}
@@ -2924,7 +3144,7 @@ RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool r
if (kind < Element::RS_KIND_USER || kind > Element::RS_KIND_PIXEL_YUV)
strm.Printf("invalid kind\n");
else
- strm.Printf("%s\n", AllocationDetails::RsDataKindToString[static_cast<unsigned int>(kind)]);
+ strm.Printf("%s\n", AllocationDetails::RsDataKindToString[static_cast<uint32_t>(kind)]);
}
strm.EOL();
@@ -2955,7 +3175,7 @@ RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp
void
RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
{
- Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
InitSearchFilter(target);
@@ -2968,29 +3188,28 @@ RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
BreakOnModuleKernels(module);
if (log)
- log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)"
- "- breakpoints set on all currently loaded kernels");
+ log->Printf("%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("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set");
+ log->Printf("%s(False) - breakpoints no longer automatically set.", __FUNCTION__);
}
}
// Given the name of a kernel this function creates a breakpoint using our
// own breakpoint resolver, and returns the Breakpoint shared pointer.
BreakpointSP
-RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
+RenderScriptRuntime::CreateKernelBreakpoint(const ConstString &name)
{
- Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
if (!m_filtersp)
{
if (log)
- log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set");
+ log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
return nullptr;
}
@@ -3000,7 +3219,7 @@ RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
// Give RS breakpoints a specific name, so the user can manipulate them as a group.
Error err;
if (!bp->AddName("RenderScriptKernel", err) && log)
- log->Printf("RenderScriptRuntime::CreateKernelBreakpoint: Error setting break name, %s", err.AsCString());
+ log->Printf("%s - error setting break name, '%s'.", __FUNCTION__, err.AsCString());
return bp;
}
@@ -3009,41 +3228,113 @@ RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
// If this is possible it returns true and sets the uint64_t parameter to the variables unsigned value.
// Otherwise function returns false.
bool
-RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, const char* var_name, uint64_t& val)
+RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, const char *var_name, uint64_t &val)
{
- Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
Error error;
VariableSP var_sp;
// Find variable in stack frame
- ValueObjectSP value_sp(frame_sp->GetValueForVariableExpressionPath(var_name,
- eNoDynamicValues,
- StackFrame::eExpressionPathOptionCheckPtrVsMember |
- StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
- var_sp,
- error));
+ ValueObjectSP value_sp(frame_sp->GetValueForVariableExpressionPath(
+ var_name, eNoDynamicValues,
+ StackFrame::eExpressionPathOptionCheckPtrVsMember | StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
+ var_sp, error));
if (!error.Success())
{
if (log)
- log->Printf("RenderScriptRuntime::GetFrameVarAsUnsigned - Error, couldn't find '%s' in frame", var_name);
-
+ log->Printf("%s - error, couldn't find '%s' in frame", __FUNCTION__, var_name);
return false;
}
- // Find the unsigned int value for the variable
+ // Find the uint32_t value for the variable
bool success = false;
val = value_sp->GetValueAsUnsigned(0, &success);
if (!success)
{
if (log)
- log->Printf("RenderScriptRuntime::GetFrameVarAsUnsigned - Error, couldn't parse '%s' as an unsigned int", var_name);
-
+ log->Printf("%s - error, couldn't parse '%s' as an uint32_t.", __FUNCTION__, var_name);
return false;
}
return true;
}
+// Function attempts to find the current coordinate of a kernel invocation by investigating the
+// values of frame variables in the .expand function. These coordinates are returned via the coord
+// array reference parameter. Returns true if the coordinates could be found, and false otherwise.
+bool
+RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord, Thread *thread_ptr)
+{
+ static const std::string s_runtimeExpandSuffix(".expand");
+ static const std::array<const char *, 3> s_runtimeCoordVars{{"rsIndex", "p->current.y", "p->current.z"}};
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+ if (!thread_ptr)
+ {
+ if (log)
+ log->Printf("%s - Error, No thread pointer", __FUNCTION__);
+
+ return false;
+ }
+
+ // Walk the call stack looking for a function whose name has the suffix '.expand'
+ // and contains the variables we're looking for.
+ for (uint32_t i = 0; i < thread_ptr->GetStackFrameCount(); ++i)
+ {
+ if (!thread_ptr->SetSelectedFrameByIndex(i))
+ continue;
+
+ StackFrameSP frame_sp = thread_ptr->GetSelectedFrame();
+ if (!frame_sp)
+ continue;
+
+ // Find the function name
+ const SymbolContext sym_ctx = frame_sp->GetSymbolContext(false);
+ const char *func_name_cstr = sym_ctx.GetFunctionName().AsCString();
+ if (!func_name_cstr)
+ continue;
+
+ if (log)
+ log->Printf("%s - Inspecting function '%s'", __FUNCTION__, func_name_cstr);
+
+ // Check if function name has .expand suffix
+ std::string func_name(func_name_cstr);
+ const int length_difference = func_name.length() - s_runtimeExpandSuffix.length();
+ if (length_difference <= 0)
+ continue;
+
+ const int32_t has_expand_suffix = func_name.compare(length_difference,
+ s_runtimeExpandSuffix.length(),
+ s_runtimeExpandSuffix);
+
+ if (has_expand_suffix != 0)
+ continue;
+
+ if (log)
+ log->Printf("%s - Found .expand function '%s'", __FUNCTION__, func_name_cstr);
+
+ // Get values for variables in .expand frame that tell us the current kernel invocation
+ bool found_coord_variables = true;
+ assert(s_runtimeCoordVars.size() == coord.size());
+
+ for (uint32_t i = 0; i < coord.size(); ++i)
+ {
+ uint64_t value = 0;
+ if (!GetFrameVarAsUnsigned(frame_sp, s_runtimeCoordVars[i], value))
+ {
+ found_coord_variables = false;
+ break;
+ }
+ coord[i] = value;
+ }
+
+ if (found_coord_variables)
+ return true;
+ }
+ return false;
+}
+
// Callback when a kernel breakpoint hits and we're looking for a specific coordinate.
// Baton parameter contains a pointer to the target coordinate we want to break on.
// Function then checks the .expand frame for the current coordinate and breaks to user if it matches.
@@ -3051,61 +3342,46 @@ RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, const ch
// Parameter 'break_loc_id' is the id for the BreakpointLocation which was hit,
// a single logical breakpoint can have multiple addresses.
bool
-RenderScriptRuntime::KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx,
- user_id_t break_id, user_id_t break_loc_id)
+RenderScriptRuntime::KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, user_id_t break_id,
+ user_id_t break_loc_id)
{
- Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
assert(baton && "Error: null baton in conditional kernel breakpoint callback");
// Coordinate we want to stop on
- const int* target_coord = static_cast<const int*>(baton);
+ const uint32_t *target_coord = static_cast<const uint32_t *>(baton);
if (log)
- log->Printf("RenderScriptRuntime::KernelBreakpointHit - Break ID %" PRIu64 ", target coord (%d, %d, %d)",
- break_id, target_coord[0], target_coord[1], target_coord[2]);
+ log->Printf("%s - Break ID %" PRIu64 ", (%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", __FUNCTION__, break_id,
+ target_coord[0], target_coord[1], target_coord[2]);
- // Go up one stack frame to .expand kernel
+ // Select current thread
ExecutionContext context(ctx->exe_ctx_ref);
- ThreadSP thread_sp = context.GetThreadSP();
- if (!thread_sp->SetSelectedFrameByIndex(1))
- {
- if (log)
- log->Printf("RenderScriptRuntime::KernelBreakpointHit - Error, couldn't go up stack frame");
-
- return false;
- }
+ Thread *thread_ptr = context.GetThreadPtr();
+ assert(thread_ptr && "Null thread pointer");
- StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
- if (!frame_sp)
+ // Find current kernel invocation from .expand frame variables
+ RSCoordinate current_coord{}; // Zero initialise array
+ if (!GetKernelCoordinate(current_coord, thread_ptr))
{
if (log)
- log->Printf("RenderScriptRuntime::KernelBreakpointHit - Error, couldn't select .expand stack frame");
-
+ log->Printf("%s - Error, couldn't select .expand stack frame", __FUNCTION__);
return false;
}
- // Get values for variables in .expand frame that tell us the current kernel invocation
- const char* coord_expressions[] = {"rsIndex", "p->current.y", "p->current.z"};
- uint64_t current_coord[3] = {0, 0, 0};
-
- for(int i = 0; i < 3; ++i)
- {
- if (!GetFrameVarAsUnsigned(frame_sp, coord_expressions[i], current_coord[i]))
- return false;
-
- if (log)
- log->Printf("RenderScriptRuntime::KernelBreakpointHit, %s = %" PRIu64, coord_expressions[i], current_coord[i]);
- }
+ if (log)
+ log->Printf("%s - (%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", __FUNCTION__, current_coord[0], current_coord[1],
+ current_coord[2]);
// Check if the current kernel invocation coordinate matches our target coordinate
- if (current_coord[0] == static_cast<uint64_t>(target_coord[0]) &&
- current_coord[1] == static_cast<uint64_t>(target_coord[1]) &&
- current_coord[2] == static_cast<uint64_t>(target_coord[2]))
+ if (current_coord[0] == target_coord[0] &&
+ current_coord[1] == target_coord[1] &&
+ current_coord[2] == target_coord[2])
{
if (log)
- log->Printf("RenderScriptRuntime::KernelBreakpointHit, BREAKING %" PRIu64 ", %" PRIu64 ", %" PRIu64,
- current_coord[0], current_coord[1], current_coord[2]);
+ log->Printf("%s, BREAKING (%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", __FUNCTION__, current_coord[0],
+ current_coord[1], current_coord[2]);
BreakpointSP breakpoint_sp = context.GetTargetPtr()->GetBreakpointByID(break_id);
assert(breakpoint_sp != nullptr && "Error: Couldn't find breakpoint matching break id for callback");
@@ -3121,8 +3397,8 @@ RenderScriptRuntime::KernelBreakpointHit(void *baton, StoppointCallbackContext *
// Argument 'coords', represents a three dimensional coordinate which can be used to specify
// a single kernel instance to break on. If this is set then we add a callback to the breakpoint.
void
-RenderScriptRuntime::PlaceBreakpointOnKernel(Stream &strm, const char* name, const std::array<int,3> coords,
- Error& error, TargetSP target)
+RenderScriptRuntime::PlaceBreakpointOnKernel(Stream &strm, const char *name, const std::array<int, 3> coords,
+ Error &error, TargetSP target)
{
if (!name)
{
@@ -3138,11 +3414,12 @@ RenderScriptRuntime::PlaceBreakpointOnKernel(Stream &strm, const char* name, con
// We have a conditional breakpoint on a specific coordinate
if (coords[0] != -1)
{
- strm.Printf("Conditional kernel breakpoint on coordinate %d, %d, %d", coords[0], coords[1], coords[2]);
+ strm.Printf("Conditional kernel breakpoint on coordinate %" PRId32 ", %" PRId32 ", %" PRId32,
+ coords[0], coords[1], coords[2]);
strm.EOL();
// Allocate memory for the baton, and copy over coordinate
- int* baton = new int[3];
+ uint32_t *baton = new uint32_t[coords.size()];
baton[0] = coords[0]; baton[1] = coords[1]; baton[2] = coords[2];
// Create a callback that will be invoked everytime the breakpoint is hit.
@@ -3150,7 +3427,7 @@ RenderScriptRuntime::PlaceBreakpointOnKernel(Stream &strm, const char* name, con
bp->SetCallback(KernelBreakpointHit, baton, true);
// Store a shared pointer to the baton, so the memory will eventually be cleaned up after destruction
- m_conditional_breaks[bp->GetID()] = std::shared_ptr<int>(baton);
+ m_conditional_breaks[bp->GetID()] = std::shared_ptr<uint32_t>(baton);
}
if (bp)
@@ -3170,10 +3447,10 @@ RenderScriptRuntime::DumpModules(Stream &strm) const
strm.IndentLess();
}
-RenderScriptRuntime::ScriptDetails*
+RenderScriptRuntime::ScriptDetails *
RenderScriptRuntime::LookUpScript(addr_t address, bool create)
{
- for (const auto & s : m_scripts)
+ for (const auto &s : m_scripts)
{
if (s->script.isValid())
if (*s->script == address)
@@ -3189,10 +3466,10 @@ RenderScriptRuntime::LookUpScript(addr_t address, bool create)
return nullptr;
}
-RenderScriptRuntime::AllocationDetails*
+RenderScriptRuntime::AllocationDetails *
RenderScriptRuntime::LookUpAllocation(addr_t address, bool create)
{
- for (const auto & a : m_allocations)
+ for (const auto &a : m_allocations)
{
if (a->address.isValid())
if (*a->address == address)
@@ -3213,7 +3490,7 @@ RSModuleDescriptor::Dump(Stream &strm) const
{
strm.Indent();
m_module->GetFileSpec().Dump(&strm);
- if(m_module->GetNumCompileUnits())
+ if (m_module->GetNumCompileUnits())
{
strm.Indent("Debug info loaded.");
}
@@ -3240,7 +3517,7 @@ RSModuleDescriptor::Dump(Stream &strm) const
{
kernel.Dump(strm);
}
- strm.Printf("Pragmas: %" PRIu64 , static_cast<uint64_t>(m_pragmas.size()));
+ strm.Printf("Pragmas: %" PRIu64, static_cast<uint64_t>(m_pragmas.size()));
strm.EOL();
strm.IndentMore();
for (const auto &key_val : m_pragmas)
@@ -3261,7 +3538,7 @@ RSGlobalDescriptor::Dump(Stream &strm) const
{
auto var = var_list.GetVariableAtIndex(0);
auto type = var->GetType();
- if(type)
+ if (type)
{
strm.Printf(" - ");
type->DumpTypeName(&strm);
@@ -3274,7 +3551,7 @@ RSGlobalDescriptor::Dump(Stream &strm) const
else
{
strm.Printf(" - variable identified, but not found in binary");
- const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
+ const Symbol *s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
if (s)
{
strm.Printf(" (symbol exists) ");
@@ -3291,44 +3568,6 @@ RSKernelDescriptor::Dump(Stream &strm) const
strm.EOL();
}
-class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed
-{
-public:
- CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript module probe",
- "Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
- "renderscript module probe",
- eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched)
- {
- }
-
- ~CommandObjectRenderScriptRuntimeModuleProbe() override = default;
-
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- Target *target = m_exe_ctx.GetTargetPtr();
- RenderScriptRuntime *runtime =
- (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
- auto module_list = target->GetImages();
- bool new_rs_details = runtime->ProbeModules(module_list);
- if (new_rs_details)
- {
- result.AppendMessage("New renderscript modules added to runtime model.");
- }
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
-
- result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-};
-
class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
{
public:
@@ -3356,10 +3595,9 @@ class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword
{
public:
CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.",
- NULL)
+ : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with RenderScript modules.",
+ nullptr)
{
- LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter)));
LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter)));
}
@@ -3371,8 +3609,8 @@ class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed
public:
CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "renderscript kernel list",
- "Lists renderscript kernel names and associated script resources.", "renderscript kernel list",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched)
+ "Lists renderscript kernel names and associated script resources.",
+ "renderscript kernel list", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
{
}
@@ -3394,14 +3632,16 @@ class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObject
public:
CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "renderscript kernel breakpoint set",
- "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name> [-c x,y,z]",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), m_options(interpreter)
+ "Sets a breakpoint on a renderscript kernel.",
+ "renderscript kernel breakpoint set <kernel_name> [-c x,y,z]",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options(interpreter)
{
}
~CommandObjectRenderScriptRuntimeKernelBreakpointSet() override = default;
- Options*
+ Options *
GetOptions() override
{
return &m_options;
@@ -3410,9 +3650,7 @@ public:
class CommandOptions : public Options
{
public:
- CommandOptions(CommandInterpreter &interpreter) : Options(interpreter)
- {
- }
+ CommandOptions(CommandInterpreter &interpreter) : Options(interpreter) {}
~CommandOptions() override = default;
@@ -3426,7 +3664,8 @@ public:
{
case 'c':
if (!ParseCoordinate(option_arg))
- error.SetErrorStringWithFormat("Couldn't parse coordinate '%s', should be in format 'x,y,z'.", option_arg);
+ error.SetErrorStringWithFormat("Couldn't parse coordinate '%s', should be in format 'x,y,z'.",
+ option_arg);
break;
default:
error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
@@ -3439,23 +3678,23 @@ public:
// Where 'id_cstr' is this argument with the whitespace trimmed.
// Missing coordinates are defaulted to zero.
bool
- ParseCoordinate(const char* id_cstr)
+ ParseCoordinate(const char *id_cstr)
{
RegularExpression regex;
RegularExpression::Match regex_match(3);
bool matched = false;
- if(regex.Compile("^([0-9]+),([0-9]+),([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
+ if (regex.Compile("^([0-9]+),([0-9]+),([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
matched = true;
- else if(regex.Compile("^([0-9]+),([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
+ else if (regex.Compile("^([0-9]+),([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
matched = true;
- else if(regex.Compile("^([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
+ else if (regex.Compile("^([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
matched = true;
- for(uint32_t i = 0; i < 3; i++)
+ for (uint32_t i = 0; i < 3; i++)
{
std::string group;
- if(regex_match.GetMatchAtIndex(id_cstr, i + 1, group))
- m_coord[i] = (uint32_t)strtoul(group.c_str(), NULL, 0);
+ if (regex_match.GetMatchAtIndex(id_cstr, i + 1, group))
+ m_coord[i] = (uint32_t)strtoul(group.c_str(), nullptr, 0);
else
m_coord[i] = 0;
}
@@ -3471,14 +3710,14 @@ public:
m_coord[2] = -1;
}
- const OptionDefinition*
+ const OptionDefinition *
GetDefinitions() override
{
return g_option_table;
}
static OptionDefinition g_option_table[];
- std::array<int,3> m_coord;
+ std::array<int, 3> m_coord;
};
bool
@@ -3487,13 +3726,14 @@ public:
const size_t argc = command.GetArgumentCount();
if (argc < 1)
{
- result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name, and an optional coordinate.", m_cmd_name.c_str());
+ result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name, and an optional coordinate.",
+ m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
RenderScriptRuntime *runtime =
- (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
+ (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
Error error;
runtime->PlaceBreakpointOnKernel(result.GetOutputStream(), command.GetArgumentAtIndex(0), m_options.m_coord,
@@ -3514,26 +3754,24 @@ private:
CommandOptions m_options;
};
-OptionDefinition
-CommandObjectRenderScriptRuntimeKernelBreakpointSet::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeValue,
- "Set a breakpoint on a single invocation of the kernel with specified coordinate.\n"
- "Coordinate takes the form 'x[,y][,z] where x,y,z are positive integers representing kernel dimensions. "
- "Any unset dimensions will be defaulted to zero."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
-};
+OptionDefinition CommandObjectRenderScriptRuntimeKernelBreakpointSet::CommandOptions::g_option_table[] = {
+ {LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeValue,
+ "Set a breakpoint on a single invocation of the kernel with specified coordinate.\n"
+ "Coordinate takes the form 'x[,y][,z] where x,y,z are positive integers representing kernel dimensions. "
+ "Any unset dimensions will be defaulted to zero."},
+ {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}};
class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed
{
public:
CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all",
- "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
- "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
- "but does not remove currently set breakpoints.",
- "renderscript kernel breakpoint all <enable/disable>",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
+ : CommandObjectParsed(
+ interpreter, "renderscript kernel breakpoint all",
+ "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
+ "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
+ "but does not remove currently set breakpoints.",
+ "renderscript kernel breakpoint all <enable/disable>",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
{
}
@@ -3550,11 +3788,11 @@ public:
return false;
}
- RenderScriptRuntime *runtime =
- static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
bool do_break = false;
- const char* argument = command.GetArgumentAtIndex(0);
+ const char *argument = command.GetArgumentAtIndex(0);
if (strcmp(argument, "enable") == 0)
{
do_break = true;
@@ -3579,12 +3817,48 @@ public:
}
};
+class CommandObjectRenderScriptRuntimeKernelCoordinate : public CommandObjectParsed
+{
+public:
+ CommandObjectRenderScriptRuntimeKernelCoordinate(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "renderscript kernel coordinate",
+ "Shows the (x,y,z) coordinate of the current kernel invocation.",
+ "renderscript kernel coordinate",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
+ {
+ }
+
+ ~CommandObjectRenderScriptRuntimeKernelCoordinate() override = default;
+
+ bool
+ DoExecute(Args &command, CommandReturnObject &result) override
+ {
+ RSCoordinate coord{}; // Zero initialize array
+ bool success = RenderScriptRuntime::GetKernelCoordinate(coord, m_exe_ctx.GetThreadPtr());
+ Stream &stream = result.GetOutputStream();
+
+ if (success)
+ {
+ stream.Printf("Coordinate: (%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", coord[0], coord[1], coord[2]);
+ stream.EOL();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ stream.Printf("Error: Coordinate could not be found.");
+ stream.EOL();
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return true;
+ }
+};
+
class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword
{
public:
CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.",
- nullptr)
+ : CommandObjectMultiword(interpreter, "renderscript kernel",
+ "Commands that generate breakpoints on renderscript kernels.", nullptr)
{
LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter)));
LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter)));
@@ -3597,11 +3871,14 @@ class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword
{
public:
CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.",
- NULL)
+ : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with RenderScript kernels.",
+ nullptr)
{
LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter)));
- LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
+ LoadSubCommand("coordinate",
+ CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelCoordinate(interpreter)));
+ LoadSubCommand("breakpoint",
+ CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
}
~CommandObjectRenderScriptRuntimeKernel() override = default;
@@ -3611,9 +3888,8 @@ class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed
{
public:
CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript context dump",
- "Dumps renderscript context information.", "renderscript context dump",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched)
+ : CommandObjectParsed(interpreter, "renderscript context dump", "Dumps renderscript context information.",
+ "renderscript context dump", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
{
}
@@ -3634,8 +3910,8 @@ class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword
{
public:
CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.",
- NULL)
+ : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with RenderScript contexts.",
+ nullptr)
{
LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter)));
}
@@ -3649,13 +3925,14 @@ public:
CommandObjectRenderScriptRuntimeAllocationDump(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "renderscript allocation dump",
"Displays the contents of a particular allocation", "renderscript allocation dump <ID>",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter)
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched),
+ m_options(interpreter)
{
}
~CommandObjectRenderScriptRuntimeAllocationDump() override = default;
- Options*
+ Options *
GetOptions() override
{
return &m_options;
@@ -3664,9 +3941,7 @@ public:
class CommandOptions : public Options
{
public:
- CommandOptions(CommandInterpreter &interpreter) : Options(interpreter)
- {
- }
+ CommandOptions(CommandInterpreter &interpreter) : Options(interpreter) {}
~CommandOptions() override = default;
@@ -3699,7 +3974,7 @@ public:
m_outfile.Clear();
}
- const OptionDefinition*
+ const OptionDefinition *
GetDefinitions() override
{
return g_option_table;
@@ -3721,10 +3996,10 @@ public:
return false;
}
- RenderScriptRuntime *runtime =
- static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
- const char* id_cstr = command.GetArgumentAtIndex(0);
+ const char *id_cstr = command.GetArgumentAtIndex(0);
bool convert_complete = false;
const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
if (!convert_complete)
@@ -3734,7 +4009,7 @@ public:
return false;
}
- Stream* output_strm = nullptr;
+ Stream *output_strm = nullptr;
StreamFile outfile_stream;
const FileSpec &outfile_spec = m_options.m_outfile; // Dump allocation to file instead
if (outfile_spec)
@@ -3773,13 +4048,10 @@ private:
CommandOptions m_options;
};
-OptionDefinition
-CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename,
- "Print results to specified file instead of command line."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
-};
+OptionDefinition CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions::g_option_table[] = {
+ {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename,
+ "Print results to specified file instead of command line."},
+ {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}};
class CommandObjectRenderScriptRuntimeAllocationList : public CommandObjectParsed
{
@@ -3787,13 +4059,14 @@ public:
CommandObjectRenderScriptRuntimeAllocationList(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "renderscript allocation list",
"List renderscript allocations and their information.", "renderscript allocation list",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter)
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched),
+ m_options(interpreter)
{
}
~CommandObjectRenderScriptRuntimeAllocationList() override = default;
- Options*
+ Options *
GetOptions() override
{
return &m_options;
@@ -3802,9 +4075,7 @@ public:
class CommandOptions : public Options
{
public:
- CommandOptions(CommandInterpreter &interpreter) : Options(interpreter), m_refresh(false)
- {
- }
+ CommandOptions(CommandInterpreter &interpreter) : Options(interpreter), m_id(0) {}
~CommandOptions() override = default;
@@ -3816,8 +4087,11 @@ public:
switch (short_option)
{
- case 'r':
- m_refresh = true;
+ case 'i':
+ bool success;
+ m_id = StringConvert::ToUInt32(option_arg, 0, 0, &success);
+ if (!success)
+ error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
break;
default:
error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
@@ -3829,25 +4103,25 @@ public:
void
OptionParsingStarting() override
{
- m_refresh = false;
+ m_id = 0;
}
- const OptionDefinition*
+ const OptionDefinition *
GetDefinitions() override
{
return g_option_table;
}
static OptionDefinition g_option_table[];
- bool m_refresh;
+ uint32_t m_id;
};
bool
DoExecute(Args &command, CommandReturnObject &result) override
{
- RenderScriptRuntime *runtime =
- static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
- runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), m_options.m_refresh);
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+ runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), m_options.m_id);
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
@@ -3856,21 +4130,18 @@ private:
CommandOptions m_options;
};
-OptionDefinition
-CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "refresh", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
- "Recompute allocation details."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
-};
+OptionDefinition CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::g_option_table[] = {
+ {LLDB_OPT_SET_1, false, "id", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex,
+ "Only show details of a single allocation with specified id."},
+ {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}};
class CommandObjectRenderScriptRuntimeAllocationLoad : public CommandObjectParsed
{
public:
CommandObjectRenderScriptRuntimeAllocationLoad(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript allocation load",
- "Loads renderscript allocation contents from a file.", "renderscript allocation load <ID> <filename>",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched)
+ : CommandObjectParsed(
+ interpreter, "renderscript allocation load", "Loads renderscript allocation contents from a file.",
+ "renderscript allocation load <ID> <filename>", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
{
}
@@ -3882,25 +4153,26 @@ public:
const size_t argc = command.GetArgumentCount();
if (argc != 2)
{
- result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str());
+ result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.",
+ m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
- RenderScriptRuntime *runtime =
- static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
- const char* id_cstr = command.GetArgumentAtIndex(0);
+ const char *id_cstr = command.GetArgumentAtIndex(0);
bool convert_complete = false;
const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
if (!convert_complete)
{
- result.AppendErrorWithFormat ("invalid allocation id argument '%s'", id_cstr);
- result.SetStatus (eReturnStatusFailed);
+ result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr);
+ result.SetStatus(eReturnStatusFailed);
return false;
}
- const char* filename = command.GetArgumentAtIndex(1);
+ const char *filename = command.GetArgumentAtIndex(1);
bool success = runtime->LoadAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr());
if (success)
@@ -3916,9 +4188,9 @@ class CommandObjectRenderScriptRuntimeAllocationSave : public CommandObjectParse
{
public:
CommandObjectRenderScriptRuntimeAllocationSave(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript allocation save",
- "Write renderscript allocation contents to a file.", "renderscript allocation save <ID> <filename>",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched)
+ : CommandObjectParsed(
+ interpreter, "renderscript allocation save", "Write renderscript allocation contents to a file.",
+ "renderscript allocation save <ID> <filename>", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
{
}
@@ -3930,25 +4202,26 @@ public:
const size_t argc = command.GetArgumentCount();
if (argc != 2)
{
- result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str());
+ result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.",
+ m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
- RenderScriptRuntime *runtime =
- static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
- const char* id_cstr = command.GetArgumentAtIndex(0);
+ const char *id_cstr = command.GetArgumentAtIndex(0);
bool convert_complete = false;
const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
if (!convert_complete)
{
- result.AppendErrorWithFormat ("invalid allocation id argument '%s'", id_cstr);
- result.SetStatus (eReturnStatusFailed);
+ result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr);
+ result.SetStatus(eReturnStatusFailed);
return false;
}
- const char* filename = command.GetArgumentAtIndex(1);
+ const char *filename = command.GetArgumentAtIndex(1);
bool success = runtime->SaveAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr());
if (success)
@@ -3960,17 +4233,51 @@ public:
}
};
+class CommandObjectRenderScriptRuntimeAllocationRefresh : public CommandObjectParsed
+{
+public:
+ CommandObjectRenderScriptRuntimeAllocationRefresh(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "renderscript allocation refresh",
+ "Recomputes the details of all allocations.", "renderscript allocation refresh",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched)
+ {
+ }
+
+ ~CommandObjectRenderScriptRuntimeAllocationRefresh() override = default;
+
+ bool
+ DoExecute(Args &command, CommandReturnObject &result) override
+ {
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+
+ bool success = runtime->RecomputeAllAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr());
+
+ if (success)
+ {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ else
+ {
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+};
+
class CommandObjectRenderScriptRuntimeAllocation : public CommandObjectMultiword
{
public:
CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript allocation", "Commands that deal with renderscript allocations.",
- NULL)
+ : CommandObjectMultiword(interpreter, "renderscript allocation",
+ "Commands that deal with RenderScript allocations.", nullptr)
{
LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationList(interpreter)));
LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationDump(interpreter)));
LoadSubCommand("save", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationSave(interpreter)));
LoadSubCommand("load", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationLoad(interpreter)));
+ LoadSubCommand("refresh", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationRefresh(interpreter)));
}
~CommandObjectRenderScriptRuntimeAllocation() override = default;
@@ -3980,9 +4287,8 @@ class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed
{
public:
CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript status",
- "Displays current renderscript runtime status.", "renderscript status",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched)
+ : CommandObjectParsed(interpreter, "renderscript status", "Displays current RenderScript runtime status.",
+ "renderscript status", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
{
}
@@ -4003,7 +4309,7 @@ class CommandObjectRenderScriptRuntime : public CommandObjectMultiword
{
public:
CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.",
+ : CommandObjectMultiword(interpreter, "renderscript", "Commands for operating on the RenderScript runtime.",
"renderscript <subcommand> [<subcommand-options>]")
{
LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter)));
@@ -4023,21 +4329,18 @@ RenderScriptRuntime::Initiate()
}
RenderScriptRuntime::RenderScriptRuntime(Process *process)
- : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false),
+ : lldb_private::CPPLanguageRuntime(process),
+ m_initiated(false),
+ m_debuggerPresentFlagged(false),
m_breakAllKernels(false)
{
ModulesDidLoad(process->GetTarget().GetImages());
}
lldb::CommandObjectSP
-RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter)
+RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter &interpreter)
{
- static CommandObjectSP command_object;
- if(!command_object)
- {
- command_object.reset(new CommandObjectRenderScriptRuntime(interpreter));
- }
- return command_object;
+ return CommandObjectSP(new CommandObjectRenderScriptRuntime(interpreter));
}
RenderScriptRuntime::~RenderScriptRuntime() = default;
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
index 2fe439017bbc..2a0839a1a78b 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
@@ -20,13 +20,15 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/LanguageRuntime.h"
-#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Core/Module.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/lldb-private.h"
-namespace lldb_private {
-namespace lldb_renderscript {
+namespace lldb_private
+{
+namespace lldb_renderscript
+{
typedef uint32_t RSSlot;
class RSModuleDescriptor;
@@ -36,6 +38,7 @@ struct RSKernelDescriptor;
typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP;
typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP;
typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
+typedef std::array<uint32_t, 3> RSCoordinate;
// Breakpoint Resolvers decide where a breakpoint is placed,
// so having our own allows us to limit the search scope to RS kernel modules.
@@ -43,9 +46,8 @@ typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
class RSBreakpointResolver : public BreakpointResolver
{
public:
- RSBreakpointResolver(Breakpoint *bkpt, ConstString name):
- BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
- m_kernel_name(name)
+ RSBreakpointResolver(Breakpoint *bkpt, ConstString name)
+ : BreakpointResolver(bkpt, BreakpointResolver::NameResolver), m_kernel_name(name)
{
}
@@ -62,10 +64,7 @@ public:
}
Searcher::CallbackReturn
- SearchCallback(SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool containing) override;
+ SearchCallback(SearchFilter &filter, SymbolContext &context, Address *addr, bool containing) override;
Searcher::Depth
GetDepth() override
@@ -88,13 +87,12 @@ struct RSKernelDescriptor
{
public:
RSKernelDescriptor(const RSModuleDescriptor *module, const char *name, uint32_t slot)
- : m_module(module)
- , m_name(name)
- , m_slot(slot)
+ : m_module(module), m_name(name), m_slot(slot)
{
}
- void Dump(Stream &strm) const;
+ void
+ Dump(Stream &strm) const;
const RSModuleDescriptor *m_module;
ConstString m_name;
@@ -104,13 +102,10 @@ public:
struct RSGlobalDescriptor
{
public:
- RSGlobalDescriptor(const RSModuleDescriptor *module, const char *name )
- : m_module(module)
- , m_name(name)
- {
- }
+ RSGlobalDescriptor(const RSModuleDescriptor *module, const char *name) : m_module(module), m_name(name) {}
- void Dump(Stream &strm) const;
+ void
+ Dump(Stream &strm) const;
const RSModuleDescriptor *m_module;
ConstString m_name;
@@ -119,16 +114,15 @@ public:
class RSModuleDescriptor
{
public:
- RSModuleDescriptor(const lldb::ModuleSP &module)
- : m_module(module)
- {
- }
+ RSModuleDescriptor(const lldb::ModuleSP &module) : m_module(module) {}
~RSModuleDescriptor() = default;
- bool ParseRSInfo();
+ bool
+ ParseRSInfo();
- void Dump(Stream &strm) const;
+ void
+ Dump(Stream &strm) const;
const lldb::ModuleSP m_module;
std::vector<RSKernelDescriptor> m_kernels;
@@ -156,105 +150,144 @@ public:
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
- static void Initialize();
+ static void
+ Initialize();
- static void Terminate();
+ static void
+ Terminate();
- static lldb_private::LanguageRuntime *CreateInstance(Process *process, lldb::LanguageType language);
+ static lldb_private::LanguageRuntime *
+ CreateInstance(Process *process, lldb::LanguageType language);
- static lldb::CommandObjectSP GetCommandObject(CommandInterpreter& interpreter);
+ static lldb::CommandObjectSP
+ GetCommandObject(CommandInterpreter &interpreter);
- static lldb_private::ConstString GetPluginNameStatic();
+ static lldb_private::ConstString
+ GetPluginNameStatic();
- static bool IsRenderScriptModule(const lldb::ModuleSP &module_sp);
+ static bool
+ IsRenderScriptModule(const lldb::ModuleSP &module_sp);
- static ModuleKind GetModuleKind(const lldb::ModuleSP &module_sp);
+ static ModuleKind
+ GetModuleKind(const lldb::ModuleSP &module_sp);
- static void ModulesDidLoad(const lldb::ProcessSP& process_sp, const ModuleList &module_list );
+ static void
+ ModulesDidLoad(const lldb::ProcessSP &process_sp, const ModuleList &module_list);
- bool IsVTableName(const char *name) override;
+ bool
+ IsVTableName(const char *name) override;
+
+ bool
+ GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &address,
+ Value::ValueType &value_type) override;
- bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name, Address &address,
- Value::ValueType &value_type) override;
-
TypeAndOrName
- FixUpDynamicType(const TypeAndOrName& type_and_or_name,
- ValueObject& static_value) override;
+ FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value) override;
- bool CouldHaveDynamicValue(ValueObject &in_value) override;
+ bool
+ CouldHaveDynamicValue(ValueObject &in_value) override;
- lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override;
+ lldb::BreakpointResolverSP
+ CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override;
- bool LoadModule(const lldb::ModuleSP &module_sp);
+ bool
+ LoadModule(const lldb::ModuleSP &module_sp);
- bool ProbeModules(const ModuleList module_list);
+ void
+ DumpModules(Stream &strm) const;
- void DumpModules(Stream &strm) const;
+ void
+ DumpContexts(Stream &strm) const;
- void DumpContexts(Stream &strm) const;
+ void
+ DumpKernels(Stream &strm) const;
- void DumpKernels(Stream &strm) const;
+ bool
+ DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id);
- bool DumpAllocation(Stream &strm, StackFrame* frame_ptr, const uint32_t id);
+ void
+ ListAllocations(Stream &strm, StackFrame *frame_ptr, const uint32_t index);
- void ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute);
+ bool
+ RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr);
- void PlaceBreakpointOnKernel(Stream &strm, const char *name, const std::array<int,3> coords,
- Error &error, lldb::TargetSP target);
+ void
+ PlaceBreakpointOnKernel(Stream &strm, const char *name, const std::array<int, 3> coords, Error &error,
+ lldb::TargetSP target);
- void SetBreakAllKernels(bool do_break, lldb::TargetSP target);
+ void
+ SetBreakAllKernels(bool do_break, lldb::TargetSP target);
- void Status(Stream &strm) const;
+ void
+ Status(Stream &strm) const;
- void ModulesDidLoad(const ModuleList &module_list) override;
+ void
+ ModulesDidLoad(const ModuleList &module_list) override;
- bool LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr);
+ bool
+ LoadAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr);
- bool SaveAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr);
+ bool
+ SaveAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr);
- void Update();
+ void
+ Update();
- void Initiate();
+ void
+ Initiate();
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
+ lldb_private::ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
- uint32_t GetPluginVersion() override;
+ static bool
+ GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord, Thread *thread_ptr);
protected:
struct ScriptDetails;
struct AllocationDetails;
struct Element;
- void InitSearchFilter(lldb::TargetSP target)
+ void
+ InitSearchFilter(lldb::TargetSP target)
{
if (!m_filtersp)
m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target));
}
- void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
+ void
+ FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
- void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind);
+ void
+ LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind);
- bool RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr);
+ bool
+ RefreshAllocation(AllocationDetails *allocation, StackFrame *frame_ptr);
- bool EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result);
+ bool
+ EvalRSExpression(const char *expression, StackFrame *frame_ptr, uint64_t *result);
- lldb::BreakpointSP CreateKernelBreakpoint(const ConstString& name);
+ lldb::BreakpointSP
+ CreateKernelBreakpoint(const ConstString &name);
+
+ void
+ BreakOnModuleKernels(const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
- void BreakOnModuleKernels(const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
-
struct RuntimeHook;
- typedef void (RenderScriptRuntime::*CaptureStateFn)(RuntimeHook* hook_info, ExecutionContext &context); // Please do this!
+ typedef void (RenderScriptRuntime::*CaptureStateFn)(RuntimeHook *hook_info,
+ ExecutionContext &context); // Please do this!
struct HookDefn
{
- const char * name;
- const char * symbol_name_m32; // mangled name for the 32 bit architectures
- const char * symbol_name_m64; // mangled name for the 64 bit archs
+ const char *name;
+ const char *symbol_name_m32; // mangled name for the 32 bit architectures
+ const char *symbol_name_m64; // mangled name for the 64 bit archs
uint32_t version;
ModuleKind kind;
CaptureStateFn grabber;
@@ -263,7 +296,7 @@ protected:
struct RuntimeHook
{
lldb::addr_t address;
- const HookDefn *defn;
+ const HookDefn *defn;
lldb::BreakpointSP bp_sp;
};
@@ -279,7 +312,7 @@ protected:
std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> m_scriptMappings;
std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks;
- std::map<lldb::user_id_t, std::shared_ptr<int>> m_conditional_breaks;
+ std::map<lldb::user_id_t, std::shared_ptr<uint32_t>> m_conditional_breaks;
lldb::SearchFilterSP m_filtersp; // Needed to create breakpoints through Target API
@@ -290,81 +323,93 @@ protected:
static const size_t s_runtimeHookCount;
private:
- // Used to index expression format strings
- enum ExpressionStrings
- {
- eExprGetOffsetPtr = 0,
- eExprAllocGetType,
- eExprTypeDimX,
- eExprTypeDimY,
- eExprTypeDimZ,
- eExprTypeElemPtr,
- eExprElementType,
- eExprElementKind,
- eExprElementVec,
- eExprElementFieldCount,
- eExprSubelementsId,
- eExprSubelementsName,
- eExprSubelementsArrSize
- };
-
RenderScriptRuntime(Process *process); // Call CreateInstance instead.
- static bool HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
+ static bool
+ HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
- static bool KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx,
- lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+ static bool
+ KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
- void HookCallback(RuntimeHook* hook_info, ExecutionContext& context);
+ void
+ HookCallback(RuntimeHook *hook_info, ExecutionContext &context);
- bool GetArgSimple(ExecutionContext& context, uint32_t arg, uint64_t* data);
+ void
+ CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context);
- void CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context);
- void CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context);
- void CaptureAllocationDestroy(RuntimeHook* hook_info, ExecutionContext& context);
- void CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context);
+ void
+ CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context);
+
+ void
+ CaptureAllocationDestroy(RuntimeHook *hook_info, ExecutionContext &context);
+
+ void
+ CaptureSetGlobalVar(RuntimeHook *hook_info, ExecutionContext &context);
+
+ void
+ CaptureScriptInvokeForEachMulti(RuntimeHook *hook_info, ExecutionContext &context);
+
+ AllocationDetails *
+ FindAllocByID(Stream &strm, const uint32_t alloc_id);
+
+ std::shared_ptr<uint8_t>
+ GetAllocationData(AllocationDetails *allocation, StackFrame *frame_ptr);
+
+ void
+ SetElementSize(Element &elem);
+
+ static bool
+ GetFrameVarAsUnsigned(const lldb::StackFrameSP, const char *var_name, uint64_t &val);
+
+ void
+ FindStructTypeName(Element &elem, StackFrame *frame_ptr);
- AllocationDetails* FindAllocByID(Stream &strm, const uint32_t alloc_id);
- std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails* allocation, StackFrame* frame_ptr);
- void SetElementSize(Element& elem);
- static bool GetFrameVarAsUnsigned(const lldb::StackFrameSP, const char* var_name, uint64_t& val);
- void FindStructTypeName(Element& elem, StackFrame* frame_ptr);
+ size_t
+ PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset, const Element &elem);
- size_t PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset, const Element& elem);
- size_t CalculateElementHeaderSize(const Element& elem);
+ size_t
+ CalculateElementHeaderSize(const Element &elem);
//
// Helper functions for jitting the runtime
//
- const char* JITTemplate(ExpressionStrings e);
- bool JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr,
- unsigned int x = 0, unsigned int y = 0, unsigned int z = 0);
+ bool
+ JITDataPointer(AllocationDetails *allocation, StackFrame *frame_ptr,
+ uint32_t x = 0, uint32_t y = 0, uint32_t z = 0);
- bool JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr);
+ bool
+ JITTypePointer(AllocationDetails *allocation, StackFrame *frame_ptr);
- bool JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr);
+ bool
+ JITTypePacked(AllocationDetails *allocation, StackFrame *frame_ptr);
- bool JITElementPacked(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr);
+ bool
+ JITElementPacked(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr);
- bool JITAllocationSize(AllocationDetails* allocation, StackFrame* frame_ptr);
+ bool
+ JITAllocationSize(AllocationDetails *allocation, StackFrame *frame_ptr);
- bool JITSubelements(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr);
+ bool
+ JITSubelements(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr);
- bool JITAllocationStride(AllocationDetails* allocation, StackFrame* frame_ptr);
+ bool
+ JITAllocationStride(AllocationDetails *allocation, StackFrame *frame_ptr);
// Search for a script detail object using a target address.
// If a script does not currently exist this function will return nullptr.
// If 'create' is true and there is no previous script with this address,
// then a new Script detail object will be created for this address and returned.
- ScriptDetails* LookUpScript(lldb::addr_t address, bool create);
+ ScriptDetails *
+ LookUpScript(lldb::addr_t address, bool create);
// Search for a previously saved allocation detail object using a target address.
// If an allocation does not exist for this address then nullptr will be returned.
// If 'create' is true and there is no previous allocation then a new allocation
// detail object will be created for this address and returned.
- AllocationDetails* LookUpAllocation(lldb::addr_t address, bool create);
+ AllocationDetails *
+ LookUpAllocation(lldb::addr_t address, bool create);
};
} // namespace lldb_private
diff --git a/source/Plugins/Makefile b/source/Plugins/Makefile
deleted file mode 100644
index 931f459a26b7..000000000000
--- a/source/Plugins/Makefile
+++ /dev/null
@@ -1,67 +0,0 @@
-##===- source/Plugins/Makefile -----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-
-include $(LLDB_LEVEL)/../../Makefile.config
-
-
-PARALLEL_DIRS := ABI/MacOSX-arm ABI/MacOSX-arm64 ABI/MacOSX-i386 ABI/SysV-i386 ABI/SysV-x86_64 \
- ABI/SysV-arm ABI/SysV-arm64 ABI/SysV-hexagon ABI/SysV-ppc ABI/SysV-ppc64 \
- ABI/SysV-mips ABI/SysV-mips64 Disassembler/llvm \
- ObjectContainer/BSD-Archive ObjectFile/ELF ObjectFile/PECOFF \
- ObjectContainer/Universal-Mach-O ObjectFile/Mach-O \
- ObjectFile/JIT SymbolFile/DWARF SymbolFile/Symtab Process/Utility \
- DynamicLoader/Static Platform Process/elf-core Process/gdb-remote \
- Instruction/ARM Instruction/ARM64 Instruction/MIPS Instruction/MIPS64 \
- UnwindAssembly/InstEmulation UnwindAssembly/x86 \
- LanguageRuntime/CPlusPlus/ItaniumABI \
- LanguageRuntime/ObjC/AppleObjCRuntime \
- LanguageRuntime/Go/ \
- LanguageRuntime/RenderScript/RenderScriptRuntime \
- Language/CPlusPlus \
- Language/Go \
- Language/ObjC \
- Language/ObjCPlusPlus \
- DynamicLoader/POSIX-DYLD \
- DynamicLoader/Hexagon-DYLD \
- DynamicLoader/MacOSX-DYLD \
- DynamicLoader/Windows-DYLD \
- JITLoader/GDB \
- ExpressionParser/Clang \
- ExpressionParser/Go \
- OperatingSystem/Go \
- OperatingSystem/Python \
- SystemRuntime/MacOSX \
- SymbolVendor/ELF \
- MemoryHistory/asan \
- InstrumentationRuntime/AddressSanitizer \
- ScriptInterpreter/Python ScriptInterpreter/None
-
-ifeq ($(HOST_OS),Darwin)
-PARALLEL_DIRS += Process/MacOSX-Kernel
-PARALLEL_DIRS += DynamicLoader/Darwin-Kernel
-PARALLEL_DIRS += SymbolVendor/MacOSX
-#PARALLEL_DIRS += Process/MacOSX-User
-PARALLEL_DIRS += Process/mach-core
-endif
-
-ifeq ($(HOST_OS),Linux)
-PARALLEL_DIRS += Process/Linux Process/POSIX
-endif
-
-ifneq (,$(filter $(HOST_OS), FreeBSD GNU/kFreeBSD))
-PARALLEL_DIRS += Process/FreeBSD Process/POSIX
-endif
-
-ifeq ($(HOST_OS),NetBSD)
-PARALLEL_DIRS += Process/POSIX
-endif
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/MemoryHistory/asan/Makefile b/source/Plugins/MemoryHistory/asan/Makefile
deleted file mode 100644
index 86de6aba3638..000000000000
--- a/source/Plugins/MemoryHistory/asan/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/MemoryHistory/asan/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginMemoryHistoryASan
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp b/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
index c57519871624..a9d13ac79c37 100644
--- a/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
+++ b/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
@@ -12,8 +12,10 @@
#include "lldb/Target/MemoryHistory.h"
#include "lldb/lldb-private.h"
+#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Target/ThreadList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
@@ -22,6 +24,8 @@
#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/Core/ValueObject.h"
+#include <sstream>
+
using namespace lldb;
using namespace lldb_private;
@@ -34,7 +38,7 @@ MemoryHistoryASan::CreateInstance (const ProcessSP &process_sp)
Target & target = process_sp->GetTarget();
const ModuleList &target_modules = target.GetImages();
- Mutex::Locker modules_locker(target_modules.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
const size_t num_modules = target_modules.GetSize();
for (size_t i = 0; i < num_modules; ++i)
{
@@ -80,8 +84,14 @@ MemoryHistoryASan::MemoryHistoryASan(const ProcessSP &process_sp)
}
const char *
-memory_history_asan_command_format = R"(
- struct t {
+memory_history_asan_command_prefix = R"(
+ extern "C"
+ {
+ size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size, int *thread_id);
+ size_t __asan_get_free_stack(void *addr, void **trace, size_t size, int *thread_id);
+ }
+
+ struct data {
void *alloc_trace[256];
size_t alloc_count;
int alloc_tid;
@@ -89,10 +99,15 @@ memory_history_asan_command_format = R"(
void *free_trace[256];
size_t free_count;
int free_tid;
- } t;
+ };
+)";
+
+const char *
+memory_history_asan_command_format = R"(
+ data t;
- t.alloc_count = ((size_t (*) (void *, void **, size_t, int *))__asan_get_alloc_stack)((void *)0x%)" PRIx64 R"(, t.alloc_trace, 256, &t.alloc_tid);
- t.free_count = ((size_t (*) (void *, void **, size_t, int *))__asan_get_free_stack)((void *)0x%)" PRIx64 R"(, t.free_trace, 256, &t.free_tid);
+ t.alloc_count = __asan_get_alloc_stack((void *)0x%)" PRIx64 R"(, t.alloc_trace, 256, &t.alloc_tid);
+ t.free_count = __asan_get_free_stack((void *)0x%)" PRIx64 R"(, t.free_trace, 256, &t.free_tid);
t;
)";
@@ -110,7 +125,7 @@ static void CreateHistoryThreadFromValueObject(ProcessSP process_sp, ValueObject
return;
int count = count_sp->GetValueAsUnsigned(0);
- tid_t tid = tid_sp->GetValueAsUnsigned(0);
+ tid_t tid = tid_sp->GetValueAsUnsigned(0) + 1;
if (count <= 0)
return;
@@ -131,8 +146,9 @@ static void CreateHistoryThreadFromValueObject(ProcessSP process_sp, ValueObject
HistoryThread *history_thread = new HistoryThread(*process_sp, tid, pcs, 0, false);
ThreadSP new_thread_sp(history_thread);
- // let's use thread name for the type of history thread, since history threads don't have names anyway
- history_thread->SetThreadName(thread_name);
+ std::ostringstream thread_name_with_number;
+ thread_name_with_number << thread_name << " Thread " << tid;
+ history_thread->SetThreadName(thread_name_with_number.str().c_str());
// Save this in the Process' ExtendedThreadList so a strong pointer retains the object
process_sp->GetExtendedThreadList().AddThread (new_thread_sp);
result.push_back(new_thread_sp);
@@ -146,38 +162,49 @@ MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address)
HistoryThreads result;
ProcessSP process_sp = m_process_wp.lock();
- if (process_sp)
- {
- ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread();
-
- if (thread_sp)
- {
- StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
-
- if (frame_sp)
- {
- ExecutionContext exe_ctx (frame_sp);
- ValueObjectSP return_value_sp;
- StreamString expr;
- expr.Printf(memory_history_asan_command_format, address, address);
-
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetTryAllThreads(true);
- options.SetStopOthers(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTimeoutUsec(GET_STACK_FUNCTION_TIMEOUT_USEC);
-
- if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), return_value_sp, options) == eExpressionCompleted)
- {
- if (return_value_sp)
- {
- CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "free", "Memory deallocated at", result);
- CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "alloc", "Memory allocated at", result);
- }
- }
- }
- }
+ if (! process_sp)
+ return result;
+
+ ThreadSP thread_sp = process_sp->GetThreadList().GetExpressionExecutionThread();
+ if (!thread_sp)
+ return result;
+
+ StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
+ if (!frame_sp)
+ return result;
+
+ ExecutionContext exe_ctx (frame_sp);
+ ValueObjectSP return_value_sp;
+ StreamString expr;
+ Error eval_error;
+ expr.Printf(memory_history_asan_command_format, address, address);
+
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetTryAllThreads(true);
+ options.SetStopOthers(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTimeoutUsec(GET_STACK_FUNCTION_TIMEOUT_USEC);
+ options.SetPrefix(memory_history_asan_command_prefix);
+ options.SetAutoApplyFixIts(false);
+ options.SetLanguage(eLanguageTypeObjC_plus_plus);
+
+ ExpressionResults expr_result = UserExpression::Evaluate (exe_ctx,
+ options,
+ expr.GetData(),
+ "",
+ return_value_sp,
+ eval_error);
+ if (expr_result != eExpressionCompleted) {
+ process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf("Warning: Cannot evaluate AddressSanitizer expression:\n%s\n", eval_error.AsCString());
+ return result;
}
+
+ if (!return_value_sp)
+ return result;
+
+ CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "free", "Memory deallocated by", result);
+ CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "alloc", "Memory allocated by", result);
+
return result;
}
diff --git a/source/Plugins/ObjectContainer/BSD-Archive/Makefile b/source/Plugins/ObjectContainer/BSD-Archive/Makefile
deleted file mode 100644
index 00c5911ea95f..000000000000
--- a/source/Plugins/ObjectContainer/BSD-Archive/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ObjectContainer/BSD-Archive/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginObjectContainerBSDArchive
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index f2a74b05fe26..984a9ece12ef 100644
--- a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -35,7 +35,6 @@ typedef struct ar_hdr
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/ObjectFile.h"
using namespace lldb;
@@ -226,7 +225,7 @@ ObjectContainerBSDArchive::Archive::FindObject (const ConstString &object_name,
ObjectContainerBSDArchive::Archive::shared_ptr
ObjectContainerBSDArchive::Archive::FindCachedArchive (const FileSpec &file, const ArchSpec &arch, const TimeValue &time, lldb::offset_t file_offset)
{
- Mutex::Locker locker(Archive::GetArchiveCacheMutex ());
+ std::lock_guard<std::recursive_mutex> guard(Archive::GetArchiveCacheMutex());
shared_ptr archive_sp;
Archive::Map &archive_map = Archive::GetArchiveCache ();
Archive::Map::iterator pos = archive_map.find (file);
@@ -281,7 +280,7 @@ ObjectContainerBSDArchive::Archive::ParseAndCacheArchiveForFile
const size_t num_objects = archive_sp->ParseObjects ();
if (num_objects > 0)
{
- Mutex::Locker locker(Archive::GetArchiveCacheMutex ());
+ std::lock_guard<std::recursive_mutex> guard(Archive::GetArchiveCacheMutex());
Archive::GetArchiveCache().insert(std::make_pair(file, archive_sp));
}
else
@@ -299,14 +298,13 @@ ObjectContainerBSDArchive::Archive::GetArchiveCache ()
return g_archive_map;
}
-Mutex &
-ObjectContainerBSDArchive::Archive::GetArchiveCacheMutex ()
+std::recursive_mutex &
+ObjectContainerBSDArchive::Archive::GetArchiveCacheMutex()
{
- static Mutex g_archive_map_mutex (Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_archive_map_mutex;
return g_archive_map_mutex;
}
-
void
ObjectContainerBSDArchive::Initialize()
{
diff --git a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
index cbb3848dc7cd..03b0bf3e2f09 100644
--- a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
+++ b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
@@ -12,6 +12,8 @@
// C Includes
// C++ Includes
+#include <mutex>
+
// Other libraries and framework includes
// Project includes
#include "lldb/Symbol/ObjectContainer.h"
@@ -138,8 +140,8 @@ protected:
static Map &
GetArchiveCache ();
- static lldb_private::Mutex &
- GetArchiveCacheMutex ();
+ static std::recursive_mutex &
+ GetArchiveCacheMutex();
static Archive::shared_ptr
FindCachedArchive (const lldb_private::FileSpec &file,
diff --git a/source/Plugins/ObjectContainer/Universal-Mach-O/Makefile b/source/Plugins/ObjectContainer/Universal-Mach-O/Makefile
deleted file mode 100644
index 957753527d24..000000000000
--- a/source/Plugins/ObjectContainer/Universal-Mach-O/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ObjectContainer/Universal-Mach-O/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginObjectContainerMachOArchive
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
index 641a7cc3e0e2..625cce3c1062 100644
--- a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
+++ b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
@@ -198,6 +198,9 @@ ELFHeader::GetRelocationJumpSlotType() const
case EM_MIPS:
slot = R_MIPS_JUMP_SLOT;
break;
+ case EM_S390:
+ slot = R_390_JMP_SLOT;
+ break;
}
return slot;
diff --git a/source/Plugins/ObjectFile/ELF/Makefile b/source/Plugins/ObjectFile/ELF/Makefile
deleted file mode 100644
index 470660bb7861..000000000000
--- a/source/Plugins/ObjectFile/ELF/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ObjectFile/ELF/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginObjectFileELF
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index b16a2cda10f7..68e4e50a96e5 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -31,7 +31,9 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MipsABIFlags.h"
#define CASE_AND_STREAM(s, def, width) \
case def: s->Printf("%-*s", width, #def); break;
@@ -283,7 +285,7 @@ ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset)
}
}
- const char *cstr = data.GetCStr(offset, llvm::RoundUpToAlignment (n_namesz, 4));
+ const char *cstr = data.GetCStr(offset, llvm::alignTo (n_namesz, 4));
if (cstr == NULL)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
@@ -729,7 +731,10 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
SectionHeaderColl section_headers;
lldb_private::UUID &uuid = spec.GetUUID();
- GetSectionHeaderInfo(section_headers, data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc, spec.GetArchitecture ());
+ using namespace std::placeholders;
+ const SetDataFunction set_data = std::bind(&ObjectFileELF::SetData, std::cref(data), _1, _2, _3);
+ GetSectionHeaderInfo(section_headers, set_data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc, spec.GetArchitecture ());
+
llvm::Triple &spec_triple = spec.GetArchitecture ().GetTriple ();
@@ -759,7 +764,7 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
data.SetData(data_sp);
}
ProgramHeaderColl program_headers;
- GetProgramHeaderInfo(program_headers, data, header);
+ GetProgramHeaderInfo(program_headers, set_data, header);
size_t segment_data_end = 0;
for (ProgramHeaderCollConstIter I = program_headers.begin();
@@ -918,10 +923,14 @@ ObjectFileELF::SetLoadAddress (Target &target,
// Iterate through the object file sections to find all
// of the sections that have SHF_ALLOC in their flag bits.
SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
- // if (section_sp && !section_sp->IsThreadSpecific())
if (section_sp && section_sp->Test(SHF_ALLOC))
{
- lldb::addr_t load_addr = section_sp->GetFileAddress() + value;
+ lldb::addr_t load_addr = section_sp->GetFileAddress();
+ // We don't want to update the load address of a section with type
+ // eSectionTypeAbsoluteAddress as they already have the absolute load address
+ // already specified
+ if (section_sp->GetType() != eSectionTypeAbsoluteAddress)
+ load_addr += value;
// On 32-bit systems the load address have to fit into 4 bytes. The rest of
// the bytes are the overflow from the addition.
@@ -1256,7 +1265,7 @@ ObjectFileELF::ParseDependentModules()
//----------------------------------------------------------------------
size_t
ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
- DataExtractor &object_data,
+ const SetDataFunction &set_data,
const ELFHeader &header)
{
// We have already parsed the program headers
@@ -1274,7 +1283,7 @@ ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
const size_t ph_size = header.e_phnum * header.e_phentsize;
const elf_off ph_offset = header.e_phoff;
DataExtractor data;
- if (data.SetData(object_data, ph_offset, ph_size) != ph_size)
+ if (set_data(data, ph_offset, ph_size) != ph_size)
return 0;
uint32_t idx;
@@ -1298,7 +1307,10 @@ ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
size_t
ObjectFileELF::ParseProgramHeaders()
{
- return GetProgramHeaderInfo(m_program_headers, m_data, m_header);
+ using namespace std::placeholders;
+ return GetProgramHeaderInfo(m_program_headers,
+ std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2, _3),
+ m_header);
}
lldb_private::Error
@@ -1400,8 +1412,9 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l
// Only bother processing this if we don't already have the uuid set.
if (!uuid.IsValid())
{
- // 16 bytes is UUID|MD5, 20 bytes is SHA1
- if ((note.n_descsz == 16 || note.n_descsz == 20))
+ // 16 bytes is UUID|MD5, 20 bytes is SHA1. Other linkers may produce a build-id of a different
+ // length. Accept it as long as it's at least 4 bytes as it will be better than our own crc32.
+ if (note.n_descsz >= 4 && note.n_descsz <= 20)
{
uint8_t uuidbuf[20];
if (data.GetU8 (&offset, &uuidbuf, note.n_descsz) == nullptr)
@@ -1449,7 +1462,7 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l
// this ELF targets.
if(note.n_descsz)
{
- const char *cstr = data.GetCStr(&offset, llvm::RoundUpToAlignment (note.n_descsz, 4));
+ const char *cstr = data.GetCStr(&offset, llvm::alignTo (note.n_descsz, 4));
(void)cstr;
}
}
@@ -1505,13 +1518,87 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l
return error;
}
+void
+ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length, ArchSpec &arch_spec)
+{
+ lldb::offset_t Offset = 0;
+
+ uint8_t FormatVersion = data.GetU8(&Offset);
+ if (FormatVersion != llvm::ARMBuildAttrs::Format_Version)
+ return;
+
+ Offset = Offset + sizeof(uint32_t); // Section Length
+ llvm::StringRef VendorName = data.GetCStr(&Offset);
+
+ if (VendorName != "aeabi")
+ return;
+
+ if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment)
+ arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
+
+ while (Offset < length)
+ {
+ uint8_t Tag = data.GetU8(&Offset);
+ uint32_t Size = data.GetU32(&Offset);
+
+ if (Tag != llvm::ARMBuildAttrs::File || Size == 0)
+ continue;
+
+ while (Offset < length)
+ {
+ uint64_t Tag = data.GetULEB128(&Offset);
+ switch (Tag)
+ {
+ default:
+ if (Tag < 32)
+ data.GetULEB128(&Offset);
+ else if (Tag % 2 == 0)
+ data.GetULEB128(&Offset);
+ else
+ data.GetCStr(&Offset);
+
+ break;
+
+ case llvm::ARMBuildAttrs::CPU_raw_name:
+ case llvm::ARMBuildAttrs::CPU_name:
+ data.GetCStr(&Offset);
+
+ break;
+
+ case llvm::ARMBuildAttrs::ABI_VFP_args:
+ {
+ uint64_t VFPArgs = data.GetULEB128(&Offset);
+
+ if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS)
+ {
+ if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment ||
+ arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF)
+ arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
+
+ arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
+ }
+ else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS)
+ {
+ if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment ||
+ arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI)
+ arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF);
+
+ arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
+ }
+
+ break;
+ }
+ }
+ }
+ }
+}
//----------------------------------------------------------------------
// GetSectionHeaderInfo
//----------------------------------------------------------------------
size_t
ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
- lldb_private::DataExtractor &object_data,
+ const SetDataFunction &set_data,
const elf::ELFHeader &header,
lldb_private::UUID &uuid,
std::string &gnu_debuglink_file,
@@ -1556,6 +1643,15 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
}
}
+ if (arch_spec.GetMachine() == llvm::Triple::arm ||
+ arch_spec.GetMachine() == llvm::Triple::thumb)
+ {
+ if (header.e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT)
+ arch_spec.SetFlags (ArchSpec::eARM_abi_soft_float);
+ else if (header.e_flags & llvm::ELF::EF_ARM_VFP_FLOAT)
+ arch_spec.SetFlags (ArchSpec::eARM_abi_hard_float);
+ }
+
// If there are no section headers we are done.
if (header.e_shnum == 0)
return 0;
@@ -1569,7 +1665,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
const size_t sh_size = header.e_shnum * header.e_shentsize;
const elf_off sh_offset = header.e_shoff;
DataExtractor sh_data;
- if (sh_data.SetData (object_data, sh_offset, sh_size) != sh_size)
+ if (set_data (sh_data, sh_offset, sh_size) != sh_size)
return 0;
uint32_t idx;
@@ -1590,7 +1686,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
const Elf64_Off offset = sheader.sh_offset;
lldb_private::DataExtractor shstr_data;
- if (shstr_data.SetData (object_data, offset, byte_size) == byte_size)
+ if (set_data (shstr_data, offset, byte_size) == byte_size)
{
for (SectionHeaderCollIter I = section_headers.begin();
I != section_headers.end(); ++I)
@@ -1602,40 +1698,93 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
I->section_name = name;
- if (arch_spec.GetMachine() == llvm::Triple::mips || arch_spec.GetMachine() == llvm::Triple::mipsel
- || arch_spec.GetMachine() == llvm::Triple::mips64 || arch_spec.GetMachine() == llvm::Triple::mips64el)
+ if (arch_spec.IsMIPS())
{
uint32_t arch_flags = arch_spec.GetFlags ();
DataExtractor data;
if (sheader.sh_type == SHT_MIPS_ABIFLAGS)
{
- if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size))
+ if (section_size && (set_data (data, sheader.sh_offset, section_size) == section_size))
{
- lldb::offset_t ase_offset = 12; // MIPS ABI Flags Version: 0
- arch_flags |= data.GetU32 (&ase_offset);
+ // MIPS ASE Mask is at offset 12 in MIPS.abiflags section
+ lldb::offset_t offset = 12; // MIPS ABI Flags Version: 0
+ arch_flags |= data.GetU32 (&offset);
+
+ // The floating point ABI is at offset 7
+ offset = 7;
+ switch (data.GetU8 (&offset))
+ {
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY :
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_ANY;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE :
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_DOUBLE;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE :
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SINGLE;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT :
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64 :
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_OLD_64;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX :
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_XX;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_64 :
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A :
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64A;
+ break;
+ }
}
}
// Settings appropriate ArchSpec ABI Flags
- if (header.e_flags & llvm::ELF::EF_MIPS_ABI2)
+ switch(header.e_flags & llvm::ELF::EF_MIPS_ABI)
{
- arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32;
- }
- else if (header.e_flags & llvm::ELF::EF_MIPS_ABI_O32)
- {
- arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32;
+ case llvm::ELF::EF_MIPS_ABI_O32:
+ arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32;
+ break;
+ case EF_MIPS_ABI_O64:
+ arch_flags |= lldb_private::ArchSpec::eMIPSABI_O64;
+ break;
+ case EF_MIPS_ABI_EABI32:
+ arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI32;
+ break;
+ case EF_MIPS_ABI_EABI64:
+ arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI64;
+ break;
+ default:
+ // ABI Mask doesn't cover N32 and N64 ABI.
+ if (header.e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64)
+ arch_flags |= lldb_private::ArchSpec::eMIPSABI_N64;
+ else if (header.e_flags && llvm::ELF::EF_MIPS_ABI2)
+ arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32;
+ break;
}
arch_spec.SetFlags (arch_flags);
}
+ if (arch_spec.GetMachine() == llvm::Triple::arm || arch_spec.GetMachine() == llvm::Triple::thumb)
+ {
+ DataExtractor data;
+
+ if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&
+ set_data(data, sheader.sh_offset, section_size) == section_size)
+ ParseARMAttributes(data, section_size, arch_spec);
+ }
+
if (name == g_sect_name_gnu_debuglink)
{
DataExtractor data;
- if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size))
+ if (section_size && (set_data (data, sheader.sh_offset, section_size) == section_size))
{
lldb::offset_t gnu_debuglink_offset = 0;
gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset);
- gnu_debuglink_offset = llvm::RoundUpToAlignment (gnu_debuglink_offset, 4);
+ gnu_debuglink_offset = llvm::alignTo (gnu_debuglink_offset, 4);
data.GetU32 (&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
}
}
@@ -1653,7 +1802,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
{
// Allow notes to refine module info.
DataExtractor data;
- if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size))
+ if (section_size && (set_data (data, sheader.sh_offset, section_size) == section_size))
{
Error error = RefineModuleDetailsFromNote (data, arch_spec, uuid);
if (error.Fail ())
@@ -1719,7 +1868,41 @@ ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const
size_t
ObjectFileELF::ParseSectionHeaders()
{
- return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc, m_arch_spec);
+ using namespace std::placeholders;
+
+ return GetSectionHeaderInfo(m_section_headers,
+ std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2, _3),
+ m_header,
+ m_uuid,
+ m_gnu_debuglink_file,
+ m_gnu_debuglink_crc,
+ m_arch_spec);
+}
+
+lldb::offset_t
+ObjectFileELF::SetData(const lldb_private::DataExtractor &src, lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length)
+{
+ return dst.SetData(src, offset, length);
+}
+
+lldb::offset_t
+ObjectFileELF::SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length)
+{
+ if (offset + length <= m_data.GetByteSize())
+ return dst.SetData(m_data, offset, length);
+
+ const auto process_sp = m_process_wp.lock();
+ if (process_sp != nullptr)
+ {
+ addr_t file_size = offset + length;
+
+ DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size);
+ if (!data_sp)
+ return false;
+ m_data.SetData(data_sp, 0, file_size);
+ }
+
+ return dst.SetData(m_data, offset, length);
}
const ObjectFileELF::ELFSectionHeaderInfo *
@@ -1849,6 +2032,9 @@ ObjectFileELF::CreateSections(SectionList &unified_section_list)
else if (name == g_sect_name_arm_extab) sect_type = eSectionTypeARMextab;
else if (name == g_sect_name_go_symtab) sect_type = eSectionTypeGoSymtab;
+ const uint32_t permissions = ((header.sh_flags & SHF_ALLOC) ? ePermissionsReadable : 0) |
+ ((header.sh_flags & SHF_WRITE) ? ePermissionsWritable : 0) |
+ ((header.sh_flags & SHF_EXECINSTR) ? ePermissionsExecutable : 0);
switch (header.sh_type)
{
case SHT_SYMTAB:
@@ -1900,6 +2086,7 @@ ObjectFileELF::CreateSections(SectionList &unified_section_list)
header.sh_flags, // Flags for this section.
target_bytes_size));// Number of host bytes per target byte
+ section_sp->SetPermissions(permissions);
if (is_thread_specific)
section_sp->SetIsThreadSpecific (is_thread_specific);
m_sections_ap->AddSection(section_sp);
@@ -1997,7 +2184,7 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
static ConstString bss_section_name(".bss");
static ConstString opd_section_name(".opd"); // For ppc64
- // On Android the oatdata and the oatexec symbols in system@framework@boot.oat covers the full
+ // On Android the oatdata and the oatexec symbols in the oat and odex files covers the full
// .text section what causes issues with displaying unusable symbol name to the user and very
// slow unwinding speed because the instruction emulation based unwind plans try to emulate all
// instructions in these symbols. Don't add these symbols to the symbol list as they have no
@@ -2005,10 +2192,13 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
// Filtering can't be restricted to Android because this special object file don't contain the
// note section specifying the environment to Android but the custom extension and file name
// makes it highly unlikely that this will collide with anything else.
- bool skip_oatdata_oatexec = m_file.GetFilename() == ConstString("system@framework@boot.oat");
+ ConstString file_extension = m_file.GetFileNameExtension();
+ bool skip_oatdata_oatexec = file_extension == ConstString("oat") || file_extension == ConstString("odex");
ArchSpec arch;
GetArchitecture(arch);
+ ModuleSP module_sp(GetModule());
+ SectionList* module_section_list = module_sp ? module_sp->GetSectionList() : nullptr;
// Local cache to avoid doing a FindSectionByName for each symbol. The "const char*" key must
// came from a ConstString object so they can be compared by pointer
@@ -2034,9 +2224,9 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
SectionSP symbol_section_sp;
SymbolType symbol_type = eSymbolTypeInvalid;
- Elf64_Half symbol_idx = symbol.st_shndx;
+ Elf64_Half section_idx = symbol.st_shndx;
- switch (symbol_idx)
+ switch (section_idx)
{
case SHN_ABS:
symbol_type = eSymbolTypeAbsolute;
@@ -2045,7 +2235,7 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
symbol_type = eSymbolTypeUndefined;
break;
default:
- symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
+ symbol_section_sp = section_list->GetSectionAtIndex(section_idx);
break;
}
@@ -2092,7 +2282,7 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
}
}
- if (symbol_type == eSymbolTypeInvalid)
+ if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION)
{
if (symbol_section_sp)
{
@@ -2229,30 +2419,44 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
}
}
- // symbol_value_offset may contain 0 for ARM symbols or -1 for
- // THUMB symbols. See above for more details.
+ // symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB symbols. See above for
+ // more details.
uint64_t symbol_value = symbol.st_value + symbol_value_offset;
+
+ if (symbol_section_sp == nullptr && section_idx == SHN_ABS && symbol.st_size != 0)
+ {
+ // We don't have a section for a symbol with non-zero size. Create a new section for it
+ // so the address range covered by the symbol is also covered by the module (represented
+ // through the section list). It is needed so module lookup for the addresses covered
+ // by this symbol will be successfull. This case happens for absolute symbols.
+ ConstString fake_section_name(std::string(".absolute.") + symbol_name);
+ symbol_section_sp = std::make_shared<Section>(module_sp,
+ this,
+ SHN_ABS,
+ fake_section_name,
+ eSectionTypeAbsoluteAddress,
+ symbol_value,
+ symbol.st_size,
+ 0, 0, 0,
+ SHF_ALLOC);
+
+ module_section_list->AddSection(symbol_section_sp);
+ section_list->AddSection(symbol_section_sp);
+ }
+
if (symbol_section_sp && CalculateType() != ObjectFile::Type::eTypeObjectFile)
symbol_value -= symbol_section_sp->GetFileAddress();
- if (symbol_section_sp)
+ if (symbol_section_sp && module_section_list && module_section_list != section_list)
{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- SectionList *module_section_list = module_sp->GetSectionList();
- if (module_section_list && module_section_list != section_list)
- {
- const ConstString &sect_name = symbol_section_sp->GetName();
- auto section_it = section_name_to_section.find(sect_name.GetCString());
- if (section_it == section_name_to_section.end())
- section_it = section_name_to_section.emplace(
- sect_name.GetCString(),
- module_section_list->FindSectionByName (sect_name)).first;
- if (section_it->second && section_it->second->GetFileSize())
- symbol_section_sp = section_it->second;
- }
- }
+ const ConstString &sect_name = symbol_section_sp->GetName();
+ auto section_it = section_name_to_section.find(sect_name.GetCString());
+ if (section_it == section_name_to_section.end())
+ section_it = section_name_to_section.emplace(
+ sect_name.GetCString(),
+ module_section_list->FindSectionByName (sect_name)).first;
+ if (section_it->second && section_it->second->GetFileSize())
+ symbol_section_sp = section_it->second;
}
bool is_global = symbol.getBinding() == STB_GLOBAL;
@@ -2283,6 +2487,12 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
mangled.SetDemangledName( ConstString((demangled_name + suffix).str()) );
}
+ // In ELF all symbol should have a valid size but it is not true for some function symbols
+ // coming from hand written assembly. As none of the function symbol should have 0 size we
+ // try to calculate the size for these symbols in the symtab with saying that their original
+ // size is not valid.
+ bool symbol_size_valid = symbol.st_size != 0 || symbol.getType() != STT_FUNC;
+
Symbol dc_symbol(
i + start_id, // ID is the original symbol table index.
mangled,
@@ -2295,7 +2505,7 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
symbol_section_sp, // Section in which this symbol is defined or null.
symbol_value, // Offset in section or symbol value.
symbol.st_size), // Size in bytes of this symbol.
- symbol.st_size != 0, // Size is valid if it is not 0
+ symbol_size_valid, // Symbol size is valid
has_suffix, // Contains linker annotations?
flags); // Symbol flags.
symtab->AddSymbol(dc_symbol);
@@ -2304,7 +2514,9 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
}
unsigned
-ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, lldb_private::Section *symtab)
+ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
+ user_id_t start_id,
+ lldb_private::Section *symtab)
{
if (symtab->GetObjectFile() != this)
{
@@ -2430,9 +2642,12 @@ GetPltEntrySizeAndOffset(const ELFSectionHeader* rel_hdr, const ELFSectionHeader
// Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 16 bytes.
// So round the entsize up by the alignment if addralign is set.
elf_xword plt_entsize = plt_hdr->sh_addralign ?
- llvm::RoundUpToAlignment (plt_hdr->sh_entsize, plt_hdr->sh_addralign) : plt_hdr->sh_entsize;
+ llvm::alignTo (plt_hdr->sh_entsize, plt_hdr->sh_addralign) : plt_hdr->sh_entsize;
- if (plt_entsize == 0)
+ // Some linkers e.g ld for arm, fill plt_hdr->sh_entsize field incorrectly.
+ // PLT entries relocation code in general requires multiple instruction and
+ // should be greater than 4 bytes in most cases. Try to guess correct size just in case.
+ if (plt_entsize <= 4)
{
// The linker haven't set the plt_hdr->sh_entsize field. Try to guess the size of the plt
// entries based on the number of entries and the size of the plt section with the
@@ -2533,17 +2748,17 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
{
assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
- // The link field points to the associated symbol table. The info field
- // points to the section holding the plt.
+ // The link field points to the associated symbol table.
user_id_t symtab_id = rel_hdr->sh_link;
- user_id_t plt_id = rel_hdr->sh_info;
// If the link field doesn't point to the appropriate symbol name table then
// try to find it by name as some compiler don't fill in the link fields.
if (!symtab_id)
symtab_id = GetSectionIndexByName(".dynsym");
- if (!plt_id)
- plt_id = GetSectionIndexByName(".plt");
+
+ // Get PLT section. We cannot use rel_hdr->sh_info, since current linkers
+ // point that to the .got.plt or .got section instead of .plt.
+ user_id_t plt_id = GetSectionIndexByName(".plt");
if (!symtab_id || !plt_id)
return 0;
@@ -2760,7 +2975,7 @@ ObjectFileELF::GetSymtab()
return NULL;
uint64_t symbol_id = 0;
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
// Sharable objects and dynamic executables usually have 2 distinct symbol
// tables, one named ".symtab", and the other ".dynsym". The dynsym is a smaller
@@ -2806,6 +3021,14 @@ ObjectFileELF::GetSymtab()
}
}
+ DWARFCallFrameInfo* eh_frame = GetUnwindTable().GetEHFrameInfo();
+ if (eh_frame)
+ {
+ if (m_symtab_ap == nullptr)
+ m_symtab_ap.reset(new Symtab(this));
+ ParseUnwindSymbols (m_symtab_ap.get(), eh_frame);
+ }
+
// If we still don't have any symtab then create an empty instance to avoid do the section
// lookup next time.
if (m_symtab_ap == nullptr)
@@ -2835,57 +3058,64 @@ ObjectFileELF::GetSymtab()
return m_symtab_ap.get();
}
-Symbol *
-ObjectFileELF::ResolveSymbolForAddress(const Address& so_addr, bool verify_unique)
+void
+ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, DWARFCallFrameInfo* eh_frame)
{
- if (!m_symtab_ap.get())
- return nullptr; // GetSymtab() should be called first.
-
- const SectionList *section_list = GetSectionList();
+ SectionList* section_list = GetSectionList();
if (!section_list)
- return nullptr;
+ return;
- if (DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo())
- {
- AddressRange range;
- if (eh_frame->GetAddressRange (so_addr, range))
+ // First we save the new symbols into a separate list and add them to the symbol table after
+ // we colleced all symbols we want to add. This is neccessary because adding a new symbol
+ // invalidates the internal index of the symtab what causing the next lookup to be slow because
+ // it have to recalculate the index first.
+ std::vector<Symbol> new_symbols;
+
+ eh_frame->ForEachFDEEntries(
+ [this, symbol_table, section_list, &new_symbols](lldb::addr_t file_addr,
+ uint32_t size,
+ dw_offset_t) {
+ Symbol* symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
+ if (symbol)
{
- const addr_t file_addr = range.GetBaseAddress().GetFileAddress();
- Symbol * symbol = verify_unique ? m_symtab_ap->FindSymbolContainingFileAddress(file_addr) : nullptr;
- if (symbol)
- return symbol;
-
- // Note that a (stripped) symbol won't be found by GetSymtab()...
- lldb::SectionSP eh_sym_section_sp = section_list->FindSectionContainingFileAddress(file_addr);
- if (eh_sym_section_sp.get())
+ if (!symbol->GetByteSizeIsValid())
{
- addr_t section_base = eh_sym_section_sp->GetFileAddress();
- addr_t offset = file_addr - section_base;
- uint64_t symbol_id = m_symtab_ap->GetNumSymbols();
-
+ symbol->SetByteSize(size);
+ symbol->SetSizeIsSynthesized(true);
+ }
+ }
+ else
+ {
+ SectionSP section_sp = section_list->FindSectionContainingFileAddress(file_addr);
+ if (section_sp)
+ {
+ addr_t offset = file_addr - section_sp->GetFileAddress();
+ const char* symbol_name = GetNextSyntheticSymbolName().GetCString();
+ uint64_t symbol_id = symbol_table->GetNumSymbols();
Symbol eh_symbol(
- symbol_id, // Symbol table index.
- "???", // Symbol name.
- false, // Is the symbol name mangled?
- 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?
- eh_sym_section_sp, // Section in which this symbol is defined or null.
- offset, // Offset in section or symbol value.
- range.GetByteSize(), // Size in bytes of this symbol.
- true, // Size is valid.
- false, // Contains linker annotations?
- 0); // Symbol flags.
- if (symbol_id == m_symtab_ap->AddSymbol(eh_symbol))
- return m_symtab_ap->SymbolAtIndex(symbol_id);
+ 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?
+ false, // Is this symbol a trampoline?
+ true, // Is this symbol artificial?
+ section_sp, // Section in which this symbol is defined or null.
+ offset, // Offset in section or symbol value.
+ 0, // Size: Don't specify the size as an FDE can
+ false, // Size is valid: cover multiple symbols.
+ false, // Contains linker annotations?
+ 0); // Symbol flags.
+ new_symbols.push_back(eh_symbol);
}
}
- }
- return nullptr;
-}
+ return true;
+ });
+ for (const Symbol& s : new_symbols)
+ symbol_table->AddSymbol(s);
+}
bool
ObjectFileELF::IsStripped ()
@@ -2903,6 +3133,22 @@ ObjectFileELF::IsStripped ()
void
ObjectFileELF::Dump(Stream *s)
{
+ ModuleSP module_sp(GetModule());
+ if (!module_sp)
+ {
+ return;
+ }
+
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ s->Printf("%p: ", static_cast<void *>(this));
+ s->Indent();
+ s->PutCString("ObjectFileELF");
+
+ ArchSpec header_arch;
+ GetArchitecture(header_arch);
+
+ *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
+
DumpELFHeader(s, m_header);
s->EOL();
DumpELFProgramHeaders(s);
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 4b97f92c6c5c..e2f73f53ec63 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -14,6 +14,7 @@
#include <stdint.h>
// C++ Includes
+#include <functional>
#include <vector>
// Other libraries and framework includes
@@ -56,7 +57,7 @@ struct ELFNote
size_t
GetByteSize() const
{
- return 12 + llvm::RoundUpToAlignment (n_namesz, 4) + llvm::RoundUpToAlignment (n_descsz, 4);
+ return 12 + llvm::alignTo (n_namesz, 4) + llvm::alignTo (n_descsz, 4);
}
};
@@ -149,9 +150,6 @@ public:
lldb_private::Symtab *
GetSymtab() override;
- lldb_private::Symbol *
- ResolveSymbolForAddress(const lldb_private::Address& so_addr, bool verify_unique) override;
-
bool
IsStripped () override;
@@ -231,6 +229,7 @@ private:
typedef DynamicSymbolColl::const_iterator DynamicSymbolCollConstIter;
typedef std::map<lldb::addr_t, lldb::AddressClass> FileAddressToAddressClassMap;
+ typedef std::function<lldb::offset_t (lldb_private::DataExtractor &, lldb::offset_t, lldb::offset_t)> SetDataFunction;
/// Version of this reader common to all plugins based on this class.
static const uint32_t m_plugin_version = 1;
@@ -279,7 +278,7 @@ private:
// Parses the ELF program headers.
static size_t
GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
- lldb_private::DataExtractor &data,
+ const SetDataFunction &set_data,
const elf::ELFHeader &header);
// Finds PT_NOTE segments and calculates their crc sum.
@@ -299,10 +298,14 @@ private:
size_t
ParseSectionHeaders();
+ static void
+ ParseARMAttributes(lldb_private::DataExtractor &data, uint64_t length,
+ lldb_private::ArchSpec &arch_spec);
+
/// Parses the elf section headers and returns the uuid, debug link name, crc, archspec.
static size_t
GetSectionHeaderInfo(SectionHeaderColl &section_headers,
- lldb_private::DataExtractor &data,
+ const SetDataFunction &set_data,
const elf::ELFHeader &header,
lldb_private::UUID &uuid,
std::string &gnu_debuglink_file,
@@ -347,6 +350,10 @@ private:
const ELFSectionHeaderInfo *rela_hdr,
lldb::user_id_t section_id);
+ void
+ ParseUnwindSymbols(lldb_private::Symtab *symbol_table,
+ lldb_private::DWARFCallFrameInfo* eh_frame);
+
/// Relocates debug sections
unsigned
RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr, lldb::user_id_t rel_id);
@@ -437,6 +444,13 @@ private:
static lldb_private::Error
RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid);
+
+
+ static lldb::offset_t
+ SetData(const lldb_private::DataExtractor &src, lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length);
+
+ lldb::offset_t
+ SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length);
};
#endif // liblldb_ObjectFileELF_h_
diff --git a/source/Plugins/ObjectFile/JIT/Makefile b/source/Plugins/ObjectFile/JIT/Makefile
deleted file mode 100644
index 2af3521777a1..000000000000
--- a/source/Plugins/ObjectFile/JIT/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ObjectFile/JIT/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginObjectFileJIT
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index 3103ed8fb8fe..e3d838333711 100644
--- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -158,11 +158,11 @@ ObjectFileJIT::GetSymtab()
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_symtab_ap.get() == NULL)
{
m_symtab_ap.reset(new Symtab(this));
- Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
+ std::lock_guard<std::recursive_mutex> symtab_guard(m_symtab_ap->GetMutex());
ObjectFileJITDelegateSP delegate_sp (m_delegate_wp.lock());
if (delegate_sp)
delegate_sp->PopulateSymtab(this, *m_symtab_ap);
@@ -200,7 +200,7 @@ ObjectFileJIT::Dump (Stream *s)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
s->Printf("%p: ", static_cast<void*>(this));
s->Indent();
s->PutCString("ObjectFileJIT");
diff --git a/source/Plugins/ObjectFile/Mach-O/Makefile b/source/Plugins/ObjectFile/Mach-O/Makefile
deleted file mode 100644
index 2fab0238e411..000000000000
--- a/source/Plugins/ObjectFile/Mach-O/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ObjectFile/Mach-O/Makefile -----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginObjectFileMachO
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 9c1e17782508..5f8242211b7f 100644
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -541,6 +541,7 @@ public:
lldb::offset_t next_thread_state = offset + (count * 4);
switch (flavor)
{
+ case GPRAltRegSet:
case GPRRegSet:
for (uint32_t i=0; i<count; ++i)
{
@@ -1129,7 +1130,9 @@ ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
m_mach_sections(),
m_entry_point_address(),
m_thread_context_offsets(),
- m_thread_context_offsets_valid(false)
+ m_thread_context_offsets_valid(false),
+ m_reexported_dylibs (),
+ m_allow_assembly_emulation_unwind_plans (true)
{
::memset (&m_header, 0, sizeof(m_header));
::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
@@ -1144,7 +1147,9 @@ ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
m_mach_sections(),
m_entry_point_address(),
m_thread_context_offsets(),
- m_thread_context_offsets_valid(false)
+ m_thread_context_offsets_valid(false),
+ m_reexported_dylibs (),
+ m_allow_assembly_emulation_unwind_plans (true)
{
::memset (&m_header, 0, sizeof(m_header));
::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
@@ -1212,7 +1217,7 @@ ObjectFileMachO::ParseHeader ()
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
bool can_parse = false;
lldb::offset_t offset = 0;
m_data.SetByteOrder (endian::InlHostByteOrder());
@@ -1387,6 +1392,7 @@ ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
case eSectionTypeCompactUnwind:
return eAddressClassRuntime;
+ case eSectionTypeAbsoluteAddress:
case eSectionTypeELFSymbolTable:
case eSectionTypeELFDynamicSymbols:
case eSectionTypeELFRelocationEntries:
@@ -1451,11 +1457,11 @@ ObjectFileMachO::GetSymtab()
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_symtab_ap.get() == NULL)
{
m_symtab_ap.reset(new Symtab(this));
- Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
+ std::lock_guard<std::recursive_mutex> symtab_guard(m_symtab_ap->GetMutex());
ParseSymtab ();
m_symtab_ap->Finalize ();
}
@@ -1619,6 +1625,10 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list)
}
if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
{
+ const uint32_t segment_permissions =
+ ((load_cmd.initprot & VM_PROT_READ) ? ePermissionsReadable : 0) |
+ ((load_cmd.initprot & VM_PROT_WRITE) ? ePermissionsWritable : 0) |
+ ((load_cmd.initprot & VM_PROT_EXECUTE) ? ePermissionsExecutable : 0);
const bool segment_is_encrypted = (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
@@ -1645,6 +1655,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list)
segment_sp->SetIsEncrypted (segment_is_encrypted);
m_sections_ap->AddSection(segment_sp);
+ segment_sp->SetPermissions(segment_permissions);
if (add_to_unified)
unified_section_list.AddSection(segment_sp);
}
@@ -1776,7 +1787,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list)
sect64.align,
load_cmd.flags)); // Flags for this section
segment_sp->SetIsFake(true);
-
+ segment_sp->SetPermissions(segment_permissions);
m_sections_ap->AddSection(segment_sp);
if (add_to_unified)
unified_section_list.AddSection(segment_sp);
@@ -1926,6 +1937,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list)
section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
+ section_sp->SetPermissions(segment_permissions);
segment_sp->GetChildren().AddSection(section_sp);
if (segment_sp->IsFake())
@@ -2601,6 +2613,23 @@ ObjectFileMachO::ParseSymtab ()
const size_t function_starts_count = function_starts.GetSize();
+ // For user process binaries (executables, dylibs, frameworks, bundles), if we don't have
+ // LC_FUNCTION_STARTS/eh_frame section in this binary, we're going to assume the binary
+ // has been stripped. Don't allow assembly language instruction emulation because we don't
+ // know proper function start boundaries.
+ //
+ // For all other types of binaries (kernels, stand-alone bare board binaries, kexts), they
+ // may not have LC_FUNCTION_STARTS / eh_frame sections - we should not make any assumptions
+ // about them based on that.
+ if (function_starts_count == 0 && CalculateStrata() == eStrataUser)
+ {
+ m_allow_assembly_emulation_unwind_plans = false;
+ Log *unwind_or_symbol_log (lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_UNWIND));
+
+ if (unwind_or_symbol_log)
+ module_sp->LogMessage(unwind_or_symbol_log, "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
+ }
+
const user_id_t TEXT_eh_frame_sectID =
eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
: static_cast<user_id_t>(NO_SECT);
@@ -3078,7 +3107,7 @@ ObjectFileMachO::ParseSymtab ()
{
// This is usually the second N_SO entry that contains just the filename,
// so here we combine it with the first one if we are minimizing the symbol table
- const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
+ const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName(lldb::eLanguageTypeUnknown).AsCString();
if (so_path && so_path[0])
{
std::string full_so_path (so_path);
@@ -3465,7 +3494,7 @@ ObjectFileMachO::ParseSymtab ()
sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
if (is_gsym && is_debug)
{
- const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString();
+ const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
if (gsym_name)
N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
}
@@ -3539,7 +3568,7 @@ ObjectFileMachO::ParseSymtab ()
bool found_it = false;
for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
{
- if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
+ if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled))
{
m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
// We just need the flags from the linker symbol, so put these flags
@@ -3578,7 +3607,7 @@ ObjectFileMachO::ParseSymtab ()
bool found_it = false;
for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
{
- if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
+ if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled))
{
m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
// We just need the flags from the linker symbol, so put these flags
@@ -3595,7 +3624,7 @@ ObjectFileMachO::ParseSymtab ()
}
else
{
- const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString();
+ const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
if (gsym_name)
{
// Combine N_GSYM stab entries with the non stab symbol
@@ -4089,7 +4118,7 @@ ObjectFileMachO::ParseSymtab ()
case N_ECOML:
// end common (local name): 0,,n_sect,0,address
symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- // Fall through
+ LLVM_FALLTHROUGH;
case N_ECOMM:
// end common: name,,n_sect,0,0
@@ -4145,7 +4174,8 @@ ObjectFileMachO::ParseSymtab ()
ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
undefined_name_to_desc[undefined_name] = nlist.n_desc;
}
- // Fall through
+ LLVM_FALLTHROUGH;
+
case N_PBUD:
type = eSymbolTypeUndefined;
break;
@@ -4516,7 +4546,6 @@ ObjectFileMachO::ParseSymtab ()
if (function_starts_count > 0)
{
- char synthetic_function_symbol[PATH_MAX];
uint32_t num_synthetic_function_symbols = 0;
for (i=0; i<function_starts_count; ++i)
{
@@ -4531,7 +4560,6 @@ ObjectFileMachO::ParseSymtab ()
num_syms = sym_idx + num_synthetic_function_symbols;
sym = symtab->Resize (num_syms);
}
- uint32_t synthetic_function_symbol_idx = 0;
for (i=0; i<function_starts_count; ++i)
{
const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
@@ -4566,13 +4594,8 @@ ObjectFileMachO::ParseSymtab ()
{
symbol_byte_size = section_end_file_addr - symbol_file_addr;
}
- snprintf (synthetic_function_symbol,
- sizeof(synthetic_function_symbol),
- "___lldb_unnamed_function%u$$%s",
- ++synthetic_function_symbol_idx,
- module_sp->GetFileSpec().GetFilename().GetCString());
sym[sym_idx].SetID (synthetic_sym_id++);
- sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
+ sym[sym_idx].GetMangled().SetDemangledName(GetNextSyntheticSymbolName());
sym[sym_idx].SetType (eSymbolTypeCode);
sym[sym_idx].SetIsSynthetic (true);
sym[sym_idx].GetAddressRef() = symbol_addr;
@@ -4743,7 +4766,7 @@ ObjectFileMachO::Dump (Stream *s)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
s->Printf("%p: ", static_cast<void*>(this));
s->Indent();
if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
@@ -4827,9 +4850,22 @@ ObjectFileMachO::GetArchitecture (const llvm::MachO::mach_header &header,
if (header.filetype == MH_PRELOAD)
{
- // Set vendor to an unspecified unknown or a "*" so it can match any vendor
- triple.setVendor(llvm::Triple::UnknownVendor);
- triple.setVendorName(llvm::StringRef());
+ if (header.cputype == CPU_TYPE_ARM)
+ {
+ // If this is a 32-bit arm binary, and it's a standalone binary,
+ // force the Vendor to Apple so we don't accidentally pick up
+ // the generic armv7 ABI at runtime. Apple's armv7 ABI always uses
+ // r7 for the frame pointer register; most other armv7 ABIs use a
+ // combination of r7 and r11.
+ triple.setVendor(llvm::Triple::Apple);
+ }
+ else
+ {
+ // Set vendor to an unspecified unknown or a "*" so it can match any vendor
+ // This is required for correct behavior of EFI debugging on x86_64
+ triple.setVendor(llvm::Triple::UnknownVendor);
+ triple.setVendorName(llvm::StringRef());
+ }
return true;
}
else
@@ -4886,7 +4922,7 @@ ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
return GetUUID (m_header, m_data, offset, *uuid);
}
@@ -4900,7 +4936,7 @@ ObjectFileMachO::GetDependentModules (FileSpecList& files)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
struct load_command load_cmd;
lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
std::vector<std::string> rpath_paths;
@@ -5028,7 +5064,7 @@ ObjectFileMachO::GetEntryPointAddress ()
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
struct load_command load_cmd;
lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t i;
@@ -5059,7 +5095,7 @@ ObjectFileMachO::GetEntryPointAddress ()
switch (m_header.cputype)
{
case llvm::MachO::CPU_TYPE_ARM:
- if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
+ if (flavor == 1 || flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32 from mach/arm/thread_status.h
{
offset += 60; // This is the offset of pc in the GPR thread state data structure.
start_address = m_data.GetU32(&offset);
@@ -5111,6 +5147,7 @@ ObjectFileMachO::GetEntryPointAddress ()
start_address = text_segment_sp->GetFileAddress() + entryoffset;
}
}
+ break;
default:
break;
@@ -5177,7 +5214,7 @@ ObjectFileMachO::GetNumThreadContexts ()
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (!m_thread_context_offsets_valid)
{
m_thread_context_offsets_valid = true;
@@ -5211,7 +5248,7 @@ ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &th
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (!m_thread_context_offsets_valid)
GetNumThreadContexts ();
@@ -5347,7 +5384,7 @@ ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
struct dylib_command load_cmd;
lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t version_cmd = 0;
@@ -5402,7 +5439,7 @@ ObjectFileMachO::GetArchitecture (ArchSpec &arch)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
return GetArchitecture (m_header, m_data, MachHeaderSizeFromMagic(m_header.magic), arch);
}
return false;
@@ -5614,6 +5651,12 @@ ObjectFileMachO::GetIsDynamicLinkEditor()
return m_header.filetype == llvm::MachO::MH_DYLINKER;
}
+bool
+ObjectFileMachO::AllowAssemblyEmulationUnwindPlans ()
+{
+ return m_allow_assembly_emulation_unwind_plans;
+}
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index 6b7ad531b83b..251a0865e782 100644
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -19,7 +19,6 @@
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/RangeMap.h"
#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/ObjectFile.h"
//----------------------------------------------------------------------
@@ -176,6 +175,9 @@ public:
lldb::offset_t *data_offset_ptr,
llvm::MachO::mach_header &header);
+ bool
+ AllowAssemblyEmulationUnwindPlans () override;
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
@@ -247,6 +249,7 @@ protected:
FileRangeArray m_thread_context_offsets;
bool m_thread_context_offsets_valid;
lldb_private::FileSpecList m_reexported_dylibs;
+ bool m_allow_assembly_emulation_unwind_plans;
};
#endif // liblldb_ObjectFileMachO_h_
diff --git a/source/Plugins/ObjectFile/PECOFF/Makefile b/source/Plugins/ObjectFile/PECOFF/Makefile
deleted file mode 100644
index 1b5abc461e82..000000000000
--- a/source/Plugins/ObjectFile/PECOFF/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ObjectFile/PECOFF/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginObjectFilePECOFF
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index ccd4400995c7..5f5a0ab07ad6 100644
--- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -192,7 +192,8 @@ ObjectFilePECOFF::ObjectFilePECOFF (const lldb::ModuleSP &module_sp,
m_dos_header (),
m_coff_header (),
m_coff_header_opt (),
- m_sect_headers ()
+ m_sect_headers (),
+ m_entry_point_address ()
{
::memset (&m_dos_header, 0, sizeof(m_dos_header));
::memset (&m_coff_header, 0, sizeof(m_coff_header));
@@ -211,7 +212,7 @@ ObjectFilePECOFF::ParseHeader ()
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
m_sect_headers.clear();
m_data.SetByteOrder (eByteOrderLittle);
lldb::offset_t offset = 0;
@@ -533,13 +534,13 @@ ObjectFilePECOFF::GetSymtab()
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_symtab_ap.get() == NULL)
{
SectionList *sect_list = GetSectionList();
m_symtab_ap.reset(new Symtab(this));
- Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
-
+ std::lock_guard<std::recursive_mutex> guard(m_symtab_ap->GetMutex());
+
const uint32_t num_syms = m_coff_header.nsyms;
if (num_syms > 0 && m_coff_header.symoff > 0)
@@ -662,6 +663,7 @@ ObjectFilePECOFF::GetSymtab()
symbols[i].SetDebug(true);
}
}
+ m_symtab_ap->CalculateSymbolSizes();
}
}
return m_symtab_ap.get();
@@ -687,7 +689,7 @@ ObjectFilePECOFF::CreateSections (SectionList &unified_section_list)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
const uint32_t nsects = m_sect_headers.size();
ModuleSP module_sp (GetModule());
for (uint32_t idx = 0; idx<nsects; ++idx)
@@ -813,6 +815,25 @@ ObjectFilePECOFF::GetDependentModules (FileSpecList& files)
return 0;
}
+lldb_private::Address
+ObjectFilePECOFF::GetEntryPointAddress ()
+{
+ if (m_entry_point_address.IsValid())
+ return m_entry_point_address;
+
+ if (!ParseHeader() || !IsExecutable())
+ return m_entry_point_address;
+
+ SectionList *section_list = GetSectionList();
+ addr_t offset = m_coff_header_opt.entry;
+
+ if (!section_list)
+ m_entry_point_address.SetOffset(offset);
+ else
+ m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
+ return m_entry_point_address;
+}
+
//----------------------------------------------------------------------
// Dump
@@ -826,7 +847,7 @@ ObjectFilePECOFF::Dump(Stream *s)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
s->Printf("%p: ", static_cast<void*>(this));
s->Indent();
s->PutCString("ObjectFilePECOFF");
diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
index 44e5ee1b044b..6c1cdbf56c6b 100644
--- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -144,8 +144,8 @@ public:
uint32_t
GetDependentModules(lldb_private::FileSpecList& files) override;
-// virtual lldb_private::Address
-// GetEntryPointAddress ();
+ virtual lldb_private::Address
+ GetEntryPointAddress () override;
ObjectFile::Type
CalculateType() override;
@@ -301,6 +301,7 @@ private:
coff_opt_header_t m_coff_header_opt;
SectionHeaderColl m_sect_headers;
lldb::addr_t m_image_base;
+ lldb_private::Address m_entry_point_address;
};
#endif // liblldb_ObjectFilePECOFF_h_
diff --git a/source/Plugins/OperatingSystem/Go/Makefile b/source/Plugins/OperatingSystem/Go/Makefile
deleted file mode 100644
index 7d06d483d3ae..000000000000
--- a/source/Plugins/OperatingSystem/Go/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##==- source/Plugins/OperatingSystem/Go/Makefile --------*- Makefile -*-==##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginOSGo
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
index 86c574f2776c..ec0b7014d4d4 100644
--- a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
+++ b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
@@ -197,7 +197,7 @@ OperatingSystemGo::CreateInstance(Process *process, bool force)
if (!target_sp)
return nullptr;
ModuleList &module_list = target_sp->GetImages();
- Mutex::Locker modules_locker(module_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
const size_t num_modules = module_list.GetSize();
bool found_go_runtime = false;
for (size_t i = 0; i < num_modules; ++i)
@@ -249,8 +249,19 @@ OperatingSystemGo::Init(ThreadList &threads)
TargetSP target_sp = m_process->CalculateTarget();
if (!target_sp)
return false;
- m_allg_sp = FindGlobal(target_sp, "runtime.allg");
- m_allglen_sp = FindGlobal(target_sp, "runtime.allglen");
+ // Go 1.6 stores goroutines in a slice called runtime.allgs
+ ValueObjectSP allgs_sp = FindGlobal(target_sp, "runtime.allgs");
+ if (allgs_sp)
+ {
+ m_allg_sp = allgs_sp->GetChildMemberWithName(ConstString("array"), true);
+ m_allglen_sp = allgs_sp->GetChildMemberWithName(ConstString("len"), true);
+ }
+ else
+ {
+ // Go 1.4 stores goroutines in the variable runtime.allg.
+ m_allg_sp = FindGlobal(target_sp, "runtime.allg");
+ m_allglen_sp = FindGlobal(target_sp, "runtime.allglen");
+ }
if (m_allg_sp && !m_allglen_sp)
{
@@ -506,7 +517,7 @@ OperatingSystemGo::Goroutine
OperatingSystemGo::CreateGoroutineAtIndex(uint64_t idx, Error &err)
{
err.Clear();
- Goroutine result;
+ Goroutine result = {};
ValueObjectSP g = m_allg_sp->GetSyntheticArrayMember(idx, true)->Dereference(err);
if (err.Fail())
{
diff --git a/source/Plugins/OperatingSystem/Python/Makefile b/source/Plugins/OperatingSystem/Python/Makefile
deleted file mode 100644
index 67cd0acd7038..000000000000
--- a/source/Plugins/OperatingSystem/Python/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##==- source/Plugins/OperatingSystem/Python/Makefile --------*- Makefile -*-==##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginOSPython
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index a556b0e84e83..dfb631e399f1 100644
--- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -183,16 +183,16 @@ OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list,
// This is a recursive lock so we can grant it to any Python code called on
// the stack below us.
Target &target = m_process->GetTarget();
- Mutex::Locker api_locker;
- api_locker.TryLock(target.GetAPIMutex());
-
+ std::unique_lock<std::recursive_mutex> lock(target.GetAPIMutex(), std::defer_lock);
+ lock.try_lock();
+
if (log)
log->Printf ("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
// lldb_private::Process subclass, no memory threads will be in this list.
-
- auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure threads_list stays alive
+
+ auto interpreter_lock = m_interpreter->AcquireInterpreterLock(); // to make sure threads_list stays alive
StructuredData::ArraySP threads_list = m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp);
const uint32_t num_cores = core_thread_list.GetSize(false);
@@ -324,7 +324,7 @@ OperatingSystemPython::CreateRegisterContextForThread (Thread *thread, addr_t re
// content of the process, and we're going to use python, which requires the API lock to do it.
// So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us.
Target &target = m_process->GetTarget();
- Mutex::Locker api_locker (target.GetAPIMutex());
+ std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
@@ -399,8 +399,8 @@ OperatingSystemPython::CreateThread (lldb::tid_t tid, addr_t context)
// content of the process, and we're going to use python, which requires the API lock to do it.
// So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us.
Target &target = m_process->GetTarget();
- Mutex::Locker api_locker (target.GetAPIMutex());
-
+ std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
+
auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure thread_info_dict stays alive
StructuredData::DictionarySP thread_info_dict = m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context);
std::vector<bool> core_used_map;
diff --git a/source/Plugins/Platform/Android/AdbClient.cpp b/source/Plugins/Platform/Android/AdbClient.cpp
index 736447fd22d2..1b07ddba59fc 100644
--- a/source/Plugins/Platform/Android/AdbClient.cpp
+++ b/source/Plugins/Platform/Android/AdbClient.cpp
@@ -8,33 +8,41 @@
//===----------------------------------------------------------------------===//
// Other libraries and framework includes
+#include "AdbClient.h"
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/FileUtilities.h"
+
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataEncoder.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSpec.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/FileUtilities.h"
-
-// Project includes
-#include "AdbClient.h"
#include <limits.h>
#include <algorithm>
+#include <cstdlib>
#include <fstream>
#include <sstream>
+// On Windows, transitive dependencies pull in <Windows.h>, which defines a
+// macro that clashes with a method name.
+#ifdef SendMessage
+#undef SendMessage
+#endif
+
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_android;
namespace {
-const uint32_t kReadTimeout = 1000000; // 1 second
+const std::chrono::seconds kReadTimeout(8);
const char * kOKAY = "OKAY";
const char * kFAIL = "FAIL";
const char * kDATA = "DATA";
@@ -53,6 +61,35 @@ const uint32_t kDefaultMode = 0100770; // S_IFREG | S_IRWXU | S_IRWXG
const char * kSocketNamespaceAbstract = "localabstract";
const char * kSocketNamespaceFileSystem = "localfilesystem";
+Error
+ReadAllBytes (Connection &conn, void *buffer, size_t size)
+{
+ using namespace std::chrono;
+
+ Error error;
+ ConnectionStatus status;
+ char *read_buffer = static_cast<char*>(buffer);
+
+ auto now = steady_clock::now();
+ const auto deadline = now + kReadTimeout;
+ size_t total_read_bytes = 0;
+ while (total_read_bytes < size && now < deadline)
+ {
+ uint32_t timeout_usec = duration_cast<microseconds>(deadline - now).count();
+ auto read_bytes =
+ conn.Read(read_buffer + total_read_bytes, size - total_read_bytes, timeout_usec, status, &error);
+ if (error.Fail ())
+ return error;
+ total_read_bytes += read_bytes;
+ if (status != eConnectionStatusSuccess)
+ break;
+ now = steady_clock::now();
+ }
+ if (total_read_bytes < size)
+ error = Error("Unable to read requested number of bytes. Connection status: %d.", status);
+ return error;
+}
+
} // namespace
Error
@@ -63,30 +100,39 @@ AdbClient::CreateByDeviceID(const std::string &device_id, AdbClient &adb)
if (error.Fail())
return error;
- if (device_id.empty())
+ std::string android_serial;
+ if (!device_id.empty())
+ android_serial = device_id;
+ else if (const char *env_serial = std::getenv("ANDROID_SERIAL"))
+ android_serial = env_serial;
+
+ if (android_serial.empty())
{
if (connect_devices.size() != 1)
- return Error("Expected a single connected device, got instead %" PRIu64,
- static_cast<uint64_t>(connect_devices.size()));
-
+ return Error("Expected a single connected device, got instead %zu - try setting 'ANDROID_SERIAL'",
+ connect_devices.size());
adb.SetDeviceID(connect_devices.front());
}
else
{
- auto find_it = std::find(connect_devices.begin(), connect_devices.end(), device_id);
+ auto find_it = std::find(connect_devices.begin(), connect_devices.end(), android_serial);
if (find_it == connect_devices.end())
- return Error("Device \"%s\" not found", device_id.c_str());
+ return Error("Device \"%s\" not found", android_serial.c_str());
adb.SetDeviceID(*find_it);
}
return error;
}
+AdbClient::AdbClient () {}
+
AdbClient::AdbClient (const std::string &device_id)
: m_device_id (device_id)
{
}
+AdbClient::~AdbClient() {}
+
void
AdbClient::SetDeviceID (const std::string &device_id)
{
@@ -103,7 +149,8 @@ Error
AdbClient::Connect ()
{
Error error;
- m_conn.Connect ("connect://localhost:5037", &error);
+ m_conn.reset (new ConnectionFileDescriptor);
+ m_conn->Connect ("connect://localhost:5037", &error);
return error;
}
@@ -131,6 +178,9 @@ AdbClient::GetDevices (DeviceIDList &device_list)
for (const auto device: devices)
device_list.push_back (device.split ('\t').first);
+ // Force disconnect since ADB closes connection after host:devices
+ // response is sent.
+ m_conn.reset ();
return error;
}
@@ -184,7 +234,7 @@ Error
AdbClient::SendMessage (const std::string &packet, const bool reconnect)
{
Error error;
- if (reconnect)
+ if (!m_conn || reconnect)
{
error = Connect ();
if (error.Fail ())
@@ -196,11 +246,11 @@ AdbClient::SendMessage (const std::string &packet, const bool reconnect)
ConnectionStatus status;
- m_conn.Write (length_buffer, 4, status, &error);
+ m_conn->Write (length_buffer, 4, status, &error);
if (error.Fail ())
return error;
- m_conn.Write (packet.c_str (), packet.size (), status, &error);
+ m_conn->Write (packet.c_str (), packet.size (), status, &error);
return error;
}
@@ -251,7 +301,7 @@ AdbClient::ReadMessageStream (std::vector<char>& message, uint32_t timeout_ms)
if (elapsed_time >= timeout_ms)
return Error("Timed out");
- size_t n = m_conn.Read(buffer, sizeof(buffer), 1000 * (timeout_ms - elapsed_time), status, &error);
+ size_t n = m_conn->Read(buffer, sizeof(buffer), 1000 * (timeout_ms - elapsed_time), status, &error);
if (n > 0)
message.insert(message.end(), &buffer[0], &buffer[n]);
}
@@ -304,12 +354,118 @@ AdbClient::SwitchDeviceTransport ()
}
Error
-AdbClient::PullFile (const FileSpec &remote_file, const FileSpec &local_file)
+AdbClient::StartSync ()
+{
+ auto error = SwitchDeviceTransport ();
+ if (error.Fail ())
+ return Error ("Failed to switch to device transport: %s", error.AsCString ());
+
+ error = Sync ();
+ if (error.Fail ())
+ return Error ("Sync failed: %s", error.AsCString ());
+
+ return error;
+}
+
+Error
+AdbClient::Sync ()
{
- auto error = StartSync ();
+ auto error = SendMessage ("sync:", false);
if (error.Fail ())
return error;
+ return ReadResponseStatus ();
+}
+
+Error
+AdbClient::ReadAllBytes (void *buffer, size_t size)
+{
+ return ::ReadAllBytes (*m_conn, buffer, size);
+}
+
+Error
+AdbClient::internalShell(const char *command, uint32_t timeout_ms, std::vector<char> &output_buf)
+{
+ output_buf.clear();
+
+ auto error = SwitchDeviceTransport();
+ if (error.Fail())
+ return Error("Failed to switch to device transport: %s", error.AsCString());
+
+ StreamString adb_command;
+ adb_command.Printf("shell:%s", command);
+ error = SendMessage(adb_command.GetData(), false);
+ if (error.Fail())
+ return error;
+
+ error = ReadResponseStatus();
+ if (error.Fail())
+ return error;
+
+ error = ReadMessageStream(output_buf, timeout_ms);
+ if (error.Fail())
+ return error;
+
+ // ADB doesn't propagate return code of shell execution - if
+ // output starts with /system/bin/sh: most likely command failed.
+ static const char *kShellPrefix = "/system/bin/sh:";
+ if (output_buf.size() > strlen(kShellPrefix))
+ {
+ if (!memcmp(&output_buf[0], kShellPrefix, strlen(kShellPrefix)))
+ return Error("Shell command %s failed: %s", command,
+ std::string(output_buf.begin(), output_buf.end()).c_str());
+ }
+
+ return Error();
+}
+
+Error
+AdbClient::Shell(const char *command, uint32_t timeout_ms, std::string *output)
+{
+ std::vector<char> output_buffer;
+ auto error = internalShell(command, timeout_ms, output_buffer);
+ if (error.Fail())
+ return error;
+
+ if (output)
+ output->assign(output_buffer.begin(), output_buffer.end());
+ return error;
+}
+
+Error
+AdbClient::ShellToFile(const char *command, uint32_t timeout_ms, const FileSpec &output_file_spec)
+{
+ std::vector<char> output_buffer;
+ auto error = internalShell(command, timeout_ms, output_buffer);
+ if (error.Fail())
+ return error;
+
+ const auto output_filename = output_file_spec.GetPath();
+ std::ofstream dst(output_filename, std::ios::out | std::ios::binary);
+ if (!dst.is_open())
+ return Error("Unable to open local file %s", output_filename.c_str());
+
+ dst.write(&output_buffer[0], output_buffer.size());
+ dst.close();
+ if (!dst)
+ return Error("Failed to write file %s", output_filename.c_str());
+ return Error();
+}
+
+std::unique_ptr<AdbClient::SyncService>
+AdbClient::GetSyncService (Error &error)
+{
+ std::unique_ptr<SyncService> sync_service;
+ error = StartSync ();
+ if (error.Success ())
+ sync_service.reset (new SyncService(std::move(m_conn)));
+
+ return sync_service;
+}
+
+Error
+AdbClient::SyncService::internalPullFile (const FileSpec &remote_file, const FileSpec &local_file)
+{
const auto local_file_path = local_file.GetPath ();
llvm::FileRemover local_file_remover (local_file_path.c_str ());
@@ -318,7 +474,7 @@ AdbClient::PullFile (const FileSpec &remote_file, const FileSpec &local_file)
return Error ("Unable to open local file %s", local_file_path.c_str());
const auto remote_file_path = remote_file.GetPath (false);
- error = SendSyncRequest (kRECV, remote_file_path.length (), remote_file_path.c_str ());
+ auto error = SendSyncRequest (kRECV, remote_file_path.length (), remote_file_path.c_str ());
if (error.Fail ())
return error;
@@ -338,12 +494,8 @@ AdbClient::PullFile (const FileSpec &remote_file, const FileSpec &local_file)
}
Error
-AdbClient::PushFile (const FileSpec &local_file, const FileSpec &remote_file)
+AdbClient::SyncService::internalPushFile (const FileSpec &local_file, const FileSpec &remote_file)
{
- auto error = StartSync ();
- if (error.Fail ())
- return error;
-
const auto local_file_path (local_file.GetPath ());
std::ifstream src (local_file_path.c_str(), std::ios::in | std::ios::binary);
if (!src.is_open ())
@@ -352,7 +504,7 @@ AdbClient::PushFile (const FileSpec &local_file, const FileSpec &remote_file)
std::stringstream file_description;
file_description << remote_file.GetPath(false).c_str() << "," << kDefaultMode;
std::string file_description_str = file_description.str();
- error = SendSyncRequest (kSEND, file_description_str.length(), file_description_str.c_str());
+ auto error = SendSyncRequest (kSEND, file_description_str.length(), file_description_str.c_str());
if (error.Fail ())
return error;
@@ -392,67 +544,89 @@ AdbClient::PushFile (const FileSpec &local_file, const FileSpec &remote_file)
}
Error
-AdbClient::StartSync ()
+AdbClient::SyncService::internalStat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime)
{
- auto error = SwitchDeviceTransport ();
+ const std::string remote_file_path (remote_file.GetPath (false));
+ auto error = SendSyncRequest (kSTAT, remote_file_path.length (), remote_file_path.c_str ());
if (error.Fail ())
- return Error ("Failed to switch to device transport: %s", error.AsCString ());
+ return Error ("Failed to send request: %s", error.AsCString ());
- error = Sync ();
+ static const size_t stat_len = strlen (kSTAT);
+ static const size_t response_len = stat_len + (sizeof (uint32_t) * 3);
+
+ std::vector<char> buffer (response_len);
+ error = ReadAllBytes (&buffer[0], buffer.size ());
if (error.Fail ())
- return Error ("Sync failed: %s", error.AsCString ());
+ return Error ("Failed to read response: %s", error.AsCString ());
- return error;
+ DataExtractor extractor (&buffer[0], buffer.size (), eByteOrderLittle, sizeof (void*));
+ offset_t offset = 0;
+
+ const void* command = extractor.GetData (&offset, stat_len);
+ if (!command)
+ return Error ("Failed to get response command");
+ const char* command_str = static_cast<const char*> (command);
+ if (strncmp (command_str, kSTAT, stat_len))
+ return Error ("Got invalid stat command: %s", command_str);
+
+ mode = extractor.GetU32 (&offset);
+ size = extractor.GetU32 (&offset);
+ mtime = extractor.GetU32 (&offset);
+ return Error ();
}
Error
-AdbClient::Sync ()
+AdbClient::SyncService::PullFile (const FileSpec &remote_file, const FileSpec &local_file)
{
- auto error = SendMessage ("sync:", false);
- if (error.Fail ())
- return error;
+ return executeCommand ([this, &remote_file, &local_file]() {
+ return internalPullFile (remote_file, local_file);
+ });
+}
- return ReadResponseStatus ();
+Error
+AdbClient::SyncService::PushFile (const FileSpec &local_file, const FileSpec &remote_file)
+{
+ return executeCommand ([this, &local_file, &remote_file]() {
+ return internalPushFile (local_file, remote_file);
+ });
}
Error
-AdbClient::PullFileChunk (std::vector<char> &buffer, bool &eof)
+AdbClient::SyncService::Stat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime)
{
- buffer.clear ();
+ return executeCommand ([this, &remote_file, &mode, &size, &mtime]() {
+ return internalStat (remote_file, mode, size, mtime);
+ });
+}
- std::string response_id;
- uint32_t data_len;
- auto error = ReadSyncHeader (response_id, data_len);
- if (error.Fail ())
- return error;
+bool
+AdbClient::SyncService::IsConnected () const
+{
+ return m_conn && m_conn->IsConnected ();
+}
- if (response_id == kDATA)
- {
- buffer.resize (data_len, 0);
- error = ReadAllBytes (&buffer[0], data_len);
- if (error.Fail ())
- buffer.clear ();
- }
- else if (response_id == kDONE)
- {
- eof = true;
- }
- else if (response_id == kFAIL)
- {
- std::string error_message (data_len, 0);
- error = ReadAllBytes (&error_message[0], data_len);
- if (error.Fail ())
- return Error ("Failed to read pull error message: %s", error.AsCString ());
- return Error ("Failed to pull file: %s", error_message.c_str ());
- }
- else
- return Error ("Pull failed with unknown response: %s", response_id.c_str ());
+AdbClient::SyncService::SyncService(std::unique_ptr<Connection> &&conn):
+m_conn(std::move(conn))
+{
+}
- return Error ();
+Error
+AdbClient::SyncService::executeCommand (const std::function<Error()> &cmd)
+{
+ if (!m_conn)
+ return Error ("SyncService is disconnected");
+
+ const auto error = cmd ();
+ if (error.Fail ())
+ m_conn.reset ();
+
+ return error;
}
+AdbClient::SyncService::~SyncService () {}
+
Error
-AdbClient::SendSyncRequest (const char *request_id, const uint32_t data_len, const void *data)
+AdbClient::SyncService::SendSyncRequest (const char *request_id, const uint32_t data_len, const void *data)
{
const DataBufferSP data_sp (new DataBufferHeap (kSyncPacketLen, 0));
DataEncoder encoder (data_sp, eByteOrderLittle, sizeof (void*));
@@ -461,17 +635,17 @@ AdbClient::SendSyncRequest (const char *request_id, const uint32_t data_len, con
Error error;
ConnectionStatus status;
- m_conn.Write (data_sp->GetBytes (), kSyncPacketLen, status, &error);
+ m_conn->Write (data_sp->GetBytes (), kSyncPacketLen, status, &error);
if (error.Fail ())
return error;
if (data)
- m_conn.Write (data, data_len, status, &error);
+ m_conn->Write (data, data_len, status, &error);
return error;
}
Error
-AdbClient::ReadSyncHeader (std::string &response_id, uint32_t &data_len)
+AdbClient::SyncService::ReadSyncHeader (std::string &response_id, uint32_t &data_len)
{
char buffer[kSyncPacketLen];
@@ -488,82 +662,44 @@ AdbClient::ReadSyncHeader (std::string &response_id, uint32_t &data_len)
}
Error
-AdbClient::ReadAllBytes (void *buffer, size_t size)
+AdbClient::SyncService::PullFileChunk (std::vector<char> &buffer, bool &eof)
{
- Error error;
- ConnectionStatus status;
- char *read_buffer = static_cast<char*>(buffer);
-
- size_t tota_read_bytes = 0;
- while (tota_read_bytes < size)
- {
- auto read_bytes = m_conn.Read (read_buffer + tota_read_bytes, size - tota_read_bytes, kReadTimeout, status, &error);
- if (error.Fail ())
- return error;
- tota_read_bytes += read_bytes;
- }
- return error;
-}
+ buffer.clear ();
-Error
-AdbClient::Stat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime)
-{
- auto error = StartSync ();
+ std::string response_id;
+ uint32_t data_len;
+ auto error = ReadSyncHeader (response_id, data_len);
if (error.Fail ())
return error;
- const std::string remote_file_path (remote_file.GetPath (false));
- error = SendSyncRequest (kSTAT, remote_file_path.length (), remote_file_path.c_str ());
- if (error.Fail ())
- return Error ("Failed to send request: %s", error.AsCString ());
-
- static const size_t stat_len = strlen (kSTAT);
- static const size_t response_len = stat_len + (sizeof (uint32_t) * 3);
-
- std::vector<char> buffer (response_len);
- error = ReadAllBytes (&buffer[0], buffer.size ());
- if (error.Fail ())
- return Error ("Failed to read response: %s", error.AsCString ());
-
- DataExtractor extractor (&buffer[0], buffer.size (), eByteOrderLittle, sizeof (void*));
- offset_t offset = 0;
-
- const void* command = extractor.GetData (&offset, stat_len);
- if (!command)
- return Error ("Failed to get response command");
- const char* command_str = static_cast<const char*> (command);
- if (strncmp (command_str, kSTAT, stat_len))
- return Error ("Got invalid stat command: %s", command_str);
+ if (response_id == kDATA)
+ {
+ buffer.resize (data_len, 0);
+ error = ReadAllBytes (&buffer[0], data_len);
+ if (error.Fail ())
+ buffer.clear ();
+ }
+ else if (response_id == kDONE)
+ {
+ eof = true;
+ }
+ else if (response_id == kFAIL)
+ {
+ std::string error_message (data_len, 0);
+ error = ReadAllBytes (&error_message[0], data_len);
+ if (error.Fail ())
+ return Error ("Failed to read pull error message: %s", error.AsCString ());
+ return Error ("Failed to pull file: %s", error_message.c_str ());
+ }
+ else
+ return Error ("Pull failed with unknown response: %s", response_id.c_str ());
- mode = extractor.GetU32 (&offset);
- size = extractor.GetU32 (&offset);
- mtime = extractor.GetU32 (&offset);
return Error ();
}
Error
-AdbClient::Shell (const char* command, uint32_t timeout_ms, std::string* output)
+AdbClient::SyncService::ReadAllBytes (void *buffer, size_t size)
{
- auto error = SwitchDeviceTransport ();
- if (error.Fail ())
- return Error ("Failed to switch to device transport: %s", error.AsCString ());
-
- StreamString adb_command;
- adb_command.Printf("shell:%s", command);
- error = SendMessage (adb_command.GetData(), false);
- if (error.Fail ())
- return error;
-
- error = ReadResponseStatus ();
- if (error.Fail ())
- return error;
-
- std::vector<char> in_buffer;
- error = ReadMessageStream (in_buffer, timeout_ms);
- if (error.Fail())
- return error;
-
- if (output)
- output->assign(in_buffer.begin(), in_buffer.end());
- return error;
+ return ::ReadAllBytes (*m_conn, buffer, size);
}
+
diff --git a/source/Plugins/Platform/Android/AdbClient.h b/source/Plugins/Platform/Android/AdbClient.h
index 4ec411d1411d..37973bbdccf8 100644
--- a/source/Plugins/Platform/Android/AdbClient.h
+++ b/source/Plugins/Platform/Android/AdbClient.h
@@ -14,7 +14,9 @@
// C++ Includes
+#include <functional>
#include <list>
+#include <memory>
#include <string>
#include <vector>
@@ -22,7 +24,6 @@
// Project includes
#include "lldb/Core/Error.h"
-#include "lldb/Host/ConnectionFileDescriptor.h"
namespace lldb_private {
@@ -41,12 +42,63 @@ public:
using DeviceIDList = std::list<std::string>;
+ class SyncService
+ {
+ friend class AdbClient;
+
+ public:
+ ~SyncService ();
+
+ Error
+ PullFile (const FileSpec &remote_file, const FileSpec &local_file);
+
+ Error
+ PushFile (const FileSpec &local_file, const FileSpec &remote_file);
+
+ Error
+ Stat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime);
+
+ bool
+ IsConnected () const;
+
+ private:
+ explicit SyncService (std::unique_ptr<Connection> &&conn);
+
+ Error
+ SendSyncRequest (const char *request_id, const uint32_t data_len, const void *data);
+
+ Error
+ ReadSyncHeader (std::string &response_id, uint32_t &data_len);
+
+ Error
+ PullFileChunk (std::vector<char> &buffer, bool &eof);
+
+ Error
+ ReadAllBytes (void *buffer, size_t size);
+
+ Error
+ internalPullFile (const FileSpec &remote_file, const FileSpec &local_file);
+
+ Error
+ internalPushFile (const FileSpec &local_file, const FileSpec &remote_file);
+
+ Error
+ internalStat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime);
+
+ Error
+ executeCommand (const std::function<Error()> &cmd);
+
+ std::unique_ptr<Connection> m_conn;
+ };
+
static Error
CreateByDeviceID(const std::string &device_id, AdbClient &adb);
- AdbClient () = default;
+ AdbClient ();
explicit AdbClient (const std::string &device_id);
+ ~AdbClient();
+
const std::string&
GetDeviceID() const;
@@ -65,16 +117,16 @@ public:
DeletePortForwarding (const uint16_t local_port);
Error
- PullFile (const FileSpec &remote_file, const FileSpec &local_file);
+ Shell (const char* command, uint32_t timeout_ms, std::string* output);
Error
- PushFile (const FileSpec &local_file, const FileSpec &remote_file);
+ ShellToFile(const char *command, uint32_t timeout_ms, const FileSpec &output_file_spec);
- Error
- Stat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime);
+ std::unique_ptr<SyncService>
+ GetSyncService (Error &error);
Error
- Shell (const char* command, uint32_t timeout_ms, std::string* output);
+ SwitchDeviceTransport ();
private:
Error
@@ -90,12 +142,6 @@ private:
SendDeviceMessage (const std::string &packet);
Error
- SendSyncRequest (const char *request_id, const uint32_t data_len, const void *data);
-
- Error
- ReadSyncHeader (std::string &response_id, uint32_t &data_len);
-
- Error
ReadMessage (std::vector<char> &message);
Error
@@ -108,25 +154,23 @@ private:
ReadResponseStatus ();
Error
- SwitchDeviceTransport ();
-
- Error
Sync ();
Error
StartSync ();
Error
- PullFileChunk (std::vector<char> &buffer, bool &eof);
+ internalShell(const char *command, uint32_t timeout_ms, std::vector<char> &output_buf);
Error
- ReadAllBytes (void *buffer, size_t size);
+ ReadAllBytes(void *buffer, size_t size);
std::string m_device_id;
- ConnectionFileDescriptor m_conn;
+ std::unique_ptr<Connection> m_conn;
};
} // namespace platform_android
} // namespace lldb_private
#endif // liblldb_AdbClient_h_
+
diff --git a/source/Plugins/Platform/Android/Makefile b/source/Plugins/Platform/Android/Makefile
deleted file mode 100644
index aa186f924e66..000000000000
--- a/source/Plugins/Platform/Android/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Platform/Android/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginPlatformAndroid
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.cpp b/source/Plugins/Platform/Android/PlatformAndroid.cpp
index e842884c046a..381795171d36 100644
--- a/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ b/source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -225,8 +225,36 @@ PlatformAndroid::GetFile (const FileSpec& source,
if (source_spec.IsRelative())
source_spec = GetRemoteWorkingDirectory ().CopyByAppendingPathComponent (source_spec.GetCString (false));
- AdbClient adb (m_device_id);
- return adb.PullFile (source_spec, destination);
+ Error error;
+ auto sync_service = GetSyncService (error);
+ if (error.Fail ())
+ return error;
+
+ uint32_t mode = 0, size = 0, mtime = 0;
+ error = sync_service->Stat(source_spec, mode, size, mtime);
+ if (error.Fail())
+ return error;
+
+ if (mode != 0)
+ return sync_service->PullFile(source_spec, destination);
+
+ auto source_file = source_spec.GetCString(false);
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("Got mode == 0 on '%s': try to get file via 'shell cat'", source_file);
+
+ if (strchr(source_file, '\'') != nullptr)
+ return Error("Doesn't support single-quotes in filenames");
+
+ // mode == 0 can signify that adbd cannot access the file
+ // due security constraints - try "cat ..." as a fallback.
+ AdbClient adb(m_device_id);
+
+ char cmd[PATH_MAX];
+ snprintf(cmd, sizeof(cmd), "cat '%s'", source_file);
+
+ return adb.ShellToFile(cmd, 60000 /* ms */, destination);
}
Error
@@ -242,9 +270,12 @@ PlatformAndroid::PutFile (const FileSpec& source,
if (destination_spec.IsRelative())
destination_spec = GetRemoteWorkingDirectory ().CopyByAppendingPathComponent (destination_spec.GetCString (false));
- AdbClient adb (m_device_id);
// TODO: Set correct uid and gid on remote file.
- return adb.PushFile(source, destination_spec);
+ Error error;
+ auto sync_service = GetSyncService (error);
+ if (error.Fail ())
+ return error;
+ return sync_service->PushFile(source, destination_spec);
}
const char *
@@ -315,8 +346,9 @@ PlatformAndroid::DownloadSymbolFile (const lldb::ModuleSP& module_sp,
const FileSpec& dst_file_spec)
{
// For oat file we can try to fetch additional debug info from the device
- if (module_sp->GetFileSpec().GetFileNameExtension() != ConstString("oat"))
- return Error("Symbol file downloading only supported for oat files");
+ ConstString extension = module_sp->GetFileSpec().GetFileNameExtension();
+ if (extension != ConstString("oat") && extension != ConstString("odex"))
+ return Error("Symbol file downloading only supported for oat and odex files");
// If we have no information about the platform file we can't execute oatdump
if (!module_sp->GetPlatformFileSpec())
@@ -331,7 +363,6 @@ PlatformAndroid::DownloadSymbolFile (const lldb::ModuleSP& module_sp,
return Error("Symtab already available in the module");
AdbClient adb(m_device_id);
-
std::string tmpdir;
Error error = adb.Shell("mktemp --directory --tmpdir /data/local/tmp", 5000 /* ms */, &tmpdir);
if (error.Fail() || tmpdir.empty())
@@ -387,3 +418,15 @@ PlatformAndroid::GetLibdlFunctionDeclarations() const
extern "C" char* dlerror(void) asm("__dl_dlerror");
)";
}
+
+AdbClient::SyncService*
+PlatformAndroid::GetSyncService (Error &error)
+{
+ if (m_adb_sync_svc && m_adb_sync_svc->IsConnected ())
+ return m_adb_sync_svc.get ();
+
+ AdbClient adb (m_device_id);
+ m_adb_sync_svc = adb.GetSyncService (error);
+ return (error.Success ()) ? m_adb_sync_svc.get () : nullptr;
+}
+
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.h b/source/Plugins/Platform/Android/PlatformAndroid.h
index 119d0a0bdf04..6f7a87ca9fef 100644
--- a/source/Plugins/Platform/Android/PlatformAndroid.h
+++ b/source/Plugins/Platform/Android/PlatformAndroid.h
@@ -12,12 +12,15 @@
// C Includes
// C++ Includes
+#include <memory>
#include <string>
// Other libraries and framework includes
// Project includes
#include "Plugins/Platform/Linux/PlatformLinux.h"
+#include "AdbClient.h"
+
namespace lldb_private {
namespace platform_android {
@@ -102,6 +105,9 @@ namespace platform_android {
GetLibdlFunctionDeclarations() const override;
private:
+ AdbClient::SyncService* GetSyncService (Error &error);
+
+ std::unique_ptr<AdbClient::SyncService> m_adb_sync_svc;
std::string m_device_id;
uint32_t m_sdk_version;
diff --git a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
index 3d91dd6b7a32..f11f2874e356 100644
--- a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
@@ -11,6 +11,8 @@
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Host/common/TCPSocket.h"
+#include "lldb/Host/ConnectionFileDescriptor.h"
+
#include "PlatformAndroidRemoteGDBServer.h"
#include "Utility/UriParser.h"
@@ -258,18 +260,3 @@ PlatformAndroidRemoteGDBServer::ConnectProcess(const char* connect_url,
target,
error);
}
-
-size_t
-PlatformAndroidRemoteGDBServer::ConnectToWaitingProcesses(Debugger& debugger, Error& error)
-{
- std::vector<std::string> connection_urls;
- GetPendingGdbServerList(connection_urls);
-
- for (size_t i = 0; i < connection_urls.size(); ++i)
- {
- ConnectProcess(connection_urls[i].c_str(), nullptr, debugger, nullptr, error);
- if (error.Fail())
- return i; // We already connected to i process succsessfully
- }
- return connection_urls.size();
-}
diff --git a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
index 3d2653812ded..79e273c665eb 100644
--- a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
+++ b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
@@ -46,9 +46,6 @@ public:
lldb_private::Target *target,
lldb_private::Error &error) override;
- size_t
- ConnectToWaitingProcesses(lldb_private::Debugger& debugger, lldb_private::Error& error) override;
-
protected:
std::string m_device_id;
std::map<lldb::pid_t, uint16_t> m_port_forwards;
diff --git a/source/Plugins/Platform/FreeBSD/Makefile b/source/Plugins/Platform/FreeBSD/Makefile
deleted file mode 100644
index e5c25d8504df..000000000000
--- a/source/Plugins/Platform/FreeBSD/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Platform/FreeBSD/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginPlatformFreeBSD
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index 9b3c57501117..83c9247f4682 100644
--- a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -614,84 +614,31 @@ PlatformFreeBSD::GetStatus (Stream &strm)
size_t
PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
{
- ArchSpec arch = target.GetArchitecture();
- const uint8_t *trap_opcode = NULL;
- size_t trap_opcode_size = 0;
-
- switch (arch.GetMachine())
+ switch (target.GetArchitecture().GetMachine())
{
- default:
- assert(false && "Unhandled architecture in PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode()");
- break;
- case llvm::Triple::aarch64:
- {
- static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 };
- trap_opcode = g_aarch64_opcode;
- trap_opcode_size = sizeof(g_aarch64_opcode);
- }
- break;
- // TODO: support big-endian arm and thumb trap codes.
case llvm::Triple::arm:
{
- static const uint8_t g_arm_breakpoint_opcode[] = { 0xfe, 0xde, 0xff, 0xe7 };
- static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };
-
- lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
+ lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
AddressClass addr_class = eAddressClassUnknown;
if (bp_loc_sp)
- addr_class = bp_loc_sp->GetAddress ().GetAddressClass ();
+ {
+ addr_class = bp_loc_sp->GetAddress().GetAddressClass();
+ if (addr_class == eAddressClassUnknown && (bp_loc_sp->GetAddress().GetFileAddress() & 1))
+ addr_class = eAddressClassCodeAlternateISA;
+ }
- if (addr_class == eAddressClassCodeAlternateISA
- || (addr_class == eAddressClassUnknown && (bp_site->GetLoadAddress() & 1)))
+ if (addr_class == eAddressClassCodeAlternateISA)
{
// TODO: Enable when FreeBSD supports thumb breakpoints.
// FreeBSD kernel as of 10.x, does not support thumb breakpoints
- trap_opcode = g_thumb_breakpoint_opcode;
- trap_opcode_size = 0;
- }
- else
- {
- trap_opcode = g_arm_breakpoint_opcode;
- trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
+ return 0;
}
}
- break;
- case llvm::Triple::mips64:
- {
- static const uint8_t g_hex_opcode[] = { 0x00, 0x00, 0x00, 0x0d };
- trap_opcode = g_hex_opcode;
- trap_opcode_size = sizeof(g_hex_opcode);
- }
- break;
- case llvm::Triple::mips64el:
- {
- static const uint8_t g_hex_opcode[] = { 0x0d, 0x00, 0x00, 0x00 };
- trap_opcode = g_hex_opcode;
- trap_opcode_size = sizeof(g_hex_opcode);
- }
- break;
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- {
- static const uint8_t g_ppc_opcode[] = { 0x7f, 0xe0, 0x00, 0x08 };
- trap_opcode = g_ppc_opcode;
- trap_opcode_size = sizeof(g_ppc_opcode);
- }
- break;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- {
- static const uint8_t g_i386_opcode[] = { 0xCC };
- trap_opcode = g_i386_opcode;
- trap_opcode_size = sizeof(g_i386_opcode);
- }
- break;
+ LLVM_FALLTHROUGH;
+ default:
+ return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
}
-
- if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
- return trap_opcode_size;
- return 0;
}
diff --git a/source/Plugins/Platform/Kalimba/Makefile b/source/Plugins/Platform/Kalimba/Makefile
deleted file mode 100644
index c22b7d21c13d..000000000000
--- a/source/Plugins/Platform/Kalimba/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Platform/Kalimba/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginPlatformKalimba
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Platform/Linux/Makefile b/source/Plugins/Platform/Linux/Makefile
deleted file mode 100644
index 2877fddf0bcd..000000000000
--- a/source/Plugins/Platform/Linux/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Platform/Linux/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginPlatformLinux
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.cpp b/source/Plugins/Platform/Linux/PlatformLinux.cpp
index 8dc9769844c7..846e350eec56 100644
--- a/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -485,6 +485,7 @@ PlatformLinux::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
case 6: triple.setArchName("mips"); break;
case 7: triple.setArchName("mips64el"); break;
case 8: triple.setArchName("mipsel"); break;
+ case 9: triple.setArchName("s390x"); break;
default: return false;
}
// Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the vendor by
@@ -522,98 +523,6 @@ PlatformLinux::GetStatus (Stream &strm)
#endif
}
-size_t
-PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target,
- BreakpointSite *bp_site)
-{
- ArchSpec arch = target.GetArchitecture();
- const uint8_t *trap_opcode = NULL;
- size_t trap_opcode_size = 0;
-
- switch (arch.GetMachine())
- {
- default:
- assert(false && "CPU type not supported!");
- break;
-
- case llvm::Triple::aarch64:
- {
- static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 };
- trap_opcode = g_aarch64_opcode;
- trap_opcode_size = sizeof(g_aarch64_opcode);
- }
- break;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- {
- static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
- trap_opcode = g_i386_breakpoint_opcode;
- trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
- }
- break;
- case llvm::Triple::hexagon:
- {
- static const uint8_t g_hex_opcode[] = { 0x0c, 0xdb, 0x00, 0x54 };
- trap_opcode = g_hex_opcode;
- trap_opcode_size = sizeof(g_hex_opcode);
- }
- break;
- case llvm::Triple::arm:
- {
- // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
- // but the linux kernel does otherwise.
- static const uint8_t g_arm_breakpoint_opcode[] = { 0xf0, 0x01, 0xf0, 0xe7 };
- static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };
-
- lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
- AddressClass addr_class = eAddressClassUnknown;
-
- if (bp_loc_sp)
- {
- addr_class = bp_loc_sp->GetAddress ().GetAddressClass ();
-
- if (addr_class == eAddressClassUnknown &&
- (bp_loc_sp->GetAddress ().GetFileAddress () & 1))
- {
- addr_class = eAddressClassCodeAlternateISA;
- }
- }
-
- if (addr_class == eAddressClassCodeAlternateISA)
- {
- trap_opcode = g_thumb_breakpoint_opcode;
- trap_opcode_size = sizeof(g_thumb_breakpoint_opcode);
- }
- else
- {
- trap_opcode = g_arm_breakpoint_opcode;
- trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
- }
- }
- break;
- case llvm::Triple::mips:
- case llvm::Triple::mips64:
- {
- static const uint8_t g_hex_opcode[] = { 0x00, 0x00, 0x00, 0x0d };
- trap_opcode = g_hex_opcode;
- trap_opcode_size = sizeof(g_hex_opcode);
- }
- break;
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64el:
- {
- static const uint8_t g_hex_opcode[] = { 0x0d, 0x00, 0x00, 0x00 };
- trap_opcode = g_hex_opcode;
- trap_opcode_size = sizeof(g_hex_opcode);
- }
- break;
- }
-
- if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
- return trap_opcode_size;
- return 0;
-}
-
int32_t
PlatformLinux::GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info)
{
@@ -762,9 +671,9 @@ PlatformLinux::DebugProcess (ProcessLaunchInfo &launch_info,
if (log)
log->Printf ("PlatformLinux::%s setting up hijacker", __FUNCTION__);
- listener_sp.reset (new Listener("lldb.PlatformLinux.DebugProcess.hijack"));
+ listener_sp = Listener::MakeListener("lldb.PlatformLinux.DebugProcess.hijack");
launch_info.SetHijackListener (listener_sp);
- process_sp->HijackProcessEvents (listener_sp.get ());
+ process_sp->HijackProcessEvents (listener_sp);
}
// Log file actions.
@@ -790,7 +699,7 @@ PlatformLinux::DebugProcess (ProcessLaunchInfo &launch_info,
// Handle the hijacking of process events.
if (listener_sp)
{
- const StateType state = process_sp->WaitForProcessToStop (NULL, NULL, false, listener_sp.get());
+ const StateType state = process_sp->WaitForProcessToStop (NULL, NULL, false, listener_sp);
if (state == eStateStopped)
{
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.h b/source/Plugins/Platform/Linux/PlatformLinux.h
index 770a20c90cce..d99256cff0ea 100644
--- a/source/Plugins/Platform/Linux/PlatformLinux.h
+++ b/source/Plugins/Platform/Linux/PlatformLinux.h
@@ -87,10 +87,6 @@ namespace platform_linux {
bool
GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) override;
- size_t
- GetSoftwareBreakpointTrapOpcode (Target &target,
- BreakpointSite *bp_site) override;
-
int32_t
GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info) override;
diff --git a/source/Plugins/Platform/MacOSX/Makefile b/source/Plugins/Platform/MacOSX/Makefile
deleted file mode 100644
index 4377d369bc19..000000000000
--- a/source/Plugins/Platform/MacOSX/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-##===- source/Plugins/Platform/MacOSX/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LEVEL := $(LLDB_LEVEL)/../..
-
-include $(LEVEL)/Makefile.config
-
-SOURCES += PlatformDarwin.cpp \
- PlatformDarwinKernel.cpp \
- PlatformMacOSX.cpp \
- PlatformRemoteiOS.cpp \
- PlatformRemoteAppleTV.cpp \
- PlatformRemoteAppleWatch.cpp
-
-ifeq ($(HOST_OS),Darwin)
-SOURCES += PlatformAppleSimulator.cpp \
- PlatformiOSSimulator.cpp \
- PlatformiOSSimulatorCoreSimulatorSupport.mm \
- PlatformAppleTVSimulator.cpp \
- PlatformAppleWatchSimulator.cpp
-endif
-
-LIBRARYNAME := lldbPluginPlatformMacOSX
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
-
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
index eea2844d5649..a5f165e1f925 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
@@ -252,7 +252,7 @@ FileSpec
PlatformAppleSimulator::GetCoreSimulatorPath()
{
#if defined(__APPLE__)
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
if (!m_core_simulator_framework_path.hasValue())
{
const char *developer_dir = GetDeveloperDirectory();
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
index f537934a9172..097d58dcfbc1 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
@@ -304,7 +304,7 @@ EnumerateDirectoryCallback (void *baton, FileSpec::FileType file_type, const Fil
const char *
PlatformAppleTVSimulator::GetSDKDirectoryAsCString()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
if (m_sdk_directory.empty())
{
const char *developer_dir = GetDeveloperDirectory();
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
index ea8e789b2920..46e5970bc089 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
@@ -304,7 +304,7 @@ EnumerateDirectoryCallback (void *baton, FileSpec::FileType file_type, const Fil
const char *
PlatformAppleWatchSimulator::GetSDKDirectoryAsCString()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
if (m_sdk_directory.empty())
{
const char *developer_dir = GetDeveloperDirectory();
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index fb38630710a1..f9eada986529 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -583,22 +583,13 @@ PlatformDarwin::GetSharedModule (const ModuleSpec &module_spec,
size_t
PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
{
- const uint8_t *trap_opcode = NULL;
+ const uint8_t *trap_opcode = nullptr;
uint32_t trap_opcode_size = 0;
bool bp_is_thumb = false;
-
+
llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
switch (machine)
{
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- {
- static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
- trap_opcode = g_i386_breakpoint_opcode;
- trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
- }
- break;
-
case llvm::Triple::aarch64:
{
// TODO: fix this with actual darwin breakpoint opcode for arm64.
@@ -611,7 +602,8 @@ PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite
break;
case llvm::Triple::thumb:
- bp_is_thumb = true; // Fall through...
+ bp_is_thumb = true;
+ LLVM_FALLTHROUGH;
case llvm::Triple::arm:
{
static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
@@ -634,7 +626,7 @@ PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite
trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
}
break;
-
+
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
{
@@ -643,12 +635,11 @@ PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite
trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
}
break;
-
+
default:
- assert(!"Unhandled architecture in PlatformDarwin::GetSoftwareBreakpointTrapOpcode()");
- break;
+ return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
}
-
+
if (trap_opcode && trap_opcode_size)
{
if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
@@ -1024,7 +1015,7 @@ PlatformDarwin::ARMGetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch
const char *
PlatformDarwin::GetDeveloperDirectory()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
if (m_developer_directory.empty())
{
bool developer_dir_path_valid = false;
@@ -1166,6 +1157,7 @@ PlatformDarwin::SetThreadCreationBreakpoint (Target &target)
llvm::array_lengthof(g_bp_names),
eFunctionNameTypeFull,
eLanguageTypeUnknown,
+ 0,
skip_prologue,
internal,
hardware);
@@ -1580,10 +1572,10 @@ PlatformDarwin::AddClangModuleCompilationOptionsForSDKType (Target *target, std:
FileSpec sysroot_spec;
// Scope for mutex locker below
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
sysroot_spec = GetSDKDirectoryForModules(sdk_type);
}
-
+
if (sysroot_spec.IsDirectory())
{
options.push_back("-isysroot");
@@ -1703,3 +1695,28 @@ PlatformDarwin::LocateExecutable (const char *basename)
return FileSpec();
}
+
+lldb_private::Error
+PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info)
+{
+ // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr
+ // if the OS_ACTIVITY_DT_MODE environment variable is set. (It doesn't
+ // require any specific value; rather, it just needs to exist).
+ // We will set it here as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag
+ // is not set. Xcode makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell
+ // LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they
+ // specifically want it unset.
+ const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE";
+ auto &env_vars = launch_info.GetEnvironmentEntries();
+ if (!env_vars.ContainsEnvironmentVariable(disable_env_var))
+ {
+ // We want to make sure that OS_ACTIVITY_DT_MODE is set so that
+ // we get os_log and NSLog messages mirrored to the target process
+ // stderr.
+ if (!env_vars.ContainsEnvironmentVariable("OS_ACTIVITY_DT_MODE"))
+ env_vars.AppendArgument("OS_ACTIVITY_DT_MODE=enable");
+ }
+
+ // Let our parent class do the real launching.
+ return PlatformPOSIX::LaunchProcess(launch_info);
+}
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index b280b35da655..faecf4cc5a24 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -98,6 +98,9 @@ public:
lldb_private::FileSpec
LocateExecutable (const char *basename) override;
+ lldb_private::Error
+ LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
+
protected:
void
ReadLibdispatchOffsetsAddress (lldb_private::Process *process);
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
index a502aa03eb26..d3c1c805a83b 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
@@ -30,6 +30,7 @@
#include "lldb/Interpreter/OptionValueFileSpecList.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/Property.h"
+#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -881,12 +882,24 @@ PlatformDarwinKernel::GetSharedModule (const ModuleSpec &module_spec,
ModuleSP module_sp (new Module (kern_spec));
if (module_sp && module_sp->GetObjectFile() && module_sp->MatchesModuleSpec (kern_spec))
{
- Error error;
- error = ModuleList::GetSharedModule (kern_spec, module_sp, NULL, NULL, NULL);
- if (module_sp && module_sp->GetObjectFile())
+ // module_sp is an actual kernel binary we want to add.
+ if (process)
{
+ process->GetTarget().GetImages().AppendIfNeeded (module_sp);
+ error.Clear();
return error;
}
+ else
+ {
+ error = ModuleList::GetSharedModule (kern_spec, module_sp, NULL, NULL, NULL);
+ if (module_sp
+ && module_sp->GetObjectFile()
+ && module_sp->GetObjectFile()->GetType() != ObjectFile::Type::eTypeCoreFile)
+ {
+ return error;
+ }
+ module_sp.reset();
+ }
}
}
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
index 04231f27ff9b..30af2bb2250b 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
@@ -158,14 +158,6 @@ PlatformRemoteAppleTV::CreateInstance (bool force, const ArchSpec *arch)
case llvm::Triple::TvOS: // This is the right triple value for Apple TV debugging
break;
-#if defined(__APPLE__)
- // Only accept "unknown" for the OS if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
-#endif
default:
create = false;
break;
@@ -314,9 +306,14 @@ PlatformRemoteAppleTV::GetContainedFilesIntoVectorOfStringsCallback (void *baton
bool
PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded()
{
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (m_sdk_directory_infos.empty())
{
const char *device_support_dir = GetDeviceSupportDirectory();
+ if (log)
+ {
+ log->Printf ("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded Got DeviceSupport directory %s", device_support_dir);
+ }
if (device_support_dir)
{
const bool find_directories = true;
@@ -341,12 +338,20 @@ PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded()
if (sdk_symbols_symlink_fspec.Exists())
{
m_sdk_directory_infos.push_back(sdk_directory_info);
+ if (log)
+ {
+ log->Printf ("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded added builtin SDK directory %s", sdk_symbols_symlink_fspec.GetPath().c_str());
+ }
}
else
{
sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols");
if (sdk_symbols_symlink_fspec.Exists())
m_sdk_directory_infos.push_back(sdk_directory_info);
+ if (log)
+ {
+ log->Printf ("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded added builtin SDK directory %s", sdk_symbols_symlink_fspec.GetPath().c_str());
+ }
}
}
@@ -374,6 +379,10 @@ PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded()
}
if (local_sdk_cache.Exists())
{
+ if (log)
+ {
+ log->Printf ("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded searching %s for additional SDKs", local_sdk_cache.GetPath().c_str());
+ }
char path[PATH_MAX];
if (local_sdk_cache.GetPath(path, sizeof(path)))
{
@@ -388,6 +397,10 @@ PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded()
for (uint32_t i=num_installed; i<num_sdk_infos; ++i)
{
m_sdk_directory_infos[i].user_cached = true;
+ if (log)
+ {
+ log->Printf ("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded user SDK directory %s", m_sdk_directory_infos[i].directory.GetPath().c_str());
+ }
}
}
}
@@ -572,6 +585,7 @@ uint32_t
PlatformRemoteAppleTV::FindFileInAllSDKs (const char *platform_file_path,
FileSpecList &file_list)
{
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE);
if (platform_file_path && platform_file_path[0] && UpdateSDKDirectoryInfosIfNeeded())
{
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
@@ -579,6 +593,10 @@ PlatformRemoteAppleTV::FindFileInAllSDKs (const char *platform_file_path,
// First try for an exact match of major, minor and update
for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
{
+ if (log)
+ {
+ log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
+ }
if (GetFileInSDK (platform_file_path,
sdk_idx,
local_file))
@@ -618,6 +636,7 @@ PlatformRemoteAppleTV::GetFileInSDKRoot (const char *platform_file_path,
bool symbols_dirs_only,
lldb_private::FileSpec &local_file)
{
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0])
{
char resolved_path[PATH_MAX];
@@ -632,7 +651,13 @@ PlatformRemoteAppleTV::GetFileInSDKRoot (const char *platform_file_path,
local_file.SetFile(resolved_path, true);
if (local_file.Exists())
+ {
+ if (log)
+ {
+ log->Printf ("Found a copy of %s in the SDK dir %s", platform_file_path, sdkroot_path);
+ }
return true;
+ }
}
::snprintf (resolved_path,
@@ -643,7 +668,13 @@ PlatformRemoteAppleTV::GetFileInSDKRoot (const char *platform_file_path,
local_file.SetFile(resolved_path, true);
if (local_file.Exists())
+ {
+ if (log)
+ {
+ log->Printf ("Found a copy of %s in the SDK dir %s/Symbols.Internal", platform_file_path, sdkroot_path);
+ }
return true;
+ }
::snprintf (resolved_path,
sizeof(resolved_path),
"%s/Symbols%s",
@@ -652,7 +683,13 @@ PlatformRemoteAppleTV::GetFileInSDKRoot (const char *platform_file_path,
local_file.SetFile(resolved_path, true);
if (local_file.Exists())
+ {
+ if (log)
+ {
+ log->Printf ("Found a copy of %s in the SDK dir %s/Symbols", platform_file_path, sdkroot_path);
+ }
return true;
+ }
}
return false;
}
@@ -662,6 +699,7 @@ PlatformRemoteAppleTV::GetSymbolFile (const FileSpec &platform_file,
const UUID *uuid_ptr,
FileSpec &local_file)
{
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
Error error;
char platform_file_path[PATH_MAX];
if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
@@ -679,7 +717,13 @@ PlatformRemoteAppleTV::GetSymbolFile (const FileSpec &platform_file,
local_file.SetFile(resolved_path, true);
if (local_file.Exists())
+ {
+ if (log)
+ {
+ log->Printf ("Found a copy of %s in the DeviceSupport dir %s", platform_file_path, os_version_dir);
+ }
return error;
+ }
::snprintf (resolved_path,
sizeof(resolved_path),
@@ -689,7 +733,13 @@ PlatformRemoteAppleTV::GetSymbolFile (const FileSpec &platform_file,
local_file.SetFile(resolved_path, true);
if (local_file.Exists())
+ {
+ if (log)
+ {
+ log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal", platform_file_path, os_version_dir);
+ }
return error;
+ }
::snprintf (resolved_path,
sizeof(resolved_path),
"%s/Symbols/%s",
@@ -698,8 +748,13 @@ PlatformRemoteAppleTV::GetSymbolFile (const FileSpec &platform_file,
local_file.SetFile(resolved_path, true);
if (local_file.Exists())
+ {
+ if (log)
+ {
+ log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols", platform_file_path, os_version_dir);
+ }
return error;
-
+ }
}
local_file = platform_file;
if (local_file.Exists())
@@ -729,6 +784,7 @@ PlatformRemoteAppleTV::GetSharedModule (const ModuleSpec &module_spec,
// then we attempt to get a shared module for the right architecture
// with the right UUID.
const FileSpec &platform_file = module_spec.GetFileSpec();
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE);
Error error;
char platform_file_path[PATH_MAX];
@@ -746,6 +802,10 @@ PlatformRemoteAppleTV::GetSharedModule (const ModuleSpec &module_spec,
const uint32_t connected_sdk_idx = GetConnectedSDKIndex ();
if (connected_sdk_idx < num_sdk_infos)
{
+ if (log)
+ {
+ log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[connected_sdk_idx].directory.GetPath().c_str());
+ }
if (GetFileInSDK (platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec()))
{
module_sp.reset();
@@ -765,6 +825,10 @@ PlatformRemoteAppleTV::GetSharedModule (const ModuleSpec &module_spec,
// will tend to be valid in that same SDK.
if (m_last_module_sdk_idx < num_sdk_infos)
{
+ if (log)
+ {
+ log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[m_last_module_sdk_idx].directory.GetPath().c_str());
+ }
if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec()))
{
module_sp.reset();
@@ -788,6 +852,10 @@ PlatformRemoteAppleTV::GetSharedModule (const ModuleSpec &module_spec,
// it above
continue;
}
+ if (log)
+ {
+ log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
+ }
if (GetFileInSDK (platform_file_path, sdk_idx, platform_module_spec.GetFileSpec()))
{
//printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
@@ -812,6 +880,76 @@ PlatformRemoteAppleTV::GetSharedModule (const ModuleSpec &module_spec,
if (error.Success())
return error;
+ // See if the file is present in any of the module_search_paths_ptr directories.
+ if (!module_sp && module_search_paths_ptr && platform_file)
+ {
+ // create a vector of all the file / directory names in platform_file
+ // e.g. this might be /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
+ //
+ // We'll need to look in the module_search_paths_ptr directories for
+ // both "UIFoundation" and "UIFoundation.framework" -- most likely the
+ // latter will be the one we find there.
+
+ FileSpec platform_pull_apart (platform_file);
+ std::vector<std::string> path_parts;
+ ConstString unix_root_dir("/");
+ while (true)
+ {
+ ConstString part = platform_pull_apart.GetLastPathComponent();
+ platform_pull_apart.RemoveLastPathComponent();
+ if (part.IsEmpty() || part == unix_root_dir)
+ break;
+ path_parts.push_back (part.AsCString());
+ }
+ const size_t path_parts_size = path_parts.size();
+
+ size_t num_module_search_paths = module_search_paths_ptr->GetSize();
+ for (size_t i = 0; i < num_module_search_paths; ++i)
+ {
+ // Create a new FileSpec with this module_search_paths_ptr
+ // plus just the filename ("UIFoundation"), then the parent
+ // dir plus filename ("UIFoundation.framework/UIFoundation")
+ // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
+
+ for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j)
+ {
+ FileSpec path_to_try (module_search_paths_ptr->GetFileSpecAtIndex (i));
+
+ // Add the components backwards. For .../PrivateFrameworks/UIFoundation.framework/UIFoundation
+ // path_parts is
+ // [0] UIFoundation
+ // [1] UIFoundation.framework
+ // [2] PrivateFrameworks
+ //
+ // and if 'j' is 2, we want to append path_parts[1] and then path_parts[0], aka
+ // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr path.
+
+ for (int k = j; k >= 0; --k)
+ {
+ path_to_try.AppendPathComponent (path_parts[k]);
+ }
+
+ if (path_to_try.Exists())
+ {
+ ModuleSpec new_module_spec (module_spec);
+ new_module_spec.GetFileSpec() = path_to_try;
+ Error new_error (Platform::GetSharedModule (new_module_spec,
+ process,
+ module_sp,
+ NULL,
+ old_module_sp_ptr,
+ did_create_ptr));
+
+ if (module_sp)
+ {
+ module_sp->SetPlatformFileSpec (path_to_try);
+ return new_error;
+ }
+ }
+ }
+ }
+ }
+
const bool always_create = false;
error = ModuleList::GetSharedModule (module_spec,
module_sp,
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
index 808fd96a5284..ba59887ccf27 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
@@ -158,14 +158,6 @@ PlatformRemoteAppleWatch::CreateInstance (bool force, const ArchSpec *arch)
case llvm::Triple::WatchOS: // This is the right triple value for Apple Watch debugging
break;
-#if defined(__APPLE__)
- // Only accept "unknown" for the OS if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
-#endif
default:
create = false;
break;
@@ -322,9 +314,14 @@ PlatformRemoteAppleWatch::GetContainedFilesIntoVectorOfStringsCallback (void *ba
bool
PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded()
{
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (m_sdk_directory_infos.empty())
{
const char *device_support_dir = GetDeviceSupportDirectory();
+ if (log)
+ {
+ log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded Got DeviceSupport directory %s", device_support_dir);
+ }
if (device_support_dir)
{
const bool find_directories = true;
@@ -349,12 +346,20 @@ PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded()
if (sdk_symbols_symlink_fspec.Exists())
{
m_sdk_directory_infos.push_back(sdk_directory_info);
+ if (log)
+ {
+ log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded added builtin SDK directory %s", sdk_symbols_symlink_fspec.GetPath().c_str());
+ }
}
else
{
sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols");
if (sdk_symbols_symlink_fspec.Exists())
m_sdk_directory_infos.push_back(sdk_directory_info);
+ if (log)
+ {
+ log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded added builtin SDK directory %s", sdk_symbols_symlink_fspec.GetPath().c_str());
+ }
}
}
@@ -374,6 +379,10 @@ PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded()
}
if (local_sdk_cache.Exists())
{
+ if (log)
+ {
+ log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded searching %s for additional SDKs", local_sdk_cache.GetPath().c_str());
+ }
char path[PATH_MAX];
if (local_sdk_cache.GetPath(path, sizeof(path)))
{
@@ -388,6 +397,10 @@ PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded()
for (uint32_t i=num_installed; i<num_sdk_infos; ++i)
{
m_sdk_directory_infos[i].user_cached = true;
+ if (log)
+ {
+ log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded user SDK directory %s", m_sdk_directory_infos[i].directory.GetPath().c_str());
+ }
}
}
}
@@ -583,6 +596,7 @@ uint32_t
PlatformRemoteAppleWatch::FindFileInAllSDKs (const char *platform_file_path,
FileSpecList &file_list)
{
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE);
if (platform_file_path && platform_file_path[0] && UpdateSDKDirectoryInfosIfNeeded())
{
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
@@ -590,6 +604,10 @@ PlatformRemoteAppleWatch::FindFileInAllSDKs (const char *platform_file_path,
// First try for an exact match of major, minor and update
for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
{
+ if (log)
+ {
+ log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
+ }
if (GetFileInSDK (platform_file_path,
sdk_idx,
local_file))
@@ -629,6 +647,7 @@ PlatformRemoteAppleWatch::GetFileInSDKRoot (const char *platform_file_path,
bool symbols_dirs_only,
lldb_private::FileSpec &local_file)
{
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0])
{
char resolved_path[PATH_MAX];
@@ -643,7 +662,13 @@ PlatformRemoteAppleWatch::GetFileInSDKRoot (const char *platform_file_path,
local_file.SetFile(resolved_path, true);
if (local_file.Exists())
+ {
+ if (log)
+ {
+ log->Printf ("Found a copy of %s in the SDK dir %s", platform_file_path, sdkroot_path);
+ }
return true;
+ }
}
::snprintf (resolved_path,
@@ -654,7 +679,13 @@ PlatformRemoteAppleWatch::GetFileInSDKRoot (const char *platform_file_path,
local_file.SetFile(resolved_path, true);
if (local_file.Exists())
+ {
+ if (log)
+ {
+ log->Printf ("Found a copy of %s in the SDK dir %s/Symbols.Internal", platform_file_path, sdkroot_path);
+ }
return true;
+ }
::snprintf (resolved_path,
sizeof(resolved_path),
"%s/Symbols%s",
@@ -663,7 +694,13 @@ PlatformRemoteAppleWatch::GetFileInSDKRoot (const char *platform_file_path,
local_file.SetFile(resolved_path, true);
if (local_file.Exists())
+ {
+ if (log)
+ {
+ log->Printf ("Found a copy of %s in the SDK dir %s/Symbols", platform_file_path, sdkroot_path);
+ }
return true;
+ }
}
return false;
}
@@ -673,6 +710,7 @@ PlatformRemoteAppleWatch::GetSymbolFile (const FileSpec &platform_file,
const UUID *uuid_ptr,
FileSpec &local_file)
{
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
Error error;
char platform_file_path[PATH_MAX];
if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
@@ -690,7 +728,13 @@ PlatformRemoteAppleWatch::GetSymbolFile (const FileSpec &platform_file,
local_file.SetFile(resolved_path, true);
if (local_file.Exists())
+ {
+ if (log)
+ {
+ log->Printf ("Found a copy of %s in the DeviceSupport dir %s", platform_file_path, os_version_dir);
+ }
return error;
+ }
::snprintf (resolved_path,
sizeof(resolved_path),
@@ -700,7 +744,13 @@ PlatformRemoteAppleWatch::GetSymbolFile (const FileSpec &platform_file,
local_file.SetFile(resolved_path, true);
if (local_file.Exists())
+ {
+ if (log)
+ {
+ log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal", platform_file_path, os_version_dir);
+ }
return error;
+ }
::snprintf (resolved_path,
sizeof(resolved_path),
"%s/Symbols/%s",
@@ -709,7 +759,13 @@ PlatformRemoteAppleWatch::GetSymbolFile (const FileSpec &platform_file,
local_file.SetFile(resolved_path, true);
if (local_file.Exists())
+ {
+ if (log)
+ {
+ log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols", platform_file_path, os_version_dir);
+ }
return error;
+ }
}
local_file = platform_file;
@@ -740,6 +796,7 @@ PlatformRemoteAppleWatch::GetSharedModule (const ModuleSpec &module_spec,
// then we attempt to get a shared module for the right architecture
// with the right UUID.
const FileSpec &platform_file = module_spec.GetFileSpec();
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE);
Error error;
char platform_file_path[PATH_MAX];
@@ -757,6 +814,10 @@ PlatformRemoteAppleWatch::GetSharedModule (const ModuleSpec &module_spec,
const uint32_t connected_sdk_idx = GetConnectedSDKIndex ();
if (connected_sdk_idx < num_sdk_infos)
{
+ if (log)
+ {
+ log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[connected_sdk_idx].directory.GetPath().c_str());
+ }
if (GetFileInSDK (platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec()))
{
module_sp.reset();
@@ -776,6 +837,10 @@ PlatformRemoteAppleWatch::GetSharedModule (const ModuleSpec &module_spec,
// will tend to be valid in that same SDK.
if (m_last_module_sdk_idx < num_sdk_infos)
{
+ if (log)
+ {
+ log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[m_last_module_sdk_idx].directory.GetPath().c_str());
+ }
if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec()))
{
module_sp.reset();
@@ -799,6 +864,10 @@ PlatformRemoteAppleWatch::GetSharedModule (const ModuleSpec &module_spec,
// it above
continue;
}
+ if (log)
+ {
+ log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
+ }
if (GetFileInSDK (platform_file_path, sdk_idx, platform_module_spec.GetFileSpec()))
{
//printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
@@ -823,6 +892,76 @@ PlatformRemoteAppleWatch::GetSharedModule (const ModuleSpec &module_spec,
if (error.Success())
return error;
+ // See if the file is present in any of the module_search_paths_ptr directories.
+ if (!module_sp && module_search_paths_ptr && platform_file)
+ {
+ // create a vector of all the file / directory names in platform_file
+ // e.g. this might be /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
+ //
+ // We'll need to look in the module_search_paths_ptr directories for
+ // both "UIFoundation" and "UIFoundation.framework" -- most likely the
+ // latter will be the one we find there.
+
+ FileSpec platform_pull_apart (platform_file);
+ std::vector<std::string> path_parts;
+ ConstString unix_root_dir("/");
+ while (true)
+ {
+ ConstString part = platform_pull_apart.GetLastPathComponent();
+ platform_pull_apart.RemoveLastPathComponent();
+ if (part.IsEmpty() || part == unix_root_dir)
+ break;
+ path_parts.push_back (part.AsCString());
+ }
+ const size_t path_parts_size = path_parts.size();
+
+ size_t num_module_search_paths = module_search_paths_ptr->GetSize();
+ for (size_t i = 0; i < num_module_search_paths; ++i)
+ {
+ // Create a new FileSpec with this module_search_paths_ptr
+ // plus just the filename ("UIFoundation"), then the parent
+ // dir plus filename ("UIFoundation.framework/UIFoundation")
+ // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
+
+ for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j)
+ {
+ FileSpec path_to_try (module_search_paths_ptr->GetFileSpecAtIndex (i));
+
+ // Add the components backwards. For .../PrivateFrameworks/UIFoundation.framework/UIFoundation
+ // path_parts is
+ // [0] UIFoundation
+ // [1] UIFoundation.framework
+ // [2] PrivateFrameworks
+ //
+ // and if 'j' is 2, we want to append path_parts[1] and then path_parts[0], aka
+ // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr path.
+
+ for (int k = j; k >= 0; --k)
+ {
+ path_to_try.AppendPathComponent (path_parts[k]);
+ }
+
+ if (path_to_try.Exists())
+ {
+ ModuleSpec new_module_spec (module_spec);
+ new_module_spec.GetFileSpec() = path_to_try;
+ Error new_error (Platform::GetSharedModule (new_module_spec,
+ process,
+ module_sp,
+ NULL,
+ old_module_sp_ptr,
+ did_create_ptr));
+
+ if (module_sp)
+ {
+ module_sp->SetPlatformFileSpec (path_to_try);
+ return new_error;
+ }
+ }
+ }
+ }
+ }
+
const bool always_create = false;
error = ModuleList::GetSharedModule (module_spec,
module_sp,
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
index 75afa9019dcd..abc429a72345 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
@@ -142,14 +142,6 @@ PlatformRemoteiOS::CreateInstance (bool force, const ArchSpec *arch)
case llvm::Triple::IOS: // This is the right triple value for iOS debugging
break;
-#if defined(__APPLE__)
- // Only accept "unknown" for the OS if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
-#endif
default:
create = false;
break;
@@ -913,6 +905,76 @@ PlatformRemoteiOS::GetSharedModule (const ModuleSpec &module_spec,
if (error.Success())
return error;
+ // See if the file is present in any of the module_search_paths_ptr directories.
+ if (!module_sp && module_search_paths_ptr && platform_file)
+ {
+ // create a vector of all the file / directory names in platform_file
+ // e.g. this might be /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
+ //
+ // We'll need to look in the module_search_paths_ptr directories for
+ // both "UIFoundation" and "UIFoundation.framework" -- most likely the
+ // latter will be the one we find there.
+
+ FileSpec platform_pull_apart (platform_file);
+ std::vector<std::string> path_parts;
+ ConstString unix_root_dir("/");
+ while (true)
+ {
+ ConstString part = platform_pull_apart.GetLastPathComponent();
+ platform_pull_apart.RemoveLastPathComponent();
+ if (part.IsEmpty() || part == unix_root_dir)
+ break;
+ path_parts.push_back (part.AsCString());
+ }
+ const size_t path_parts_size = path_parts.size();
+
+ size_t num_module_search_paths = module_search_paths_ptr->GetSize();
+ for (size_t i = 0; i < num_module_search_paths; ++i)
+ {
+ // Create a new FileSpec with this module_search_paths_ptr
+ // plus just the filename ("UIFoundation"), then the parent
+ // dir plus filename ("UIFoundation.framework/UIFoundation")
+ // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
+
+ for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j)
+ {
+ FileSpec path_to_try (module_search_paths_ptr->GetFileSpecAtIndex (i));
+
+ // Add the components backwards. For .../PrivateFrameworks/UIFoundation.framework/UIFoundation
+ // path_parts is
+ // [0] UIFoundation
+ // [1] UIFoundation.framework
+ // [2] PrivateFrameworks
+ //
+ // and if 'j' is 2, we want to append path_parts[1] and then path_parts[0], aka
+ // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr path.
+
+ for (int k = j; k >= 0; --k)
+ {
+ path_to_try.AppendPathComponent (path_parts[k]);
+ }
+
+ if (path_to_try.Exists())
+ {
+ ModuleSpec new_module_spec (module_spec);
+ new_module_spec.GetFileSpec() = path_to_try;
+ Error new_error (Platform::GetSharedModule (new_module_spec,
+ process,
+ module_sp,
+ NULL,
+ old_module_sp_ptr,
+ did_create_ptr));
+
+ if (module_sp)
+ {
+ module_sp->SetPlatformFileSpec (path_to_try);
+ return new_error;
+ }
+ }
+ }
+ }
+ }
+
const bool always_create = false;
error = ModuleList::GetSharedModule (module_spec,
module_sp,
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
index cbe9c7949a4a..99b9324417b5 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
@@ -308,7 +308,7 @@ EnumerateDirectoryCallback (void *baton, FileSpec::FileType file_type, const Fil
const char *
PlatformiOSSimulator::GetSDKDirectoryAsCString()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
if (m_sdk_directory.empty())
{
const char *developer_dir = GetDeveloperDirectory();
diff --git a/source/Plugins/Platform/Makefile b/source/Plugins/Platform/Makefile
deleted file mode 100644
index 572b08644074..000000000000
--- a/source/Plugins/Platform/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-##===- source/Plugins/Platform/Makefile --------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../..
-
-include $(LLDB_LEVEL)/../../Makefile.config
-
-PARALLEL_DIRS := gdb-server MacOSX Linux FreeBSD NetBSD POSIX Windows Kalimba Android
-
-# ifeq ($(HOST_OS),Darwin)
-# DIRS += MacOSX
-# endif
-#
-# ifeq ($(HOST_OS),Linux)
-# DIRS += Linux
-# endif
-#
-# ifeq ($(HOST_OS),FreeBSD)
-# DIRS += FreeBSD
-# endif
-#
-# ifeq ($(HOST_OS),GNU/kFreeBSD)
-# DIRS += FreeBSD
-# endif
-#
-# ifeq ($(HOST_OS),NetBSD)
-# DIRS += NetBSD
-# endif
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Platform/NetBSD/Makefile b/source/Plugins/Platform/NetBSD/Makefile
deleted file mode 100644
index 2c480bdbe8da..000000000000
--- a/source/Plugins/Platform/NetBSD/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Platform/NetBSD/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginPlatformNetBSD
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
index 2979d1e438b7..3482d2ae5e20 100644
--- a/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ b/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -585,34 +585,6 @@ PlatformNetBSD::GetStatus (Stream &strm)
Platform::GetStatus(strm);
}
-size_t
-PlatformNetBSD::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
-{
- ArchSpec arch = target.GetArchitecture();
- const uint8_t *trap_opcode = NULL;
- size_t trap_opcode_size = 0;
-
- switch (arch.GetMachine())
- {
- default:
- assert(false && "Unhandled architecture in PlatformNetBSD::GetSoftwareBreakpointTrapOpcode()");
- break;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- {
- static const uint8_t g_i386_opcode[] = { 0xCC };
- trap_opcode = g_i386_opcode;
- trap_opcode_size = sizeof(g_i386_opcode);
- }
- break;
- }
-
- if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
- return trap_opcode_size;
- return 0;
-}
-
-
void
PlatformNetBSD::CalculateTrapHandlerSymbolNames ()
{
diff --git a/source/Plugins/Platform/NetBSD/PlatformNetBSD.h b/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
index b0187be99b05..46d1d1843c63 100644
--- a/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
+++ b/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
@@ -86,10 +86,6 @@ namespace platform_netbsd {
lldb::ModuleSP &module_sp,
const FileSpecList *module_search_paths_ptr) override;
- size_t
- GetSoftwareBreakpointTrapOpcode(Target &target,
- BreakpointSite *bp_site) override;
-
bool
GetRemoteOSVersion () override;
diff --git a/source/Plugins/Platform/POSIX/Makefile b/source/Plugins/Platform/POSIX/Makefile
deleted file mode 100644
index eca927720ba8..000000000000
--- a/source/Plugins/Platform/POSIX/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Platform/POSIX/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginPlatformPOSIX
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index c7564655a11b..bc890695f0ce 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -41,6 +41,9 @@ using namespace lldb_private;
//------------------------------------------------------------------
PlatformPOSIX::PlatformPOSIX (bool is_host) :
Platform(is_host), // This is the local host platform
+m_option_group_platform_rsync(new OptionGroupPlatformRSync()),
+m_option_group_platform_ssh(new OptionGroupPlatformSSH()),
+m_option_group_platform_caching(new OptionGroupPlatformCaching()),
m_remote_platform_sp ()
{
}
@@ -69,14 +72,17 @@ PlatformPOSIX::GetModuleSpec (const FileSpec& module_file_spec,
lldb_private::OptionGroupOptions*
PlatformPOSIX::GetConnectionOptions (lldb_private::CommandInterpreter& interpreter)
{
- if (m_options.get() == NULL)
+ auto iter = m_options.find(&interpreter), end = m_options.end();
+ if (iter == end)
{
- m_options.reset(new OptionGroupOptions(interpreter));
- m_options->Append(new OptionGroupPlatformRSync());
- m_options->Append(new OptionGroupPlatformSSH());
- m_options->Append(new OptionGroupPlatformCaching());
+ std::unique_ptr<lldb_private::OptionGroupOptions> options(new OptionGroupOptions(interpreter));
+ options->Append(m_option_group_platform_rsync.get());
+ options->Append(m_option_group_platform_ssh.get());
+ options->Append(m_option_group_platform_caching.get());
+ m_options[&interpreter] = std::move(options);
}
- return m_options.get();
+
+ return m_options.at(&interpreter).get();
}
bool
@@ -675,29 +681,21 @@ PlatformPOSIX::ConnectRemote (Args& args)
if (error.Success() && m_remote_platform_sp)
{
- if (m_options.get())
+ if (m_option_group_platform_rsync.get() && m_option_group_platform_ssh.get() && m_option_group_platform_caching.get())
{
- OptionGroupOptions* options = m_options.get();
- const OptionGroupPlatformRSync *m_rsync_options =
- static_cast<const OptionGroupPlatformRSync *>(options->GetGroupWithOption('r'));
- const OptionGroupPlatformSSH *m_ssh_options =
- static_cast<const OptionGroupPlatformSSH *>(options->GetGroupWithOption('s'));
- const OptionGroupPlatformCaching *m_cache_options =
- static_cast<const OptionGroupPlatformCaching *>(options->GetGroupWithOption('c'));
-
- if (m_rsync_options->m_rsync)
+ if (m_option_group_platform_rsync->m_rsync)
{
SetSupportsRSync(true);
- SetRSyncOpts(m_rsync_options->m_rsync_opts.c_str());
- SetRSyncPrefix(m_rsync_options->m_rsync_prefix.c_str());
- SetIgnoresRemoteHostname(m_rsync_options->m_ignores_remote_hostname);
+ SetRSyncOpts(m_option_group_platform_rsync->m_rsync_opts.c_str());
+ SetRSyncPrefix(m_option_group_platform_rsync->m_rsync_prefix.c_str());
+ SetIgnoresRemoteHostname(m_option_group_platform_rsync->m_ignores_remote_hostname);
}
- if (m_ssh_options->m_ssh)
+ if (m_option_group_platform_ssh->m_ssh)
{
SetSupportsSSH(true);
- SetSSHOpts(m_ssh_options->m_ssh_opts.c_str());
+ SetSSHOpts(m_option_group_platform_ssh->m_ssh_opts.c_str());
}
- SetLocalCacheDirectory(m_cache_options->m_cache_dir.c_str());
+ SetLocalCacheDirectory(m_option_group_platform_caching->m_cache_dir.c_str());
}
}
@@ -801,13 +799,13 @@ PlatformPOSIX::Attach (ProcessAttachInfo &attach_info,
if (process_sp)
{
- auto listener_sp = attach_info.GetHijackListener();
+ ListenerSP listener_sp = attach_info.GetHijackListener();
if (listener_sp == nullptr)
{
- listener_sp.reset(new Listener("lldb.PlatformPOSIX.attach.hijack"));
+ listener_sp = Listener::MakeListener("lldb.PlatformPOSIX.attach.hijack");
attach_info.SetHijackListener(listener_sp);
}
- process_sp->HijackProcessEvents(listener_sp.get());
+ process_sp->HijackProcessEvents(listener_sp);
error = process_sp->Attach (attach_info);
}
}
@@ -869,7 +867,7 @@ PlatformPOSIX::EvaluateLibdlExpression(lldb_private::Process* process,
return error;
}
- ThreadSP thread_sp(process->GetThreadList().GetSelectedThread());
+ ThreadSP thread_sp(process->GetThreadList().GetExpressionExecutionThread());
if (!thread_sp)
return Error("Selected thread isn't valid");
@@ -884,6 +882,7 @@ PlatformPOSIX::EvaluateLibdlExpression(lldb_private::Process* process,
expr_options.SetIgnoreBreakpoints(true);
expr_options.SetExecutionPolicy(eExecutionPolicyAlways);
expr_options.SetLanguage(eLanguageTypeC_plus_plus);
+ expr_options.SetTimeoutUsec(2000000); // 2 seconds
Error expr_error;
UserExpression::Evaluate(exe_ctx,
@@ -945,7 +944,7 @@ PlatformPOSIX::DoLoadImage(lldb_private::Process* process,
if (image_ptr == 0)
{
ValueObjectSP error_str_sp = result_valobj_sp->GetChildAtIndex(1, true);
- if (error_str_sp && error_str_sp->IsCStringContainer(true))
+ if (error_str_sp)
{
DataBufferSP buffer_sp(new DataBufferHeap(10240,0));
size_t num_chars = error_str_sp->ReadPointedString (buffer_sp, error, 10240).first;
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
index 60f6207d140b..4f1f22002816 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.h
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
@@ -12,6 +12,7 @@
// C Includes
// C++ Includes
+#include <map>
#include <memory>
// Other libraries and framework includes
@@ -192,7 +193,11 @@ public:
ConnectToWaitingProcesses(lldb_private::Debugger& debugger, lldb_private::Error& error) override;
protected:
- std::unique_ptr<lldb_private::OptionGroupOptions> m_options;
+ std::unique_ptr<lldb_private::OptionGroupPlatformRSync> m_option_group_platform_rsync;
+ std::unique_ptr<lldb_private::OptionGroupPlatformSSH> m_option_group_platform_ssh;
+ std::unique_ptr<lldb_private::OptionGroupPlatformCaching> m_option_group_platform_caching;
+
+ std::map<lldb_private::CommandInterpreter*,std::unique_ptr<lldb_private::OptionGroupOptions>> m_options;
lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote POSIX-compliant OS
lldb_private::Error
diff --git a/source/Plugins/Platform/Windows/Makefile b/source/Plugins/Platform/Windows/Makefile
deleted file mode 100644
index b78cd7bfd080..000000000000
--- a/source/Plugins/Platform/Windows/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Platform/Windows/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginPlatformWindows
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Platform/Windows/PlatformWindows.cpp b/source/Plugins/Platform/Windows/PlatformWindows.cpp
index 4172f80176d3..cef5684d9bac 100644
--- a/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ b/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -321,42 +321,6 @@ PlatformWindows::ResolveExecutable (const ModuleSpec &ms,
return error;
}
-size_t
-PlatformWindows::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
-{
- ArchSpec arch = target.GetArchitecture();
- const uint8_t *trap_opcode = nullptr;
- size_t trap_opcode_size = 0;
-
- switch (arch.GetMachine())
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- {
- static const uint8_t g_i386_opcode[] = { 0xCC };
- trap_opcode = g_i386_opcode;
- trap_opcode_size = sizeof(g_i386_opcode);
- }
- break;
-
- case llvm::Triple::hexagon:
- {
- static const uint8_t g_hex_opcode[] = { 0x0c, 0xdb, 0x00, 0x54 };
- trap_opcode = g_hex_opcode;
- trap_opcode_size = sizeof(g_hex_opcode);
- }
- break;
- default:
- llvm_unreachable("Unhandled architecture in PlatformWindows::GetSoftwareBreakpointTrapOpcode()");
- break;
- }
-
- if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
- return trap_opcode_size;
-
- return 0;
-}
-
bool
PlatformWindows::GetRemoteOSVersion ()
{
@@ -601,7 +565,7 @@ PlatformWindows::Attach(ProcessAttachInfo &attach_info,
const char *plugin_name = attach_info.GetProcessPluginName();
process_sp = target->CreateProcess(attach_info.GetListenerForProcess(debugger), plugin_name, nullptr);
- process_sp->HijackProcessEvents(attach_info.GetHijackListener().get());
+ process_sp->HijackProcessEvents(attach_info.GetHijackListener());
if (process_sp)
error = process_sp->Attach (attach_info);
diff --git a/source/Plugins/Platform/Windows/PlatformWindows.h b/source/Plugins/Platform/Windows/PlatformWindows.h
index e9a04b4cc33d..6af178bb8c26 100644
--- a/source/Plugins/Platform/Windows/PlatformWindows.h
+++ b/source/Plugins/Platform/Windows/PlatformWindows.h
@@ -72,10 +72,6 @@ public:
return GetPluginDescriptionStatic(IsHost());
}
- size_t
- GetSoftwareBreakpointTrapOpcode(lldb_private::Target &target,
- lldb_private::BreakpointSite *bp_site) override;
-
bool
GetRemoteOSVersion() override;
diff --git a/source/Plugins/Platform/gdb-server/Makefile b/source/Plugins/Platform/gdb-server/Makefile
deleted file mode 100644
index c56613b2a653..000000000000
--- a/source/Plugins/Platform/gdb-server/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Platform/gdb-server/Makefile ---------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginPlatformGDB
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index f16ea017676f..e64ed66be3ca 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -714,9 +714,9 @@ PlatformRemoteGDBServer::Attach (ProcessAttachInfo &attach_info,
error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
if (error.Success())
{
- auto listener = attach_info.GetHijackListener();
- if (listener != nullptr)
- process_sp->HijackProcessEvents(listener.get());
+ ListenerSP listener_sp = attach_info.GetHijackListener();
+ if (listener_sp)
+ process_sp->HijackProcessEvents(listener_sp);
error = process_sp->Attach(attach_info);
}
@@ -1002,6 +1002,22 @@ PlatformRemoteGDBServer::ConnectProcess(const char* connect_url,
}
size_t
+PlatformRemoteGDBServer::ConnectToWaitingProcesses(Debugger& debugger, Error& error)
+{
+ std::vector<std::string> connection_urls;
+ GetPendingGdbServerList(connection_urls);
+
+ for (size_t i = 0; i < connection_urls.size(); ++i)
+ {
+ ConnectProcess(connection_urls[i].c_str(), nullptr, debugger, nullptr, error);
+ if (error.Fail())
+ return i; // We already connected to i process succsessfully
+ }
+ return connection_urls.size();
+
+}
+
+size_t
PlatformRemoteGDBServer::GetPendingGdbServerList(std::vector<std::string>& connection_urls)
{
std::vector<std::pair<uint16_t, std::string>> remote_servers;
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index 61136f1185e6..9d640f3c174b 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -224,6 +224,9 @@ public:
lldb_private::Target *target,
lldb_private::Error &error) override;
+ size_t
+ ConnectToWaitingProcesses(lldb_private::Debugger& debugger, lldb_private::Error& error) override;
+
virtual size_t
GetPendingGdbServerList(std::vector<std::string>& connection_urls);
diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
index 2b292442399f..3cb1cec6983f 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
@@ -558,22 +558,40 @@ FreeBSDThread::WatchNotify(const ProcessMessage &message)
void
FreeBSDThread::TraceNotify(const ProcessMessage &message)
{
- POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx)
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+
+ // Try to resolve the breakpoint object corresponding to the current PC.
+ assert(GetRegisterContext());
+ lldb::addr_t pc = GetRegisterContext()->GetPC();
+ if (log)
+ log->Printf ("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
+ lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
+
+ // If the current pc is a breakpoint site then set the StopInfo to Breakpoint.
+ // Otherwise, set the StopInfo to Watchpoint or Trace.
+ // If we have an operating system plug-in, we might have set a thread specific breakpoint using the
+ // operating system thread ID, so we can't make any assumptions about the thread ID so we must always
+ // report the breakpoint regardless of the thread.
+ if (bp_site && (bp_site->ValidForThisThread(this) || GetProcess()->GetOperatingSystem () != NULL))
+ SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_site->GetID()));
+ else
{
- uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
- uint32_t wp_idx;
- for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
+ POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
+ if (reg_ctx)
{
- if (reg_ctx->IsWatchpointHit(wp_idx))
+ uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
+ uint32_t wp_idx;
+ for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
{
- WatchNotify(message);
- return;
+ if (reg_ctx->IsWatchpointHit(wp_idx))
+ {
+ WatchNotify(message);
+ return;
+ }
}
}
+ SetStopInfo (StopInfo::CreateStopReasonToTrace(*this));
}
-
- SetStopInfo (StopInfo::CreateStopReasonToTrace(*this));
}
void
diff --git a/source/Plugins/Process/FreeBSD/Makefile b/source/Plugins/Process/FreeBSD/Makefile
deleted file mode 100644
index 7f546540e556..000000000000
--- a/source/Plugins/Process/FreeBSD/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-##===- source/Plugins/Process/FreeBSD/Makefile ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginProcessFreeBSD
-BUILD_ARCHIVE = 1
-
-# Extend the include path so we may locate UnwindLLDB.h
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Utility
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
index 769ccd7248ac..3a72a65da696 100644
--- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
@@ -63,12 +63,12 @@ namespace
lldb::ProcessSP
ProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp,
- Listener &listener,
+ lldb::ListenerSP listener_sp,
const FileSpec *crash_file_path)
{
lldb::ProcessSP process_sp;
if (crash_file_path == NULL)
- process_sp.reset(new ProcessFreeBSD (target_sp, listener, GetFreeBSDSignals()));
+ process_sp.reset(new ProcessFreeBSD (target_sp, listener_sp, GetFreeBSDSignals()));
return process_sp;
}
@@ -143,7 +143,7 @@ ProcessFreeBSD::DoResume()
SetPrivateState(eStateRunning);
- Mutex::Locker lock(m_thread_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
bool do_step = false;
for (tid_collection::const_iterator t_pos = m_run_tids.begin(), t_end = m_run_tids.end(); t_pos != t_end; ++t_pos)
@@ -229,7 +229,7 @@ ProcessFreeBSD::WillResume()
void
ProcessFreeBSD::SendMessage(const ProcessMessage &message)
{
- Mutex::Locker lock(m_message_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
switch (message.GetKind())
{
@@ -269,12 +269,12 @@ ProcessFreeBSD::SendMessage(const ProcessMessage &message)
//------------------------------------------------------------------------------
// Constructors and destructors.
-ProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp, Listener &listener, UnixSignalsSP &unix_signals_sp)
- : Process(target_sp, listener, unix_signals_sp),
+ProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, UnixSignalsSP &unix_signals_sp)
+ : Process(target_sp, listener_sp, unix_signals_sp),
m_byte_order(endian::InlHostByteOrder()),
m_monitor(NULL),
m_module(NULL),
- m_message_mutex (Mutex::eMutexTypeRecursive),
+ m_message_mutex(),
m_exit_now(false),
m_seen_initial_stop(),
m_resume_signo(0)
@@ -603,7 +603,7 @@ ProcessFreeBSD::RefreshStateAfterStop()
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
log->Printf ("ProcessFreeBSD::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size());
- Mutex::Locker lock(m_message_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
// This method used to only handle one message. Changing it to loop allows
// it to handle the case where we hit a breakpoint while handling a different
@@ -630,7 +630,7 @@ ProcessFreeBSD::RefreshStateAfterStop()
if (log)
log->Printf ("ProcessFreeBSD::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
- Mutex::Locker lock(m_thread_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
thread_sp.reset();
@@ -801,7 +801,7 @@ ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify)
// Try to find a vacant watchpoint slot in the inferiors' main thread
uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
- Mutex::Locker lock(m_thread_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
FreeBSDThread *thread = static_cast<FreeBSDThread*>(
m_thread_list.GetThreadAtIndex(0, false).get());
@@ -871,7 +871,7 @@ ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify)
if (wp->IsHardware())
{
bool wp_disabled = true;
- Mutex::Locker lock(m_thread_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
uint32_t thread_count = m_thread_list.GetSize(false);
for (uint32_t i = 0; i < thread_count; ++i)
{
@@ -901,7 +901,7 @@ Error
ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num)
{
Error error;
- Mutex::Locker lock(m_thread_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
FreeBSDThread *thread = static_cast<FreeBSDThread*>(
m_thread_list.GetThreadAtIndex(0, false).get());
if (thread)
@@ -924,7 +924,7 @@ ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after)
uint32_t
ProcessFreeBSD::UpdateThreadListIfNeeded()
{
- Mutex::Locker lock(m_thread_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
// Do not allow recursive updates.
return m_thread_list.GetSize(false);
}
@@ -1015,7 +1015,7 @@ bool
ProcessFreeBSD::IsAThreadRunning()
{
bool is_running = false;
- Mutex::Locker lock(m_thread_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
uint32_t thread_count = m_thread_list.GetSize(false);
for (uint32_t i = 0; i < thread_count; ++i)
{
diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
index 5f9365418d7a..888e2a90ad76 100644
--- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
+++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
@@ -13,8 +13,9 @@
// C Includes
// C++ Includes
-#include <set>
+#include <mutex>
#include <queue>
+#include <set>
// Other libraries and framework includes
#include "lldb/Target/Process.h"
@@ -35,7 +36,7 @@ public:
//------------------------------------------------------------------
static lldb::ProcessSP
CreateInstance(lldb::TargetSP target_sp,
- lldb_private::Listener &listener,
+ lldb::ListenerSP listener_sp,
const lldb_private::FileSpec *crash_file_path);
static void
@@ -54,7 +55,7 @@ public:
// Constructors and destructors
//------------------------------------------------------------------
ProcessFreeBSD(lldb::TargetSP target_sp,
- lldb_private::Listener &listener,
+ lldb::ListenerSP listener_sp,
lldb::UnixSignalsSP &unix_signals_sp);
~ProcessFreeBSD();
@@ -212,7 +213,7 @@ protected:
lldb_private::Module *m_module;
/// Message queue notifying this instance of inferior process state changes.
- lldb_private::Mutex m_message_mutex;
+ std::recursive_mutex m_message_mutex;
std::queue<ProcessMessage> m_message_queue;
/// Drive any exit events to completion.
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index cd016fbd4b8c..16707a5c8b97 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -819,6 +819,8 @@ ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process,
m_terminal_fd(-1),
m_operation(0)
{
+ using namespace std::placeholders;
+
std::unique_ptr<LaunchArgs> args(new LaunchArgs(this, module, argv, envp,
stdin_file_spec,
stdout_file_spec,
@@ -856,7 +858,7 @@ WAIT_AGAIN:
// Finally, start monitoring the child process for change in state.
m_monitor_thread = Host::StartMonitoringChildProcess(
- ProcessMonitor::MonitorCallback, this, GetPID(), true);
+ std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4), GetPID(), true);
if (!m_monitor_thread.IsJoinable())
{
error.SetErrorToGenericError();
@@ -873,6 +875,8 @@ ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process,
m_terminal_fd(-1),
m_operation(0)
{
+ using namespace std::placeholders;
+
sem_init(&m_operation_pending, 0, 0);
sem_init(&m_operation_done, 0, 0);
@@ -906,7 +910,7 @@ WAIT_AGAIN:
// Finally, start monitoring the child process for change in state.
m_monitor_thread = Host::StartMonitoringChildProcess(
- ProcessMonitor::MonitorCallback, this, GetPID(), true);
+ std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4), GetPID(), true);
if (!m_monitor_thread.IsJoinable())
{
error.SetErrorToGenericError();
@@ -1180,14 +1184,9 @@ ProcessMonitor::GetCurrentThreadIDs(std::vector<lldb::tid_t>&thread_ids)
}
bool
-ProcessMonitor::MonitorCallback(void *callback_baton,
- lldb::pid_t pid,
- bool exited,
- int signal,
- int status)
+ProcessMonitor::MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid, bool exited, int signal, int status)
{
ProcessMessage message;
- ProcessMonitor *monitor = static_cast<ProcessMonitor*>(callback_baton);
ProcessFreeBSD *process = monitor->m_process;
assert(process);
bool stop_monitoring;
@@ -1349,7 +1348,7 @@ ProcessMonitor::ServeOperation(OperationArgs *args)
void
ProcessMonitor::DoOperation(Operation *op)
{
- Mutex::Locker lock(m_operation_mutex);
+ std::lock_guard<std::mutex> guard(m_operation_mutex);
m_operation = op;
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
index 07fa6b7869ad..93f6be111361 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.h
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
@@ -15,11 +15,12 @@
#include <signal.h>
// C++ Includes
+#include <mutex>
+
// Other libraries and framework includes
#include "lldb/lldb-types.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostThread.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private
{
@@ -223,7 +224,7 @@ private:
// current operation which must be executed on the privileged thread
Operation *m_operation;
- lldb_private::Mutex m_operation_mutex;
+ std::mutex m_operation_mutex;
// semaphores notified when Operation is ready to be processed and when
// the operation is complete.
@@ -302,8 +303,7 @@ private:
DupDescriptor(const lldb_private::FileSpec &file_spec, int fd, int flags);
static bool
- MonitorCallback(void *callback_baton,
- lldb::pid_t pid, bool exited, int signal, int status);
+ MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid, bool exited, int signal, int status);
static ProcessMessage
MonitorSIGTRAP(ProcessMonitor *monitor,
diff --git a/source/Plugins/Process/Linux/CMakeLists.txt b/source/Plugins/Process/Linux/CMakeLists.txt
index 80de8413d209..8291fef467e3 100644
--- a/source/Plugins/Process/Linux/CMakeLists.txt
+++ b/source/Plugins/Process/Linux/CMakeLists.txt
@@ -9,6 +9,8 @@ add_lldb_library(lldbPluginProcessLinux
NativeRegisterContextLinux_arm64.cpp
NativeRegisterContextLinux_x86_64.cpp
NativeRegisterContextLinux_mips64.cpp
+ NativeRegisterContextLinux_s390x.cpp
NativeThreadLinux.cpp
ProcFileReader.cpp
+ SingleStepCheck.cpp
)
diff --git a/source/Plugins/Process/Linux/Makefile b/source/Plugins/Process/Linux/Makefile
deleted file mode 100644
index 239e94d608e9..000000000000
--- a/source/Plugins/Process/Linux/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-##===- source/Plugins/Process/Linux/Makefile ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginProcessLinux
-BUILD_ARCHIVE = 1
-
-# Extend the include path so we may locate UnwindLLDB.h
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Utility
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 87c76f57830c..b3842302c6db 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -25,15 +25,14 @@
// Other libraries and framework includes
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Error.h"
-#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/State.h"
-#include "lldb/Host/common/NativeBreakpoint.h"
-#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Target/Platform.h"
+#include "lldb/Host/common/NativeBreakpoint.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/Target.h"
@@ -58,7 +57,6 @@
#include "lldb/Host/linux/Personality.h"
#include "lldb/Host/linux/Ptrace.h"
-#include "lldb/Host/linux/Signalfd.h"
#include "lldb/Host/linux/Uio.h"
#include "lldb/Host/android/Android.h"
@@ -111,45 +109,96 @@ static bool ProcessVmReadvSupported()
namespace
{
- Error
- ResolveProcessArchitecture (lldb::pid_t pid, Platform &platform, ArchSpec &arch)
- {
- // Grab process info for the running process.
- ProcessInstanceInfo process_info;
- if (!platform.GetProcessInfo (pid, process_info))
- return Error("failed to get process info");
+Error
+ResolveProcessArchitecture(lldb::pid_t pid, ArchSpec &arch)
+{
+ // Grab process info for the running process.
+ ProcessInstanceInfo process_info;
+ if (!Host::GetProcessInfo(pid, process_info))
+ return Error("failed to get process info");
- // Resolve the executable module.
- ModuleSP exe_module_sp;
- ModuleSpec exe_module_spec(process_info.GetExecutableFile(), process_info.GetArchitecture());
- FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths ());
- Error error = platform.ResolveExecutable(
- exe_module_spec,
- exe_module_sp,
- executable_search_paths.GetSize () ? &executable_search_paths : NULL);
+ // Resolve the executable module.
+ ModuleSpecList module_specs;
+ if (!ObjectFile::GetModuleSpecifications(process_info.GetExecutableFile(), 0, 0, module_specs))
+ return Error("failed to get module specifications");
+ assert(module_specs.GetSize() == 1);
- if (!error.Success ())
- return error;
+ arch = module_specs.GetModuleSpecRefAtIndex(0).GetArchitecture();
+ if (arch.IsValid())
+ return Error();
+ else
+ return Error("failed to retrieve a valid architecture from the exe module");
+}
- // Check if we've got our architecture from the exe_module.
- arch = exe_module_sp->GetArchitecture ();
- if (arch.IsValid ())
- return Error();
- else
- return Error("failed to retrieve a valid architecture from the exe module");
- }
+// Used to notify the parent about which part of the launch sequence failed.
+enum LaunchCallSpecifier
+{
+ ePtraceFailed,
+ eDupStdinFailed,
+ eDupStdoutFailed,
+ eDupStderrFailed,
+ eChdirFailed,
+ eExecFailed,
+ eSetGidFailed,
+ eSetSigMaskFailed,
+ eLaunchCallMax = eSetSigMaskFailed
+};
- void
- DisplayBytes (StreamString &s, void *bytes, uint32_t count)
+static uint8_t LLVM_ATTRIBUTE_NORETURN
+ExitChildAbnormally(LaunchCallSpecifier spec)
+{
+ static_assert(eLaunchCallMax < 0x8, "Have more launch calls than we are able to represent");
+ // This may truncate the topmost bits of the errno because the exit code is only 8 bits wide.
+ // However, it should still give us a pretty good indication of what went wrong. (And the
+ // most common errors have small numbers anyway).
+ _exit(unsigned(spec) | (errno << 3));
+}
+
+// The second member is the errno (or its 5 lowermost bits anyway).
+inline std::pair<LaunchCallSpecifier, uint8_t>
+DecodeChildExitCode(int exit_code)
+{
+ return std::make_pair(LaunchCallSpecifier(exit_code & 0x7), exit_code >> 3);
+}
+
+void
+MaybeLogLaunchInfo(const ProcessLaunchInfo &info)
+{
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (!log)
+ return;
+
+ if (const FileAction *action = info.GetFileActionForFD(STDIN_FILENO))
+ log->Printf("%s: setting STDIN to '%s'", __FUNCTION__, action->GetFileSpec().GetCString());
+ else
+ log->Printf("%s leaving STDIN as is", __FUNCTION__);
+
+ if (const FileAction *action = info.GetFileActionForFD(STDOUT_FILENO))
+ log->Printf("%s setting STDOUT to '%s'", __FUNCTION__, action->GetFileSpec().GetCString());
+ else
+ log->Printf("%s leaving STDOUT as is", __FUNCTION__);
+
+ if (const FileAction *action = info.GetFileActionForFD(STDERR_FILENO))
+ log->Printf("%s setting STDERR to '%s'", __FUNCTION__, action->GetFileSpec().GetCString());
+ else
+ log->Printf("%s leaving STDERR as is", __FUNCTION__);
+
+ int i = 0;
+ for (const char **args = info.GetArguments().GetConstArgumentVector(); *args; ++args, ++i)
+ log->Printf("%s arg %d: \"%s\"", __FUNCTION__, i, *args ? *args : "nullptr");
+}
+
+void
+DisplayBytes(StreamString &s, void *bytes, uint32_t count)
+{
+ uint8_t *ptr = (uint8_t *)bytes;
+ const uint32_t loop_count = std::min<uint32_t>(DEBUG_PTRACE_MAXBYTES, count);
+ for (uint32_t i = 0; i < loop_count; i++)
{
- uint8_t *ptr = (uint8_t *)bytes;
- const uint32_t loop_count = std::min<uint32_t>(DEBUG_PTRACE_MAXBYTES, count);
- for(uint32_t i=0; i<loop_count; i++)
- {
- s.Printf ("[%x]", *ptr);
- ptr++;
- }
+ s.Printf("[%x]", *ptr);
+ ptr++;
}
+}
void
PtraceDisplayBytes(int &req, void *data, size_t data_size)
@@ -239,28 +288,6 @@ EnsureFDFlags(int fd, int flags)
return error;
}
-NativeProcessLinux::LaunchArgs::LaunchArgs(Module *module,
- char const **argv,
- char const **envp,
- const FileSpec &stdin_file_spec,
- const FileSpec &stdout_file_spec,
- const FileSpec &stderr_file_spec,
- const FileSpec &working_dir,
- const ProcessLaunchInfo &launch_info)
- : m_module(module),
- m_argv(argv),
- m_envp(envp),
- m_stdin_file_spec(stdin_file_spec),
- m_stdout_file_spec(stdout_file_spec),
- m_stderr_file_spec(stderr_file_spec),
- m_working_dir(working_dir),
- m_launch_info(launch_info)
-{
-}
-
-NativeProcessLinux::LaunchArgs::~LaunchArgs()
-{ }
-
// -----------------------------------------------------------------------------
// Public Static Methods
// -----------------------------------------------------------------------------
@@ -274,15 +301,7 @@ NativeProcessProtocol::Launch (
{
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- lldb::ModuleSP exe_module_sp;
- PlatformSP platform_sp (Platform::GetHostPlatform ());
- Error error = platform_sp->ResolveExecutable(
- ModuleSpec(launch_info.GetExecutableFile(), launch_info.GetArchitecture()),
- exe_module_sp,
- nullptr);
-
- if (! error.Success())
- return error;
+ Error error;
// Verify the working directory is valid if one was specified.
FileSpec working_dir{launch_info.GetWorkingDirectory()};
@@ -295,59 +314,9 @@ NativeProcessProtocol::Launch (
return error;
}
- const FileAction *file_action;
-
- // Default of empty will mean to use existing open file descriptors.
- FileSpec stdin_file_spec{};
- FileSpec stdout_file_spec{};
- FileSpec stderr_file_spec{};
-
- file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
- if (file_action)
- stdin_file_spec = file_action->GetFileSpec();
-
- file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
- if (file_action)
- stdout_file_spec = file_action->GetFileSpec();
-
- file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
- if (file_action)
- stderr_file_spec = file_action->GetFileSpec();
-
- if (log)
- {
- if (stdin_file_spec)
- log->Printf ("NativeProcessLinux::%s setting STDIN to '%s'",
- __FUNCTION__, stdin_file_spec.GetCString());
- else
- log->Printf ("NativeProcessLinux::%s leaving STDIN as is", __FUNCTION__);
-
- if (stdout_file_spec)
- log->Printf ("NativeProcessLinux::%s setting STDOUT to '%s'",
- __FUNCTION__, stdout_file_spec.GetCString());
- else
- log->Printf ("NativeProcessLinux::%s leaving STDOUT as is", __FUNCTION__);
-
- if (stderr_file_spec)
- log->Printf ("NativeProcessLinux::%s setting STDERR to '%s'",
- __FUNCTION__, stderr_file_spec.GetCString());
- else
- log->Printf ("NativeProcessLinux::%s leaving STDERR as is", __FUNCTION__);
- }
-
// Create the NativeProcessLinux in launch mode.
native_process_sp.reset (new NativeProcessLinux ());
- if (log)
- {
- int i = 0;
- for (const char **args = launch_info.GetArguments ().GetConstArgumentVector (); *args; ++args, ++i)
- {
- log->Printf ("NativeProcessLinux::%s arg %d: \"%s\"", __FUNCTION__, i, *args ? *args : "nullptr");
- ++i;
- }
- }
-
if (!native_process_sp->RegisterNativeDelegate (native_delegate))
{
native_process_sp.reset ();
@@ -355,17 +324,7 @@ NativeProcessProtocol::Launch (
return error;
}
- std::static_pointer_cast<NativeProcessLinux> (native_process_sp)->LaunchInferior (
- mainloop,
- exe_module_sp.get(),
- launch_info.GetArguments ().GetConstArgumentVector (),
- launch_info.GetEnvironmentEntries ().GetConstArgumentVector (),
- stdin_file_spec,
- stdout_file_spec,
- stderr_file_spec,
- working_dir,
- launch_info,
- error);
+ error = std::static_pointer_cast<NativeProcessLinux>(native_process_sp)->LaunchInferior(mainloop, launch_info);
if (error.Fail ())
{
@@ -391,15 +350,9 @@ NativeProcessProtocol::Attach (
if (log && log->GetMask ().Test (POSIX_LOG_VERBOSE))
log->Printf ("NativeProcessLinux::%s(pid = %" PRIi64 ")", __FUNCTION__, pid);
- // Grab the current platform architecture. This should be Linux,
- // since this code is only intended to run on a Linux host.
- PlatformSP platform_sp (Platform::GetHostPlatform ());
- if (!platform_sp)
- return Error("failed to get a valid default platform");
-
// Retrieve the architecture for the running process.
ArchSpec process_arch;
- Error error = ResolveProcessArchitecture (pid, *platform_sp.get (), process_arch);
+ Error error = ResolveProcessArchitecture(pid, process_arch);
if (!error.Success ())
return error;
@@ -428,227 +381,170 @@ NativeProcessLinux::NativeProcessLinux () :
m_arch (),
m_supports_mem_region (eLazyBoolCalculate),
m_mem_region_cache (),
- m_mem_region_cache_mutex(),
m_pending_notification_tid(LLDB_INVALID_THREAD_ID)
{
}
void
-NativeProcessLinux::LaunchInferior (
- MainLoop &mainloop,
- Module *module,
- const char *argv[],
- const char *envp[],
- const FileSpec &stdin_file_spec,
- const FileSpec &stdout_file_spec,
- const FileSpec &stderr_file_spec,
- const FileSpec &working_dir,
- const ProcessLaunchInfo &launch_info,
- Error &error)
+NativeProcessLinux::AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error)
{
+ Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ")", __FUNCTION__, pid);
+
m_sigchld_handle = mainloop.RegisterSignal(SIGCHLD,
[this] (MainLoopBase &) { SigchldHandler(); }, error);
if (! m_sigchld_handle)
return;
- if (module)
- m_arch = module->GetArchitecture ();
+ error = ResolveProcessArchitecture(pid, m_arch);
+ if (!error.Success())
+ return;
- SetState (eStateLaunching);
+ // Set the architecture to the exe architecture.
+ if (log)
+ log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ") detected architecture %s", __FUNCTION__, pid, m_arch.GetArchitectureName ());
- std::unique_ptr<LaunchArgs> args(
- new LaunchArgs(module, argv, envp,
- stdin_file_spec,
- stdout_file_spec,
- stderr_file_spec,
- working_dir,
- launch_info));
+ m_pid = pid;
+ SetState(eStateAttaching);
- Launch(args.get(), error);
+ Attach(pid, error);
}
void
-NativeProcessLinux::AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error)
+NativeProcessLinux::ChildFunc(const ProcessLaunchInfo &info)
{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ")", __FUNCTION__, pid);
+ // Start tracing this child that is about to exec.
+ if (ptrace(PTRACE_TRACEME, 0, nullptr, nullptr) == -1)
+ ExitChildAbnormally(ePtraceFailed);
- m_sigchld_handle = mainloop.RegisterSignal(SIGCHLD,
- [this] (MainLoopBase &) { SigchldHandler(); }, error);
- if (! m_sigchld_handle)
- return;
+ // Do not inherit setgid powers.
+ if (setgid(getgid()) != 0)
+ ExitChildAbnormally(eSetGidFailed);
- // We can use the Host for everything except the ResolveExecutable portion.
- PlatformSP platform_sp = Platform::GetHostPlatform ();
- if (!platform_sp)
+ // Attempt to have our own process group.
+ if (setpgid(0, 0) != 0)
{
- if (log)
- log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 "): no default platform set", __FUNCTION__, pid);
- error.SetErrorString ("no default platform available");
- return;
+ // FIXME log that this failed. This is common.
+ // Don't allow this to prevent an inferior exec.
}
- // Gather info about the process.
- ProcessInstanceInfo process_info;
- if (!platform_sp->GetProcessInfo (pid, process_info))
+ // Dup file descriptors if needed.
+ if (const FileAction *action = info.GetFileActionForFD(STDIN_FILENO))
+ if (!DupDescriptor(action->GetFileSpec(), STDIN_FILENO, O_RDONLY))
+ ExitChildAbnormally(eDupStdinFailed);
+
+ if (const FileAction *action = info.GetFileActionForFD(STDOUT_FILENO))
+ if (!DupDescriptor(action->GetFileSpec(), STDOUT_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
+ ExitChildAbnormally(eDupStdoutFailed);
+
+ if (const FileAction *action = info.GetFileActionForFD(STDERR_FILENO))
+ if (!DupDescriptor(action->GetFileSpec(), STDERR_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
+ ExitChildAbnormally(eDupStderrFailed);
+
+ // Close everything besides stdin, stdout, and stderr that has no file
+ // action to avoid leaking
+ for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd)
+ if (!info.GetFileActionForFD(fd))
+ close(fd);
+
+ // Change working directory
+ if (info.GetWorkingDirectory() && 0 != ::chdir(info.GetWorkingDirectory().GetCString()))
+ ExitChildAbnormally(eChdirFailed);
+
+ // Disable ASLR if requested.
+ if (info.GetFlags().Test(lldb::eLaunchFlagDisableASLR))
{
- if (log)
- log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 "): failed to get process info", __FUNCTION__, pid);
- error.SetErrorString ("failed to get process info");
- return;
+ const int old_personality = personality(LLDB_PERSONALITY_GET_CURRENT_SETTINGS);
+ if (old_personality == -1)
+ {
+ // Can't retrieve Linux personality. Cannot disable ASLR.
+ }
+ else
+ {
+ const int new_personality = personality(ADDR_NO_RANDOMIZE | old_personality);
+ if (new_personality == -1)
+ {
+ // Disabling ASLR failed.
+ }
+ else
+ {
+ // Disabling ASLR succeeded.
+ }
+ }
}
- // Resolve the executable module
- ModuleSP exe_module_sp;
- FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
- ModuleSpec exe_module_spec(process_info.GetExecutableFile(), process_info.GetArchitecture());
- error = platform_sp->ResolveExecutable(exe_module_spec, exe_module_sp,
- executable_search_paths.GetSize() ? &executable_search_paths : NULL);
- if (!error.Success())
- return;
+ // Clear the signal mask to prevent the child from being affected by
+ // any masking done by the parent.
+ sigset_t set;
+ if (sigemptyset(&set) != 0 || pthread_sigmask(SIG_SETMASK, &set, nullptr) != 0)
+ ExitChildAbnormally(eSetSigMaskFailed);
- // Set the architecture to the exe architecture.
- m_arch = exe_module_sp->GetArchitecture();
- if (log)
- log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ") detected architecture %s", __FUNCTION__, pid, m_arch.GetArchitectureName ());
+ const char **argv = info.GetArguments().GetConstArgumentVector();
- m_pid = pid;
- SetState(eStateAttaching);
+ // Propagate the environment if one is not supplied.
+ const char **envp = info.GetEnvironmentEntries().GetConstArgumentVector();
+ if (envp == NULL || envp[0] == NULL)
+ envp = const_cast<const char **>(environ);
- Attach(pid, error);
+ // Execute. We should never return...
+ execve(argv[0], const_cast<char *const *>(argv), const_cast<char *const *>(envp));
+
+ if (errno == ETXTBSY)
+ {
+ // On android M and earlier we can get this error because the adb deamon can hold a write
+ // handle on the executable even after it has finished uploading it. This state lasts
+ // only a short time and happens only when there are many concurrent adb commands being
+ // issued, such as when running the test suite. (The file remains open when someone does
+ // an "adb shell" command in the fork() child before it has had a chance to exec.) Since
+ // this state should clear up quickly, wait a while and then give it one more go.
+ usleep(50000);
+ execve(argv[0], const_cast<char *const *>(argv), const_cast<char *const *>(envp));
+ }
+
+ // ...unless exec fails. In which case we definitely need to end the child here.
+ ExitChildAbnormally(eExecFailed);
}
-::pid_t
-NativeProcessLinux::Launch(LaunchArgs *args, Error &error)
+Error
+NativeProcessLinux::LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info)
{
- assert (args && "null args");
+ Error error;
+ m_sigchld_handle = mainloop.RegisterSignal(SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
+ if (!m_sigchld_handle)
+ return error;
- const char **argv = args->m_argv;
- const char **envp = args->m_envp;
- const FileSpec working_dir = args->m_working_dir;
+ SetState(eStateLaunching);
lldb_utility::PseudoTerminal terminal;
const size_t err_len = 1024;
char err_str[err_len];
lldb::pid_t pid;
- // Propagate the environment if one is not supplied.
- if (envp == NULL || envp[0] == NULL)
- envp = const_cast<const char **>(environ);
+ MaybeLogLaunchInfo(launch_info);
if ((pid = terminal.Fork(err_str, err_len)) == static_cast<lldb::pid_t> (-1))
{
error.SetErrorToGenericError();
error.SetErrorStringWithFormat("Process fork failed: %s", err_str);
- return -1;
+ return error;
}
- // Recognized child exit status codes.
- enum {
- ePtraceFailed = 1,
- eDupStdinFailed,
- eDupStdoutFailed,
- eDupStderrFailed,
- eChdirFailed,
- eExecFailed,
- eSetGidFailed,
- eSetSigMaskFailed
- };
-
// Child process.
if (pid == 0)
{
// First, make sure we disable all logging. If we are logging to stdout, our logs can be
// mistaken for inferior output.
Log::DisableAllLogChannels(nullptr);
- // FIXME consider opening a pipe between parent/child and have this forked child
- // send log info to parent re: launch status.
-
- // Start tracing this child that is about to exec.
- error = PtraceWrapper(PTRACE_TRACEME, 0);
- if (error.Fail())
- exit(ePtraceFailed);
// terminal has already dupped the tty descriptors to stdin/out/err.
// This closes original fd from which they were copied (and avoids
// leaking descriptors to the debugged process.
terminal.CloseSlaveFileDescriptor();
- // Do not inherit setgid powers.
- if (setgid(getgid()) != 0)
- exit(eSetGidFailed);
-
- // Attempt to have our own process group.
- if (setpgid(0, 0) != 0)
- {
- // FIXME log that this failed. This is common.
- // Don't allow this to prevent an inferior exec.
- }
-
- // Dup file descriptors if needed.
- if (args->m_stdin_file_spec)
- if (!DupDescriptor(args->m_stdin_file_spec, STDIN_FILENO, O_RDONLY))
- exit(eDupStdinFailed);
-
- if (args->m_stdout_file_spec)
- if (!DupDescriptor(args->m_stdout_file_spec, STDOUT_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
- exit(eDupStdoutFailed);
-
- if (args->m_stderr_file_spec)
- if (!DupDescriptor(args->m_stderr_file_spec, STDERR_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
- exit(eDupStderrFailed);
-
- // Close everything besides stdin, stdout, and stderr that has no file
- // action to avoid leaking
- for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd)
- if (!args->m_launch_info.GetFileActionForFD(fd))
- close(fd);
-
- // Change working directory
- if (working_dir && 0 != ::chdir(working_dir.GetCString()))
- exit(eChdirFailed);
-
- // Disable ASLR if requested.
- if (args->m_launch_info.GetFlags ().Test (lldb::eLaunchFlagDisableASLR))
- {
- const int old_personality = personality (LLDB_PERSONALITY_GET_CURRENT_SETTINGS);
- if (old_personality == -1)
- {
- // Can't retrieve Linux personality. Cannot disable ASLR.
- }
- else
- {
- const int new_personality = personality (ADDR_NO_RANDOMIZE | old_personality);
- if (new_personality == -1)
- {
- // Disabling ASLR failed.
- }
- else
- {
- // Disabling ASLR succeeded.
- }
- }
- }
-
- // Clear the signal mask to prevent the child from being affected by
- // any masking done by the parent.
- sigset_t set;
- if (sigemptyset(&set) != 0 || pthread_sigmask(SIG_SETMASK, &set, nullptr) != 0)
- exit(eSetSigMaskFailed);
-
- // Execute. We should never return...
- execve(argv[0],
- const_cast<char *const *>(argv),
- const_cast<char *const *>(envp));
-
- // ...unless exec fails. In which case we definitely need to end the child here.
- exit(eExecFailed);
+ ChildFunc(launch_info);
}
- //
- // This is the parent code here.
- //
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
// Wait for the child process to trap on its call to execve.
@@ -665,42 +561,41 @@ NativeProcessLinux::Launch(LaunchArgs *args, Error &error)
// FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid.
SetState (StateType::eStateInvalid);
- return -1;
+ return error;
}
else if (WIFEXITED(status))
{
- // open, dup or execve likely failed for some reason.
- error.SetErrorToGenericError();
- switch (WEXITSTATUS(status))
+ auto p = DecodeChildExitCode(WEXITSTATUS(status));
+ Error child_error(p.second, eErrorTypePOSIX);
+ const char *failure_reason;
+ switch (p.first)
{
case ePtraceFailed:
- error.SetErrorString("Child ptrace failed.");
+ failure_reason = "Child ptrace failed";
break;
case eDupStdinFailed:
- error.SetErrorString("Child open stdin failed.");
+ failure_reason = "Child open stdin failed";
break;
case eDupStdoutFailed:
- error.SetErrorString("Child open stdout failed.");
+ failure_reason = "Child open stdout failed";
break;
case eDupStderrFailed:
- error.SetErrorString("Child open stderr failed.");
+ failure_reason = "Child open stderr failed";
break;
case eChdirFailed:
- error.SetErrorString("Child failed to set working directory.");
+ failure_reason = "Child failed to set working directory";
break;
case eExecFailed:
- error.SetErrorString("Child exec failed.");
+ failure_reason = "Child exec failed";
break;
case eSetGidFailed:
- error.SetErrorString("Child setgid failed.");
+ failure_reason = "Child setgid failed";
break;
case eSetSigMaskFailed:
- error.SetErrorString("Child failed to set signal mask.");
- break;
- default:
- error.SetErrorString("Child returned unknown exit status.");
+ failure_reason = "Child failed to set signal mask";
break;
}
+ error.SetErrorStringWithFormat("%s: %d - %s (error code truncated)", failure_reason, child_error.GetError(), child_error.AsCString());
if (log)
{
@@ -713,7 +608,7 @@ NativeProcessLinux::Launch(LaunchArgs *args, Error &error)
// FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid.
SetState (StateType::eStateInvalid);
- return -1;
+ return error;
}
assert(WIFSTOPPED(status) && (wpid == static_cast< ::pid_t> (pid)) &&
"Could not sync with inferior process.");
@@ -732,13 +627,14 @@ NativeProcessLinux::Launch(LaunchArgs *args, Error &error)
// FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid.
SetState (StateType::eStateInvalid);
- return -1;
+ return error;
}
// Release the master terminal descriptor and pass it off to the
// NativeProcessLinux instance. Similarly stash the inferior pid.
m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
m_pid = pid;
+ launch_info.SetProcessID(pid);
// Set the terminal fd to be in non blocking mode (it simplifies the
// implementation of ProcessLinux::GetSTDOUT to have a non-blocking
@@ -754,12 +650,13 @@ NativeProcessLinux::Launch(LaunchArgs *args, Error &error)
// FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid.
SetState (StateType::eStateInvalid);
- return -1;
+ return error;
}
if (log)
log->Printf ("NativeProcessLinux::%s() adding pid = %" PRIu64, __FUNCTION__, pid);
+ ResolveProcessArchitecture(m_pid, m_arch);
NativeThreadLinuxSP thread_sp = AddThread(pid);
assert (thread_sp && "AddThread() returned a nullptr thread");
thread_sp->SetStoppedBySignal(SIGSTOP);
@@ -772,17 +669,11 @@ NativeProcessLinux::Launch(LaunchArgs *args, Error &error)
if (log)
{
if (error.Success ())
- {
- log->Printf ("NativeProcessLinux::%s inferior launching succeeded", __FUNCTION__);
- }
+ log->Printf("NativeProcessLinux::%s inferior launching succeeded", __FUNCTION__);
else
- {
- log->Printf ("NativeProcessLinux::%s inferior launching failed: %s",
- __FUNCTION__, error.AsCString ());
- return -1;
- }
+ log->Printf("NativeProcessLinux::%s inferior launching failed: %s", __FUNCTION__, error.AsCString());
}
- return pid;
+ return error;
}
::pid_t
@@ -1150,8 +1041,6 @@ NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thr
assert(info.si_signo == SIGTRAP && "Unexpected child signal!");
- Mutex::Locker locker (m_threads_mutex);
-
switch (info.si_code)
{
// TODO: these two cases are required if we want to support tracing of the inferiors' children. We'd need this to debug a monitor.
@@ -1187,7 +1076,7 @@ NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thr
// Exec clears any pending notifications.
m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
- // Remove all but the main thread here. Linux fork creates a new process which only copies the main thread. Mutexes are in undefined state.
+ // Remove all but the main thread here. Linux fork creates a new process which only copies the main thread.
if (log)
log->Printf ("NativeProcessLinux::%s exec received, stop tracking all but main thread", __FUNCTION__);
@@ -1413,8 +1302,6 @@ NativeProcessLinux::MonitorSignal(const siginfo_t &info, NativeThreadLinux &thre
//
// Similarly, ACK signals generated by this monitor.
- Mutex::Locker locker (m_threads_mutex);
-
// Handle the signal.
if (info.si_code == SI_TKILL || info.si_code == SI_USER)
{
@@ -1713,8 +1600,6 @@ NativeProcessLinux::Resume (const ResumeActionList &resume_actions)
bool software_single_step = !SupportHardwareSingleStepping();
- Mutex::Locker locker (m_threads_mutex);
-
if (software_single_step)
{
for (auto thread_sp : m_threads)
@@ -1840,8 +1725,6 @@ NativeProcessLinux::Interrupt ()
if (log)
log->Printf ("NativeProcessLinux::%s selecting running thread for interrupt target", __FUNCTION__);
- Mutex::Locker locker (m_threads_mutex);
-
for (auto thread_sp : m_threads)
{
// The thread shouldn't be null but lets just cover that here.
@@ -1956,6 +1839,9 @@ ParseMemoryRegionInfoFromProcMapsLine (const std::string &maps_line, MemoryRegio
memory_region_info.GetRange ().SetRangeBase (start_address);
memory_region_info.GetRange ().SetRangeEnd (end_address);
+ // Any memory region in /proc/{pid}/maps is by definition mapped into the process.
+ memory_region_info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
+
// Parse out each permission entry.
if (line_extractor.GetBytesLeft () < 4)
return Error ("malformed /proc/{pid}/maps entry, missing some portion of permissions");
@@ -1964,31 +1850,28 @@ ParseMemoryRegionInfoFromProcMapsLine (const std::string &maps_line, MemoryRegio
const char read_perm_char = line_extractor.GetChar ();
if (read_perm_char == 'r')
memory_region_info.SetReadable (MemoryRegionInfo::OptionalBool::eYes);
- else
- {
- assert ( (read_perm_char == '-') && "unexpected /proc/{pid}/maps read permission char" );
+ else if (read_perm_char == '-')
memory_region_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo);
- }
+ else
+ return Error ("unexpected /proc/{pid}/maps read permission char");
// Handle write permission.
const char write_perm_char = line_extractor.GetChar ();
if (write_perm_char == 'w')
memory_region_info.SetWritable (MemoryRegionInfo::OptionalBool::eYes);
- else
- {
- assert ( (write_perm_char == '-') && "unexpected /proc/{pid}/maps write permission char" );
+ else if (write_perm_char == '-')
memory_region_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo);
- }
+ else
+ return Error ("unexpected /proc/{pid}/maps write permission char");
// Handle execute permission.
const char exec_perm_char = line_extractor.GetChar ();
if (exec_perm_char == 'x')
memory_region_info.SetExecutable (MemoryRegionInfo::OptionalBool::eYes);
- else
- {
- assert ( (exec_perm_char == '-') && "unexpected /proc/{pid}/maps exec permission char" );
+ else if (exec_perm_char == '-')
memory_region_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo);
- }
+ else
+ return Error ("unexpected /proc/{pid}/maps exec permission char");
return Error ();
}
@@ -2002,7 +1885,6 @@ NativeProcessLinux::GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInf
// Use an approach that reads memory regions from /proc/{pid}/maps.
// Assume proc maps entries are in ascending order.
// FIXME assert if we find differently.
- Mutex::Locker locker (m_mem_region_cache_mutex);
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Error error;
@@ -2085,6 +1967,7 @@ NativeProcessLinux::GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInf
range_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo);
range_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo);
range_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
return error;
}
@@ -2102,21 +1985,11 @@ NativeProcessLinux::GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInf
// load_addr as start and the amount of bytes betwwen load address and the end of the memory as
// size.
range_info.GetRange ().SetRangeBase (load_addr);
- switch (m_arch.GetAddressByteSize())
- {
- case 4:
- range_info.GetRange ().SetByteSize (0x100000000ull - load_addr);
- break;
- case 8:
- range_info.GetRange ().SetByteSize (0ull - load_addr);
- break;
- default:
- assert(false && "Unrecognized data byte size");
- break;
- }
+ range_info.GetRange ().SetRangeEnd(LLDB_INVALID_ADDRESS);
range_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo);
range_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo);
range_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
return error;
}
@@ -2127,12 +2000,9 @@ NativeProcessLinux::DoStopIDBumped (uint32_t newBumpId)
if (log)
log->Printf ("NativeProcessLinux::%s(newBumpId=%" PRIu32 ") called", __FUNCTION__, newBumpId);
- {
- Mutex::Locker locker (m_mem_region_cache_mutex);
if (log)
log->Printf ("NativeProcessLinux::%s clearing %" PRIu64 " entries from the cache", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ()));
m_mem_region_cache.clear ();
- }
}
Error
@@ -2179,49 +2049,8 @@ NativeProcessLinux::DeallocateMemory (lldb::addr_t addr)
lldb::addr_t
NativeProcessLinux::GetSharedLibraryInfoAddress ()
{
-#if 1
// punt on this for now
return LLDB_INVALID_ADDRESS;
-#else
- // Return the image info address for the exe module
-#if 1
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
-
- ModuleSP module_sp;
- Error error = GetExeModuleSP (module_sp);
- if (error.Fail ())
- {
- if (log)
- log->Warning ("NativeProcessLinux::%s failed to retrieve exe module: %s", __FUNCTION__, error.AsCString ());
- return LLDB_INVALID_ADDRESS;
- }
-
- if (module_sp == nullptr)
- {
- if (log)
- log->Warning ("NativeProcessLinux::%s exe module returned was NULL", __FUNCTION__);
- return LLDB_INVALID_ADDRESS;
- }
-
- ObjectFileSP object_file_sp = module_sp->GetObjectFile ();
- if (object_file_sp == nullptr)
- {
- if (log)
- log->Warning ("NativeProcessLinux::%s exe module returned a NULL object file", __FUNCTION__);
- return LLDB_INVALID_ADDRESS;
- }
-
- return obj_file_sp->GetImageInfoAddress();
-#else
- Target *target = &GetTarget();
- ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
- Address addr = obj_file->GetImageInfoAddress(target);
-
- if (addr.IsValid())
- return addr.GetLoadAddress(target);
- return LLDB_INVALID_ADDRESS;
-#endif
-#endif // punt on this for now
}
size_t
@@ -2231,7 +2060,6 @@ NativeProcessLinux::UpdateThreads ()
// with respect to thread state and they keep the thread list
// populated properly. All this method needs to do is return the
// thread count.
- Mutex::Locker locker (m_threads_mutex);
return m_threads.size ();
}
@@ -2248,6 +2076,7 @@ NativeProcessLinux::GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size)
// FIXME put this behind a breakpoint protocol class that can be
// set per architecture. Need ARM, MIPS support here.
static const uint8_t g_i386_opcode [] = { 0xCC };
+ static const uint8_t g_s390x_opcode[] = { 0x00, 0x01 };
switch (m_arch.GetMachine ())
{
@@ -2256,6 +2085,10 @@ NativeProcessLinux::GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size)
actual_opcode_size = static_cast<uint32_t> (sizeof(g_i386_opcode));
return Error ();
+ case llvm::Triple::systemz:
+ actual_opcode_size = static_cast<uint32_t> (sizeof(g_s390x_opcode));
+ return Error ();
+
case llvm::Triple::arm:
case llvm::Triple::aarch64:
case llvm::Triple::mips64:
@@ -2295,6 +2128,7 @@ NativeProcessLinux::GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hin
static const uint8_t g_i386_opcode [] = { 0xCC };
static const uint8_t g_mips64_opcode[] = { 0x00, 0x00, 0x00, 0x0d };
static const uint8_t g_mips64el_opcode[] = { 0x0d, 0x00, 0x00, 0x00 };
+ static const uint8_t g_s390x_opcode[] = { 0x00, 0x01 };
static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };
switch (m_arch.GetMachine ())
@@ -2338,6 +2172,11 @@ NativeProcessLinux::GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hin
actual_opcode_size = sizeof(g_mips64el_opcode);
return Error ();
+ case llvm::Triple::systemz:
+ trap_opcode_bytes = g_s390x_opcode;
+ actual_opcode_size = sizeof(g_s390x_opcode);
+ return Error ();
+
default:
assert(false && "CPU type not supported!");
return Error ("CPU type not supported");
@@ -2656,43 +2495,6 @@ NativeProcessLinux::WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
}
Error
-NativeProcessLinux::Resume (lldb::tid_t tid, uint32_t signo)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
-
- if (log)
- log->Printf ("NativeProcessLinux::%s() resuming thread = %" PRIu64 " with signal %s", __FUNCTION__, tid,
- Host::GetSignalAsCString(signo));
-
-
-
- intptr_t data = 0;
-
- if (signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = signo;
-
- Error error = PtraceWrapper(PTRACE_CONT, tid, nullptr, (void*)data);
-
- if (log)
- log->Printf ("NativeProcessLinux::%s() resuming thread = %" PRIu64 " result = %s", __FUNCTION__, tid, error.Success() ? "true" : "false");
- return error;
-}
-
-Error
-NativeProcessLinux::SingleStep(lldb::tid_t tid, uint32_t signo)
-{
- intptr_t data = 0;
-
- if (signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = signo;
-
- // If hardware single-stepping is not supported, we just do a continue. The breakpoint on the
- // next instruction has been setup in NativeProcessLinux::Resume.
- return PtraceWrapper(SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP : PTRACE_CONT,
- tid, nullptr, (void*)data);
-}
-
-Error
NativeProcessLinux::GetSignalInfo(lldb::tid_t tid, void *siginfo)
{
return PtraceWrapper(PTRACE_GETSIGINFO, tid, nullptr, siginfo);
@@ -2754,7 +2556,6 @@ NativeProcessLinux::StopTrackingThread (lldb::tid_t thread_id)
bool found = false;
- Mutex::Locker locker (m_threads_mutex);
for (auto it = m_threads.begin (); it != m_threads.end (); ++it)
{
if (*it && ((*it)->GetID () == thread_id))
@@ -2775,8 +2576,6 @@ NativeProcessLinux::AddThread (lldb::tid_t thread_id)
{
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
- Mutex::Locker locker (m_threads_mutex);
-
if (log)
{
log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " adding thread with tid %" PRIu64,
@@ -2980,16 +2779,14 @@ NativeProcessLinux::ResumeThread(NativeThreadLinux &thread, lldb::StateType stat
{
case eStateRunning:
{
- thread.SetRunning();
- const auto resume_result = Resume(thread.GetID(), signo);
+ const auto resume_result = thread.Resume(signo);
if (resume_result.Success())
SetState(eStateRunning, true);
return resume_result;
}
case eStateStepping:
{
- thread.SetStepping();
- const auto step_result = SingleStep(thread.GetID(), signo);
+ const auto step_result = thread.SingleStep(signo);
if (step_result.Success())
SetState(eStateRunning, true);
return step_result;
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.h b/source/Plugins/Process/Linux/NativeProcessLinux.h
index 7bac1dc8dbb7..d5be06f0cb58 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -19,7 +19,6 @@
#include "lldb/Host/Debug.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostThread.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
@@ -27,7 +26,6 @@
namespace lldb_private {
class Error;
- class Module;
class Scalar;
namespace process_linux {
@@ -127,6 +125,9 @@ namespace process_linux {
size_t data_size = 0,
long *result = nullptr);
+ bool
+ SupportHardwareSingleStepping() const;
+
protected:
// ---------------------------------------------------------------------
// NativeProcessProtocol protected interface
@@ -141,7 +142,6 @@ namespace process_linux {
LazyBool m_supports_mem_region;
std::vector<MemoryRegionInfo> m_mem_region_cache;
- Mutex m_mem_region_cache_mutex;
lldb::tid_t m_pending_notification_tid;
@@ -149,54 +149,14 @@ namespace process_linux {
// the relevan breakpoint
std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
- /// @class LauchArgs
- ///
- /// @brief Simple structure to pass data to the thread responsible for
- /// launching a child process.
- struct LaunchArgs
- {
- LaunchArgs(Module *module,
- char const **argv,
- char const **envp,
- const FileSpec &stdin_file_spec,
- const FileSpec &stdout_file_spec,
- const FileSpec &stderr_file_spec,
- const FileSpec &working_dir,
- const ProcessLaunchInfo &launch_info);
-
- ~LaunchArgs();
-
- Module *m_module; // The executable image to launch.
- char const **m_argv; // Process arguments.
- char const **m_envp; // Process environment.
- const FileSpec m_stdin_file_spec; // Redirect stdin if not empty.
- const FileSpec m_stdout_file_spec; // Redirect stdout if not empty.
- const FileSpec m_stderr_file_spec; // Redirect stderr if not empty.
- const FileSpec m_working_dir; // Working directory or empty.
- const ProcessLaunchInfo &m_launch_info;
- };
-
- typedef std::function< ::pid_t(Error &)> InitialOperation;
// ---------------------------------------------------------------------
// Private Instance Methods
// ---------------------------------------------------------------------
NativeProcessLinux ();
- /// Launches an inferior process ready for debugging. Forms the
- /// implementation of Process::DoLaunch.
- void
- LaunchInferior (
- MainLoop &mainloop,
- Module *module,
- char const *argv[],
- char const *envp[],
- const FileSpec &stdin_file_spec,
- const FileSpec &stdout_file_spec,
- const FileSpec &stderr_file_spec,
- const FileSpec &working_dir,
- const ProcessLaunchInfo &launch_info,
- Error &error);
+ Error
+ LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
/// Attaches to an existing process. Forms the
/// implementation of Process::DoAttach
@@ -204,11 +164,11 @@ namespace process_linux {
AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error);
::pid_t
- Launch(LaunchArgs *args, Error &error);
-
- ::pid_t
Attach(lldb::pid_t pid, Error &error);
+ static void
+ ChildFunc(const ProcessLaunchInfo &launch_info) LLVM_ATTRIBUTE_NORETURN;
+
static Error
SetDefaultPtraceOpts(const lldb::pid_t);
@@ -239,9 +199,6 @@ namespace process_linux {
void
MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread, bool exited);
- bool
- SupportHardwareSingleStepping() const;
-
Error
SetupSoftwareSingleStepping(NativeThreadLinux &thread);
@@ -285,16 +242,6 @@ namespace process_linux {
Error
GetEventMessage(lldb::tid_t tid, unsigned long *message);
- /// Resumes the given thread. If @p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
- Error
- Resume(lldb::tid_t tid, uint32_t signo);
-
- /// Single steps the given thread. If @p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
- Error
- SingleStep(lldb::tid_t tid, uint32_t signo);
-
void
NotifyThreadDeath (lldb::tid_t tid);
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
index 79653fc62686..5dfbaff90891 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -592,7 +592,7 @@ NativeRegisterContextLinux_arm::NumSupportedHardwareWatchpoints ()
error = ReadHardwareDebugInfo ();
if (error.Fail())
- return LLDB_INVALID_INDEX32;
+ return 0;
return m_max_hwp_supported;
}
@@ -614,6 +614,7 @@ NativeRegisterContextLinux_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t
return LLDB_INVALID_INDEX32;
uint32_t control_value = 0, wp_index = 0, addr_word_offset = 0, byte_mask = 0;
+ lldb::addr_t real_addr = addr;
// Check if we are setting watchpoint other than read/write/access
// Also update watchpoint flag to match Arm write-read bit configuration.
@@ -637,7 +638,24 @@ NativeRegisterContextLinux_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t
if (size == 0 || size > 4)
return LLDB_INVALID_INDEX32;
- // We can only watch up to four bytes that follow a 4 byte aligned address
+ // Check 4-byte alignment for hardware watchpoint target address.
+ // Below is a hack to recalculate address and size in order to
+ // make sure we can watch non 4-byte alligned addresses as well.
+ if (addr & 0x03)
+ {
+ uint8_t watch_mask = (addr & 0x03) + size;
+
+ if (watch_mask > 0x04)
+ return LLDB_INVALID_INDEX32;
+ else if (watch_mask <= 0x02)
+ size = 2;
+ else if (watch_mask <= 0x04)
+ size = 4;
+
+ addr = addr & (~0x03);
+ }
+
+ // We can only watch up to four bytes that follow a 4 byte aligned address
// per watchpoint register pair, so make sure we can properly encode this.
addr_word_offset = addr % 4;
byte_mask = ((1u << size) - 1u) << addr_word_offset;
@@ -682,6 +700,7 @@ NativeRegisterContextLinux_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t
if ((m_hwp_regs[wp_index].control & 1) == 0)
{
// Update watchpoint in local cache
+ m_hwp_regs[wp_index].real_addr = real_addr;
m_hwp_regs[wp_index].address = addr;
m_hwp_regs[wp_index].control = control_value;
m_hwp_regs[wp_index].refcount = 1;
@@ -864,6 +883,7 @@ NativeRegisterContextLinux_arm::GetWatchpointHitIndex(uint32_t &wp_index, lldb::
if (m_hwp_regs[wp_index].refcount >= 1 && WatchpointIsEnabled(wp_index)
&& trap_addr >= watch_addr && trap_addr < watch_addr + watch_size)
{
+ m_hwp_regs[wp_index].hit_addr = trap_addr;
return Error();
}
}
@@ -884,7 +904,24 @@ NativeRegisterContextLinux_arm::GetWatchpointAddress (uint32_t wp_index)
return LLDB_INVALID_ADDRESS;
if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].address;
+ return m_hwp_regs[wp_index].real_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
+}
+
+lldb::addr_t
+NativeRegisterContextLinux_arm::GetWatchpointHitAddress (uint32_t wp_index)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+
+ if (log)
+ log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
+
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].hit_addr;
else
return LLDB_INVALID_ADDRESS;
}
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
index 349564970428..452f13258c2b 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
@@ -74,6 +74,9 @@ namespace process_linux {
GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
lldb::addr_t
+ GetWatchpointHitAddress (uint32_t wp_index) override;
+
+ lldb::addr_t
GetWatchpointAddress (uint32_t wp_index) override;
uint32_t
@@ -162,6 +165,8 @@ namespace process_linux {
struct DREG
{
lldb::addr_t address; // Breakpoint/watchpoint address value.
+ lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception occurred.
+ lldb::addr_t real_addr; // Address value that should cause target to stop.
uint32_t control; // Breakpoint/watchpoint control value.
uint32_t refcount; // Serves as enable/disable and refernce counter.
};
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 22cdbb40d15c..9489f00c1afe 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -32,6 +32,8 @@
#include <sys/socket.h>
// NT_PRSTATUS and NT_FPREGSET definition
#include <elf.h>
+// user_hwdebug_state definition
+#include <asm/ptrace.h>
#define REG_CONTEXT_SIZE (GetGPRSize() + GetFPRSize())
@@ -542,7 +544,7 @@ NativeRegisterContextLinux_arm64::NumSupportedHardwareWatchpoints ()
error = ReadHardwareDebugInfo ();
if (error.Fail())
- return LLDB_INVALID_INDEX32;
+ return 0;
return m_max_hwp_supported;
}
@@ -564,6 +566,7 @@ NativeRegisterContextLinux_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size
return LLDB_INVALID_INDEX32;
uint32_t control_value = 0, wp_index = 0;
+ lldb::addr_t real_addr = addr;
// Check if we are setting watchpoint other than read/write/access
// Also update watchpoint flag to match AArch64 write-read bit configuration.
@@ -586,9 +589,23 @@ NativeRegisterContextLinux_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size
return LLDB_INVALID_INDEX32;
// Check 8-byte alignment for hardware watchpoint target address.
- // TODO: Add support for watching un-aligned addresses
+ // Below is a hack to recalculate address and size in order to
+ // make sure we can watch non 8-byte alligned addresses as well.
if (addr & 0x07)
- return LLDB_INVALID_INDEX32;
+ {
+ uint8_t watch_mask = (addr & 0x07) + size;
+
+ if (watch_mask > 0x08)
+ return LLDB_INVALID_INDEX32;
+ else if (watch_mask <= 0x02)
+ size = 2;
+ else if (watch_mask <= 0x04)
+ size = 4;
+ else
+ size = 8;
+
+ addr = addr & (~0x07);
+ }
// Setup control value
control_value = watch_flags << 3;
@@ -618,6 +635,7 @@ NativeRegisterContextLinux_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size
if ((m_hwp_regs[wp_index].control & 1) == 0)
{
// Update watchpoint in local cache
+ m_hwp_regs[wp_index].real_addr = real_addr;
m_hwp_regs[wp_index].address = addr;
m_hwp_regs[wp_index].control = control_value;
m_hwp_regs[wp_index].refcount = 1;
@@ -799,6 +817,7 @@ NativeRegisterContextLinux_arm64::GetWatchpointHitIndex(uint32_t &wp_index, lldb
if (m_hwp_regs[wp_index].refcount >= 1 && WatchpointIsEnabled(wp_index)
&& trap_addr >= watch_addr && trap_addr < watch_addr + watch_size)
{
+ m_hwp_regs[wp_index].hit_addr = trap_addr;
return Error();
}
}
@@ -819,7 +838,24 @@ NativeRegisterContextLinux_arm64::GetWatchpointAddress (uint32_t wp_index)
return LLDB_INVALID_ADDRESS;
if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].address;
+ return m_hwp_regs[wp_index].real_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
+}
+
+lldb::addr_t
+NativeRegisterContextLinux_arm64::GetWatchpointHitAddress (uint32_t wp_index)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+
+ if (log)
+ log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
+
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].hit_addr;
else
return LLDB_INVALID_ADDRESS;
}
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
index c60baa637b8a..4d9a9902ac3c 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -74,6 +74,9 @@ namespace process_linux {
GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
lldb::addr_t
+ GetWatchpointHitAddress (uint32_t wp_index) override;
+
+ lldb::addr_t
GetWatchpointAddress (uint32_t wp_index) override;
uint32_t
@@ -161,6 +164,8 @@ namespace process_linux {
struct DREG
{
lldb::addr_t address; // Breakpoint/watchpoint address value.
+ lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception occurred.
+ lldb::addr_t real_addr; // Address value that should cause target to stop.
uint32_t control; // Breakpoint/watchpoint control value.
uint32_t refcount; // Serves as enable/disable and refernce counter.
};
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
index 54d6f721c9d8..d5a61722da87 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
@@ -824,7 +824,8 @@ NativeRegisterContextLinux_mips64::ReadCP1()
error = NativeRegisterContextLinux::ReadFPR();
}
- if (IsFR0() || IsFRE())
+ // TODO: Add support for FRE
+ if (IsFR0())
{
src = (uint8_t *)&m_fpr + 4 + (IsBigEndian * 4);
dst = (uint8_t *)&m_fpr + 8 + (IsBigEndian * 4);
@@ -851,7 +852,8 @@ NativeRegisterContextLinux_mips64::WriteCP1()
uint32_t IsBigEndian = (byte_order == lldb::eByteOrderBig);
- if (IsFR0() || IsFRE())
+ // TODO: Add support for FRE
+ if (IsFR0())
{
src = (uint8_t *)&m_fpr + 8 + (IsBigEndian * 4);
dst = (uint8_t *)&m_fpr + 4 + (IsBigEndian * 4);
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
new file mode 100644
index 000000000000..b09ad400d909
--- /dev/null
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
@@ -0,0 +1,716 @@
+//===-- NativeRegisterContextLinux_s390x.cpp --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__s390x__) && defined(__linux__)
+
+#include "NativeRegisterContextLinux_s390x.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Host/HostInfo.h"
+
+#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
+
+#include <asm/ptrace.h>
+#include <linux/uio.h>
+#include <sys/ptrace.h>
+
+using namespace lldb_private;
+using namespace lldb_private::process_linux;
+
+// ----------------------------------------------------------------------------
+// Private namespace.
+// ----------------------------------------------------------------------------
+
+namespace
+{
+ // s390x 64-bit general purpose registers.
+ static const uint32_t g_gpr_regnums_s390x[] =
+ {
+ lldb_r0_s390x,
+ lldb_r1_s390x,
+ lldb_r2_s390x,
+ lldb_r3_s390x,
+ lldb_r4_s390x,
+ lldb_r5_s390x,
+ lldb_r6_s390x,
+ lldb_r7_s390x,
+ lldb_r8_s390x,
+ lldb_r9_s390x,
+ lldb_r10_s390x,
+ lldb_r11_s390x,
+ lldb_r12_s390x,
+ lldb_r13_s390x,
+ lldb_r14_s390x,
+ lldb_r15_s390x,
+ lldb_acr0_s390x,
+ lldb_acr1_s390x,
+ lldb_acr2_s390x,
+ lldb_acr3_s390x,
+ lldb_acr4_s390x,
+ lldb_acr5_s390x,
+ lldb_acr6_s390x,
+ lldb_acr7_s390x,
+ lldb_acr8_s390x,
+ lldb_acr9_s390x,
+ lldb_acr10_s390x,
+ lldb_acr11_s390x,
+ lldb_acr12_s390x,
+ lldb_acr13_s390x,
+ lldb_acr14_s390x,
+ lldb_acr15_s390x,
+ lldb_pswm_s390x,
+ lldb_pswa_s390x,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+ };
+ static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) - 1 == k_num_gpr_registers_s390x,
+ "g_gpr_regnums_s390x has wrong number of register infos");
+
+ // s390x 64-bit floating point registers.
+ static const uint32_t g_fpu_regnums_s390x[] =
+ {
+ lldb_f0_s390x,
+ lldb_f1_s390x,
+ lldb_f2_s390x,
+ lldb_f3_s390x,
+ lldb_f4_s390x,
+ lldb_f5_s390x,
+ lldb_f6_s390x,
+ lldb_f7_s390x,
+ lldb_f8_s390x,
+ lldb_f9_s390x,
+ lldb_f10_s390x,
+ lldb_f11_s390x,
+ lldb_f12_s390x,
+ lldb_f13_s390x,
+ lldb_f14_s390x,
+ lldb_f15_s390x,
+ lldb_fpc_s390x,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+ };
+ static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) - 1 == k_num_fpr_registers_s390x,
+ "g_fpu_regnums_s390x has wrong number of register infos");
+
+ // s390x Linux operating-system information.
+ static const uint32_t g_linux_regnums_s390x[] =
+ {
+ lldb_orig_r2_s390x,
+ lldb_last_break_s390x,
+ lldb_system_call_s390x,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+ };
+ static_assert((sizeof(g_linux_regnums_s390x) / sizeof(g_linux_regnums_s390x[0])) - 1 == k_num_linux_registers_s390x,
+ "g_linux_regnums_s390x has wrong number of register infos");
+
+ // Number of register sets provided by this context.
+ enum
+ {
+ k_num_register_sets = 3
+ };
+
+ // Register sets for s390x 64-bit.
+ static const RegisterSet g_reg_sets_s390x[k_num_register_sets] =
+ {
+ { "General Purpose Registers", "gpr", k_num_gpr_registers_s390x, g_gpr_regnums_s390x },
+ { "Floating Point Registers", "fpr", k_num_fpr_registers_s390x, g_fpu_regnums_s390x },
+ { "Linux Operating System Data", "linux", k_num_linux_registers_s390x, g_linux_regnums_s390x },
+ };
+}
+
+#define REG_CONTEXT_SIZE (sizeof(s390_regs) + sizeof(s390_fp_regs) + 4)
+
+// ----------------------------------------------------------------------------
+// Required ptrace defines.
+// ----------------------------------------------------------------------------
+
+#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
+#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
+
+NativeRegisterContextLinux *
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+{
+ return new NativeRegisterContextLinux_s390x(target_arch, native_thread, concrete_frame_idx);
+}
+
+// ----------------------------------------------------------------------------
+// NativeRegisterContextLinux_s390x members.
+// ----------------------------------------------------------------------------
+
+static RegisterInfoInterface *
+CreateRegisterInfoInterface(const ArchSpec &target_arch)
+{
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ return new RegisterContextLinux_s390x(target_arch);
+}
+
+NativeRegisterContextLinux_s390x::NativeRegisterContextLinux_s390x(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+ : NativeRegisterContextLinux(native_thread, concrete_frame_idx, CreateRegisterInfoInterface(target_arch))
+{
+ // Set up data about ranges of valid registers.
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::systemz:
+ m_reg_info.num_registers = k_num_registers_s390x;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
+ m_reg_info.last_gpr = k_last_gpr_s390x;
+ m_reg_info.first_fpr = k_first_fpr_s390x;
+ m_reg_info.last_fpr = k_last_fpr_s390x;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ // Clear out the watchpoint state.
+ m_watchpoint_addr = LLDB_INVALID_ADDRESS;
+}
+
+uint32_t
+NativeRegisterContextLinux_s390x::GetRegisterSetCount() const
+{
+ uint32_t sets = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
+ {
+ if (IsRegisterSetAvailable(set_index))
+ ++sets;
+ }
+
+ return sets;
+}
+
+uint32_t
+NativeRegisterContextLinux_s390x::GetUserRegisterCount() const
+{
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
+ {
+ const RegisterSet *set = GetRegisterSet(set_index);
+ if (set)
+ count += set->num_registers;
+ }
+ return count;
+}
+
+const RegisterSet *
+NativeRegisterContextLinux_s390x::GetRegisterSet(uint32_t set_index) const
+{
+ if (!IsRegisterSetAvailable(set_index))
+ return nullptr;
+
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine())
+ {
+ case llvm::Triple::systemz:
+ return &g_reg_sets_s390x[set_index];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
+
+ return nullptr;
+}
+
+bool
+NativeRegisterContextLinux_s390x::IsRegisterSetAvailable(uint32_t set_index) const
+{
+ return set_index < k_num_register_sets;
+}
+
+bool
+NativeRegisterContextLinux_s390x::IsGPR(uint32_t reg_index) const
+{
+ // GPRs come first. "orig_r2" counts as GPR since it is part of the GPR register area.
+ return reg_index <= m_reg_info.last_gpr || reg_index == lldb_orig_r2_s390x;
+}
+
+bool
+NativeRegisterContextLinux_s390x::IsFPR(uint32_t reg_index) const
+{
+ return (m_reg_info.first_fpr <= reg_index && reg_index <= m_reg_info.last_fpr);
+}
+
+Error
+NativeRegisterContextLinux_s390x::ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)
+{
+ if (!reg_info)
+ return Error("reg_info NULL");
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM)
+ return Error("register \"%s\" is an internal-only lldb register, cannot read directly", reg_info->name);
+
+ if (IsGPR(reg))
+ {
+ s390_regs regs;
+ Error error = DoReadGPR(&regs, sizeof(regs));
+ if (error.Fail())
+ return error;
+
+ uint8_t *src = (uint8_t *)&regs + reg_info->byte_offset;
+ assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
+ switch (reg_info->byte_size)
+ {
+ case 4:
+ reg_value.SetUInt32(*(uint32_t *)src);
+ break;
+ case 8:
+ reg_value.SetUInt64(*(uint64_t *)src);
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
+ }
+ return Error();
+ }
+
+ if (IsFPR(reg))
+ {
+ s390_fp_regs fp_regs;
+ Error error = DoReadFPR(&fp_regs, sizeof(fp_regs));
+ if (error.Fail())
+ return error;
+
+ // byte_offset is just the offset within FPR, not the whole user area.
+ uint8_t *src = (uint8_t *)&fp_regs + reg_info->byte_offset;
+ assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
+ switch (reg_info->byte_size)
+ {
+ case 4:
+ reg_value.SetUInt32(*(uint32_t *)src);
+ break;
+ case 8:
+ reg_value.SetUInt64(*(uint64_t *)src);
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
+ }
+ return Error();
+ }
+
+ if (reg == lldb_last_break_s390x)
+ {
+ uint64_t last_break;
+ Error error = DoReadRegisterSet(NT_S390_LAST_BREAK, &last_break, 8);
+ if (error.Fail())
+ return error;
+
+ reg_value.SetUInt64(last_break);
+ return Error();
+ }
+
+ if (reg == lldb_system_call_s390x)
+ {
+ uint32_t system_call;
+ Error error = DoReadRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
+ if (error.Fail())
+ return error;
+
+ reg_value.SetUInt32(system_call);
+ return Error();
+ }
+
+ return Error("failed - register wasn't recognized");
+}
+
+Error
+NativeRegisterContextLinux_s390x::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)
+{
+ if (!reg_info)
+ return Error("reg_info NULL");
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM)
+ return Error("register \"%s\" is an internal-only lldb register, cannot write directly", reg_info->name);
+
+ if (IsGPR(reg))
+ {
+ s390_regs regs;
+ Error error = DoReadGPR(&regs, sizeof(regs));
+ if (error.Fail())
+ return error;
+
+ uint8_t *dst = (uint8_t *)&regs + reg_info->byte_offset;
+ assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
+ switch (reg_info->byte_size)
+ {
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
+ }
+ return DoWriteGPR(&regs, sizeof(regs));
+ }
+
+ if (IsFPR(reg))
+ {
+ s390_fp_regs fp_regs;
+ Error error = DoReadFPR(&fp_regs, sizeof(fp_regs));
+ if (error.Fail())
+ return error;
+
+ // byte_offset is just the offset within fp_regs, not the whole user area.
+ uint8_t *dst = (uint8_t *)&fp_regs + reg_info->byte_offset;
+ assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
+ switch (reg_info->byte_size)
+ {
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
+ }
+ return DoWriteFPR(&fp_regs, sizeof(fp_regs));
+ }
+
+ if (reg == lldb_last_break_s390x)
+ {
+ return Error("The last break address is read-only");
+ }
+
+ if (reg == lldb_system_call_s390x)
+ {
+ uint32_t system_call = reg_value.GetAsUInt32();
+ return DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
+ }
+
+ return Error("failed - register wasn't recognized");
+}
+
+Error
+NativeRegisterContextLinux_s390x::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
+{
+ Error error;
+
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp)
+ {
+ error.SetErrorStringWithFormat("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
+ return error;
+ }
+
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr)
+ {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64 " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
+
+ error = DoReadGPR(dst, sizeof(s390_regs));
+ dst += sizeof(s390_regs);
+ if (error.Fail())
+ return error;
+
+ error = DoReadFPR(dst, sizeof(s390_fp_regs));
+ dst += sizeof(s390_fp_regs);
+ if (error.Fail())
+ return error;
+
+ // Ignore errors if the regset is unsupported (happens on older kernels).
+ DoReadRegisterSet(NT_S390_SYSTEM_CALL, dst, 4);
+ dst += 4;
+
+ // To enable inferior function calls while the process is stopped in
+ // an interrupted system call, we need to clear the system call flag.
+ // It will be restored to its original value by WriteAllRegisterValues.
+ // Again we ignore error if the regset is unsupported.
+ uint32_t system_call = 0;
+ DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
+
+ return error;
+}
+
+Error
+NativeRegisterContextLinux_s390x::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
+{
+ Error error;
+
+ if (!data_sp)
+ {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_s390x::%s invalid data_sp provided", __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE)
+ {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_s390x::%s data_sp contained mismatched data size, expected %" PRIu64
+ ", actual %" PRIu64,
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr)
+ {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_s390x::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
+ return error;
+ }
+
+ error = DoWriteGPR(src, sizeof(s390_regs));
+ src += sizeof(s390_regs);
+ if (error.Fail())
+ return error;
+
+ error = DoWriteFPR(src, sizeof(s390_fp_regs));
+ src += sizeof(s390_fp_regs);
+ if (error.Fail())
+ return error;
+
+ // Ignore errors if the regset is unsupported (happens on older kernels).
+ DoWriteRegisterSet(NT_S390_SYSTEM_CALL, src, 4);
+ src += 4;
+
+ return error;
+}
+
+Error
+NativeRegisterContextLinux_s390x::DoReadRegisterValue(uint32_t offset, const char *reg_name, uint32_t size,
+ RegisterValue &value)
+{
+ return Error("DoReadRegisterValue unsupported");
+}
+
+Error
+NativeRegisterContextLinux_s390x::DoWriteRegisterValue(uint32_t offset, const char *reg_name,
+ const RegisterValue &value)
+{
+ return Error("DoWriteRegisterValue unsupported");
+}
+
+Error
+NativeRegisterContextLinux_s390x::PeekUserArea(uint32_t offset, void *buf, size_t buf_size)
+{
+ ptrace_area parea;
+ parea.len = buf_size;
+ parea.process_addr = (addr_t)buf;
+ parea.kernel_addr = offset;
+
+ return NativeProcessLinux::PtraceWrapper(PTRACE_PEEKUSR_AREA, m_thread.GetID(), &parea);
+}
+
+Error
+NativeRegisterContextLinux_s390x::PokeUserArea(uint32_t offset, const void *buf, size_t buf_size)
+{
+ ptrace_area parea;
+ parea.len = buf_size;
+ parea.process_addr = (addr_t)buf;
+ parea.kernel_addr = offset;
+
+ return NativeProcessLinux::PtraceWrapper(PTRACE_POKEUSR_AREA, m_thread.GetID(), &parea);
+}
+
+Error
+NativeRegisterContextLinux_s390x::DoReadGPR(void *buf, size_t buf_size)
+{
+ assert(buf_size == sizeof(s390_regs));
+ return PeekUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
+}
+
+Error
+NativeRegisterContextLinux_s390x::DoWriteGPR(void *buf, size_t buf_size)
+{
+ assert(buf_size == sizeof(s390_regs));
+ return PokeUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
+}
+
+Error
+NativeRegisterContextLinux_s390x::DoReadFPR(void *buf, size_t buf_size)
+{
+ assert(buf_size == sizeof(s390_fp_regs));
+ return PeekUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
+}
+
+Error
+NativeRegisterContextLinux_s390x::DoWriteFPR(void *buf, size_t buf_size)
+{
+ assert(buf_size == sizeof(s390_fp_regs));
+ return PokeUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
+}
+
+Error
+NativeRegisterContextLinux_s390x::DoReadRegisterSet(uint32_t regset, void *buf, size_t buf_size)
+{
+ struct iovec iov;
+ iov.iov_base = buf;
+ iov.iov_len = buf_size;
+
+ return ReadRegisterSet(&iov, buf_size, regset);
+}
+
+Error
+NativeRegisterContextLinux_s390x::DoWriteRegisterSet(uint32_t regset, const void *buf, size_t buf_size)
+{
+ struct iovec iov;
+ iov.iov_base = const_cast<void *>(buf);
+ iov.iov_len = buf_size;
+
+ return WriteRegisterSet(&iov, buf_size, regset);
+}
+
+Error
+NativeRegisterContextLinux_s390x::IsWatchpointHit(uint32_t wp_index, bool &is_hit)
+{
+ per_lowcore_bits per_lowcore;
+
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
+
+ if (m_watchpoint_addr == LLDB_INVALID_ADDRESS)
+ {
+ is_hit = false;
+ return Error();
+ }
+
+ Error error = PeekUserArea(offsetof(user_regs_struct, per_info.lowcore), &per_lowcore, sizeof(per_lowcore));
+ if (error.Fail())
+ {
+ is_hit = false;
+ return error;
+ }
+
+ is_hit = (per_lowcore.perc_storage_alteration == 1 && per_lowcore.perc_store_real_address == 0);
+
+ if (is_hit)
+ {
+ // Do not report this watchpoint again.
+ memset(&per_lowcore, 0, sizeof(per_lowcore));
+ PokeUserArea(offsetof(user_regs_struct, per_info.lowcore), &per_lowcore, sizeof(per_lowcore));
+ }
+
+ return Error();
+}
+
+Error
+NativeRegisterContextLinux_s390x::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
+{
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ for (wp_index = 0; wp_index < num_hw_wps; ++wp_index)
+ {
+ bool is_hit;
+ Error error = IsWatchpointHit(wp_index, is_hit);
+ if (error.Fail())
+ {
+ wp_index = LLDB_INVALID_INDEX32;
+ return error;
+ }
+ else if (is_hit)
+ {
+ return error;
+ }
+ }
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
+}
+
+Error
+NativeRegisterContextLinux_s390x::IsWatchpointVacant(uint32_t wp_index, bool &is_vacant)
+{
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
+
+ is_vacant = m_watchpoint_addr == LLDB_INVALID_ADDRESS;
+
+ return Error();
+}
+
+bool
+NativeRegisterContextLinux_s390x::ClearHardwareWatchpoint(uint32_t wp_index)
+{
+ per_struct per_info;
+
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return false;
+
+ Error error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info, sizeof(per_info));
+ if (error.Fail())
+ return false;
+
+ per_info.control_regs.bits.em_storage_alteration = 0;
+ per_info.control_regs.bits.storage_alt_space_ctl = 0;
+ per_info.starting_addr = 0;
+ per_info.ending_addr = 0;
+
+ error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info, sizeof(per_info));
+ if (error.Fail())
+ return false;
+
+ m_watchpoint_addr = LLDB_INVALID_ADDRESS;
+ return true;
+}
+
+Error
+NativeRegisterContextLinux_s390x::ClearAllHardwareWatchpoints()
+{
+ if (ClearHardwareWatchpoint(0))
+ return Error();
+ return Error("Clearing all hardware watchpoints failed.");
+}
+
+uint32_t
+NativeRegisterContextLinux_s390x::SetHardwareWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags)
+{
+ per_struct per_info;
+
+ if (watch_flags != 0x1)
+ return LLDB_INVALID_INDEX32;
+
+ if (m_watchpoint_addr != LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_INDEX32;
+
+ Error error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info, sizeof(per_info));
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
+
+ per_info.control_regs.bits.em_storage_alteration = 1;
+ per_info.control_regs.bits.storage_alt_space_ctl = 1;
+ per_info.starting_addr = addr;
+ per_info.ending_addr = addr + size - 1;
+
+ error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info, sizeof(per_info));
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
+
+ m_watchpoint_addr = addr;
+ return 0;
+}
+
+lldb::addr_t
+NativeRegisterContextLinux_s390x::GetWatchpointAddress(uint32_t wp_index)
+{
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
+ return m_watchpoint_addr;
+}
+
+uint32_t
+NativeRegisterContextLinux_s390x::NumSupportedHardwareWatchpoints()
+{
+ return 1;
+}
+
+#endif // defined(__s390x__) && defined(__linux__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
new file mode 100644
index 000000000000..8cd4ab7f1242
--- /dev/null
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
@@ -0,0 +1,141 @@
+//===-- NativeRegisterContextLinux_s390x.h ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__s390x__) && defined(__linux__)
+
+#ifndef lldb_NativeRegisterContextLinux_s390x_h
+#define lldb_NativeRegisterContextLinux_s390x_h
+
+#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
+#include "Plugins/Process/Utility/RegisterContext_s390x.h"
+#include "Plugins/Process/Utility/lldb-s390x-register-enums.h"
+
+namespace lldb_private
+{
+namespace process_linux
+{
+
+class NativeProcessLinux;
+
+class NativeRegisterContextLinux_s390x : public NativeRegisterContextLinux
+{
+public:
+ NativeRegisterContextLinux_s390x(const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
+
+ uint32_t
+ GetRegisterSetCount() const override;
+
+ const RegisterSet *
+ GetRegisterSet(uint32_t set_index) const override;
+
+ uint32_t
+ GetUserRegisterCount() const override;
+
+ Error
+ ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+
+ Error
+ WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+
+ Error
+ ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ Error
+ WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ Error
+ IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
+
+ Error
+ GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
+
+ Error
+ IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
+
+ bool
+ ClearHardwareWatchpoint(uint32_t wp_index) override;
+
+ Error
+ ClearAllHardwareWatchpoints() override;
+
+ uint32_t
+ SetHardwareWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags) override;
+
+ lldb::addr_t
+ GetWatchpointAddress(uint32_t wp_index) override;
+
+ uint32_t
+ NumSupportedHardwareWatchpoints() override;
+
+protected:
+ Error
+ DoReadRegisterValue(uint32_t offset, const char *reg_name, uint32_t size, RegisterValue &value) override;
+
+ Error
+ DoWriteRegisterValue(uint32_t offset, const char *reg_name, const RegisterValue &value) override;
+
+ Error
+ DoReadGPR(void *buf, size_t buf_size) override;
+
+ Error
+ DoWriteGPR(void *buf, size_t buf_size) override;
+
+ Error
+ DoReadFPR(void *buf, size_t buf_size) override;
+
+ Error
+ DoWriteFPR(void *buf, size_t buf_size) override;
+
+private:
+ // Info about register ranges.
+ struct RegInfo
+ {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+ };
+
+ // Private member variables.
+ RegInfo m_reg_info;
+ lldb::addr_t m_watchpoint_addr;
+
+ // Private member methods.
+ bool
+ IsRegisterSetAvailable(uint32_t set_index) const;
+
+ bool
+ IsGPR(uint32_t reg_index) const;
+
+ bool
+ IsFPR(uint32_t reg_index) const;
+
+ Error
+ PeekUserArea(uint32_t offset, void *buf, size_t buf_size);
+
+ Error
+ PokeUserArea(uint32_t offset, const void *buf, size_t buf_size);
+
+ Error
+ DoReadRegisterSet(uint32_t regset, void *buf, size_t buf_size);
+
+ Error
+ DoWriteRegisterSet(uint32_t regset, const void *buf, size_t buf_size);
+};
+
+} // namespace process_linux
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextLinux_s390x_h
+
+#endif // defined(__s390x__) && defined(__linux__)
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index cbf82885e23a..070b1bcda3b8 100644
--- a/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -14,10 +14,12 @@
#include "NativeProcessLinux.h"
#include "NativeRegisterContextLinux.h"
+#include "SingleStepCheck.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/State.h"
#include "lldb/Host/HostNativeThread.h"
+#include "lldb/Host/linux/Ptrace.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/lldb-enumerations.h"
@@ -199,8 +201,8 @@ NativeThreadLinux::RemoveWatchpoint (lldb::addr_t addr)
return Error ("Clearing hardware watchpoint failed.");
}
-void
-NativeThreadLinux::SetRunning ()
+Error
+NativeThreadLinux::Resume(uint32_t signo)
{
const StateType new_state = StateType::eStateRunning;
MaybeLogStateChange (new_state);
@@ -213,29 +215,92 @@ NativeThreadLinux::SetRunning ()
// then this is a new thread. So set all existing watchpoints.
if (m_watchpoint_index_map.empty())
{
- const auto process_sp = GetProcess();
- if (process_sp)
+ NativeProcessLinux &process = GetProcess();
+
+ const auto &watchpoint_map = process.GetWatchpointMap();
+ GetRegisterContext()->ClearAllHardwareWatchpoints();
+ for (const auto &pair : watchpoint_map)
{
- const auto &watchpoint_map = process_sp->GetWatchpointMap();
- if (watchpoint_map.empty()) return;
- GetRegisterContext()->ClearAllHardwareWatchpoints();
- for (const auto &pair : watchpoint_map)
- {
- const auto& wp = pair.second;
- SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
- }
+ const auto &wp = pair.second;
+ SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
}
}
+
+ intptr_t data = 0;
+
+ if (signo != LLDB_INVALID_SIGNAL_NUMBER)
+ data = signo;
+
+ return NativeProcessLinux::PtraceWrapper(PTRACE_CONT, GetID(), nullptr, reinterpret_cast<void *>(data));
}
void
-NativeThreadLinux::SetStepping ()
+NativeThreadLinux::MaybePrepareSingleStepWorkaround()
+{
+ if (!SingleStepWorkaroundNeeded())
+ return;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ if (sched_getaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set, &m_original_cpu_set) != 0)
+ {
+ // This should really not fail. But, just in case...
+ if (log)
+ {
+ Error error(errno, eErrorTypePOSIX);
+ log->Printf("NativeThreadLinux::%s Unable to get cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__,
+ m_tid, error.AsCString());
+ }
+ return;
+ }
+
+ cpu_set_t set;
+ CPU_ZERO(&set);
+ CPU_SET(0, &set);
+ if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof set, &set) != 0 && log)
+ {
+ // This may fail in very locked down systems, if the thread is not allowed to run on
+ // cpu 0. If that happens, only thing we can do is it log it and continue...
+ Error error(errno, eErrorTypePOSIX);
+ log->Printf("NativeThreadLinux::%s Unable to set cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__, m_tid,
+ error.AsCString());
+ }
+}
+
+void
+NativeThreadLinux::MaybeCleanupSingleStepWorkaround()
+{
+ if (!SingleStepWorkaroundNeeded())
+ return;
+
+ if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set, &m_original_cpu_set) != 0)
+ {
+ Error error(errno, eErrorTypePOSIX);
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ log->Printf("NativeThreadLinux::%s Unable to reset cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__,
+ m_tid, error.AsCString());
+ }
+}
+
+Error
+NativeThreadLinux::SingleStep(uint32_t signo)
{
const StateType new_state = StateType::eStateStepping;
MaybeLogStateChange (new_state);
m_state = new_state;
-
m_stop_info.reason = StopReason::eStopReasonNone;
+
+ MaybePrepareSingleStepWorkaround();
+
+ intptr_t data = 0;
+ if (signo != LLDB_INVALID_SIGNAL_NUMBER)
+ data = signo;
+
+ // If hardware single-stepping is not supported, we just do a continue. The breakpoint on the
+ // next instruction has been setup in NativeProcessLinux::Resume.
+ return NativeProcessLinux::PtraceWrapper(GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
+ : PTRACE_CONT,
+ m_tid, nullptr, reinterpret_cast<void *>(data));
}
void
@@ -245,9 +310,7 @@ NativeThreadLinux::SetStoppedBySignal(uint32_t signo, const siginfo_t *info)
if (log)
log->Printf ("NativeThreadLinux::%s called with signal 0x%02" PRIx32, __FUNCTION__, signo);
- const StateType new_state = StateType::eStateStopped;
- MaybeLogStateChange (new_state);
- m_state = new_state;
+ SetStopped();
m_stop_info.reason = StopReason::eStopReasonSignal;
m_stop_info.details.signal.signo = signo;
@@ -288,6 +351,17 @@ NativeThreadLinux::IsStopped (int *signo)
return true;
}
+void
+NativeThreadLinux::SetStopped()
+{
+ if (m_state == StateType::eStateStepping)
+ MaybeCleanupSingleStepWorkaround();
+
+ const StateType new_state = StateType::eStateStopped;
+ MaybeLogStateChange(new_state);
+ m_state = new_state;
+ m_stop_description.clear();
+}
void
NativeThreadLinux::SetStoppedByExec ()
@@ -296,9 +370,7 @@ NativeThreadLinux::SetStoppedByExec ()
if (log)
log->Printf ("NativeThreadLinux::%s()", __FUNCTION__);
- const StateType new_state = StateType::eStateStopped;
- MaybeLogStateChange (new_state);
- m_state = new_state;
+ SetStopped();
m_stop_info.reason = StopReason::eStopReasonExec;
m_stop_info.details.signal.signo = SIGSTOP;
@@ -307,9 +379,7 @@ NativeThreadLinux::SetStoppedByExec ()
void
NativeThreadLinux::SetStoppedByBreakpoint ()
{
- const StateType new_state = StateType::eStateStopped;
- MaybeLogStateChange (new_state);
- m_state = new_state;
+ SetStopped();
m_stop_info.reason = StopReason::eStopReasonBreakpoint;
m_stop_info.details.signal.signo = SIGTRAP;
@@ -319,10 +389,7 @@ NativeThreadLinux::SetStoppedByBreakpoint ()
void
NativeThreadLinux::SetStoppedByWatchpoint (uint32_t wp_index)
{
- const StateType new_state = StateType::eStateStopped;
- MaybeLogStateChange (new_state);
- m_state = new_state;
- m_stop_description.clear ();
+ SetStopped();
lldbassert(wp_index != LLDB_INVALID_INDEX32 &&
"wp_index cannot be invalid");
@@ -363,9 +430,7 @@ NativeThreadLinux::IsStoppedAtWatchpoint ()
void
NativeThreadLinux::SetStoppedByTrace ()
{
- const StateType new_state = StateType::eStateStopped;
- MaybeLogStateChange (new_state);
- m_state = new_state;
+ SetStopped();
m_stop_info.reason = StopReason::eStopReasonTrace;
m_stop_info.details.signal.signo = SIGTRAP;
@@ -374,9 +439,7 @@ NativeThreadLinux::SetStoppedByTrace ()
void
NativeThreadLinux::SetStoppedWithNoReason ()
{
- const StateType new_state = StateType::eStateStopped;
- MaybeLogStateChange (new_state);
- m_state = new_state;
+ SetStopped();
m_stop_info.reason = StopReason::eStopReasonNone;
m_stop_info.details.signal.signo = 0;
@@ -397,11 +460,9 @@ NativeThreadLinux::RequestStop ()
{
Log* log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
- const auto process_sp = GetProcess();
- if (! process_sp)
- return Error("Process is null.");
+ NativeProcessLinux &process = GetProcess();
- lldb::pid_t pid = process_sp->GetID();
+ lldb::pid_t pid = process.GetID();
lldb::tid_t tid = GetID();
if (log)
@@ -438,3 +499,11 @@ NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state)
// Log it.
log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state));
}
+
+NativeProcessLinux &
+NativeThreadLinux::GetProcess()
+{
+ auto process_sp = std::static_pointer_cast<NativeProcessLinux>(NativeThreadProtocol::GetProcess());
+ assert(process_sp);
+ return *process_sp;
+}
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.h b/source/Plugins/Process/Linux/NativeThreadLinux.h
index bf6b00a78cfd..f1b6a6e44782 100644
--- a/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ b/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -13,6 +13,8 @@
#include "lldb/lldb-private-forward.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
+#include <sched.h>
+
#include <map>
#include <memory>
#include <string>
@@ -54,11 +56,16 @@ namespace process_linux {
// ---------------------------------------------------------------------
// Interface for friend classes
// ---------------------------------------------------------------------
- void
- SetRunning ();
- void
- SetStepping ();
+ /// Resumes the thread. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
+ Error
+ Resume(uint32_t signo);
+
+ /// Single steps the thread. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
+ Error
+ SingleStep(uint32_t signo);
void
SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
@@ -102,6 +109,18 @@ namespace process_linux {
void
MaybeLogStateChange (lldb::StateType new_state);
+ NativeProcessLinux &
+ GetProcess();
+
+ void
+ SetStopped();
+
+ inline void
+ MaybePrepareSingleStepWorkaround();
+
+ inline void
+ MaybeCleanupSingleStepWorkaround();
+
// ---------------------------------------------------------------------
// Member Variables
// ---------------------------------------------------------------------
@@ -111,6 +130,7 @@ namespace process_linux {
std::string m_stop_description;
using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
WatchpointIndexMap m_watchpoint_index_map;
+ cpu_set_t m_original_cpu_set; // For single-step workaround.
};
typedef std::shared_ptr<NativeThreadLinux> NativeThreadLinuxSP;
diff --git a/source/Plugins/Process/Linux/SingleStepCheck.cpp b/source/Plugins/Process/Linux/SingleStepCheck.cpp
new file mode 100644
index 000000000000..8c557d4b6ff8
--- /dev/null
+++ b/source/Plugins/Process/Linux/SingleStepCheck.cpp
@@ -0,0 +1,177 @@
+//===-- SingleStepCheck.cpp ----------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SingleStepCheck.h"
+
+#include <sched.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "NativeProcessLinux.h"
+
+#include "llvm/Support/Compiler.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Host/linux/Ptrace.h"
+
+using namespace lldb_private::process_linux;
+
+#if defined(__arm64__) || defined(__aarch64__)
+namespace
+{
+
+void LLVM_ATTRIBUTE_NORETURN
+Child()
+{
+ if (ptrace(PTRACE_TRACEME, 0, nullptr, nullptr) == -1)
+ _exit(1);
+
+ // We just do an endless loop SIGSTOPPING ourselves until killed. The tracer will fiddle with our cpu
+ // affinities and monitor the behaviour.
+ for (;;)
+ {
+ raise(SIGSTOP);
+
+ // Generate a bunch of instructions here, so that a single-step does not land in the
+ // raise() accidentally. If single-stepping works, we will be spinning in this loop. If
+ // it doesn't, we'll land in the raise() call above.
+ for (volatile unsigned i = 0; i < CPU_SETSIZE; ++i)
+ ;
+ }
+}
+
+struct ChildDeleter
+{
+ ::pid_t pid;
+
+ ~ChildDeleter()
+ {
+ int status;
+ kill(pid, SIGKILL); // Kill the child.
+ waitpid(pid, &status, __WALL); // Pick up the remains.
+ }
+};
+
+} // end anonymous namespace
+
+bool
+impl::SingleStepWorkaroundNeeded()
+{
+ // We shall spawn a child, and use it to verify the debug capabilities of the cpu. We shall
+ // iterate through the cpus, bind the child to each one in turn, and verify that
+ // single-stepping works on that cpu. A workaround is needed if we find at least one broken
+ // cpu.
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ Error error;
+ ::pid_t child_pid = fork();
+ if (child_pid == -1)
+ {
+ if (log)
+ {
+ error.SetErrorToErrno();
+ log->Printf("%s failed to fork(): %s", __FUNCTION__, error.AsCString());
+ }
+ return false;
+ }
+ if (child_pid == 0)
+ Child();
+
+ ChildDeleter child_deleter{child_pid};
+ cpu_set_t available_cpus;
+ if (sched_getaffinity(child_pid, sizeof available_cpus, &available_cpus) == -1)
+ {
+ if (log)
+ {
+ error.SetErrorToErrno();
+ log->Printf("%s failed to get available cpus: %s", __FUNCTION__, error.AsCString());
+ }
+ return false;
+ }
+
+ int status;
+ ::pid_t wpid = waitpid(child_pid, &status, __WALL);
+ if (wpid != child_pid || !WIFSTOPPED(status))
+ {
+ if (log)
+ {
+ error.SetErrorToErrno();
+ log->Printf("%s waitpid() failed (status = %x): %s", __FUNCTION__, status, error.AsCString());
+ }
+ return false;
+ }
+
+ unsigned cpu;
+ for (cpu = 0; cpu < CPU_SETSIZE; ++cpu)
+ {
+ if (!CPU_ISSET(cpu, &available_cpus))
+ continue;
+
+ cpu_set_t cpus;
+ CPU_ZERO(&cpus);
+ CPU_SET(cpu, &cpus);
+ if (sched_setaffinity(child_pid, sizeof cpus, &cpus) == -1)
+ {
+ if (log)
+ {
+ error.SetErrorToErrno();
+ log->Printf("%s failed to switch to cpu %u: %s", __FUNCTION__, cpu, error.AsCString());
+ }
+ continue;
+ }
+
+ int status;
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, child_pid);
+ if (error.Fail())
+ {
+ if (log)
+ log->Printf("%s single step failed: %s", __FUNCTION__, error.AsCString());
+ break;
+ }
+
+ wpid = waitpid(child_pid, &status, __WALL);
+ if (wpid != child_pid || !WIFSTOPPED(status))
+ {
+ if (log)
+ {
+ error.SetErrorToErrno();
+ log->Printf("%s waitpid() failed (status = %x): %s", __FUNCTION__, status, error.AsCString());
+ }
+ break;
+ }
+ if (WSTOPSIG(status) != SIGTRAP)
+ {
+ if (log)
+ log->Printf("%s single stepping on cpu %d failed with status %x", __FUNCTION__, cpu, status);
+ break;
+ }
+ }
+
+ // cpu is either the index of the first broken cpu, or CPU_SETSIZE.
+ if (cpu == 0)
+ {
+ if (log)
+ log->Printf("%s SINGLE STEPPING ON FIRST CPU IS NOT WORKING. DEBUGGING LIKELY TO BE UNRELIABLE.",
+ __FUNCTION__);
+ // No point in trying to fiddle with the affinities, just give it our best shot and see how it goes.
+ return false;
+ }
+
+ return cpu != CPU_SETSIZE;
+}
+
+#else // !arm64
+bool
+impl::SingleStepWorkaroundNeeded()
+{
+ return false;
+}
+#endif
diff --git a/source/Plugins/Process/Linux/SingleStepCheck.h b/source/Plugins/Process/Linux/SingleStepCheck.h
new file mode 100644
index 000000000000..f83f7c973f8d
--- /dev/null
+++ b/source/Plugins/Process/Linux/SingleStepCheck.h
@@ -0,0 +1,41 @@
+//===-- SingleStepCheck.h ------------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SingleStepCheck_H_
+#define liblldb_SingleStepCheck_H_
+
+namespace lldb_private
+{
+namespace process_linux
+{
+
+namespace impl
+{
+extern bool
+SingleStepWorkaroundNeeded();
+}
+
+// arm64 linux had a bug which prevented single-stepping and watchpoints from working on non-boot
+// cpus, due to them being incorrectly initialized after coming out of suspend. This issue is
+// particularly affecting android M, which uses suspend ("doze mode") quite aggressively. This
+// code detects that situation and makes single-stepping work by doing all the step operations on
+// the boot cpu.
+//
+// The underlying issue has been fixed in android N and linux 4.4. This code can be removed once
+// these systems become obsolete.
+inline bool
+SingleStepWorkaroundNeeded()
+{
+ static bool value = impl::SingleStepWorkaroundNeeded();
+ return value;
+}
+} // end namespace process_linux
+} // end namespace lldb_private
+
+#endif // #ifndef liblldb_SingleStepCheck_H_
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
index 5c1c3284a35c..29a0d58f7080 100644
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
@@ -37,21 +37,21 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// CommunicationKDP constructor
//----------------------------------------------------------------------
-CommunicationKDP::CommunicationKDP (const char *comm_name) :
- Communication(comm_name),
- m_addr_byte_size (4),
- m_byte_order (eByteOrderLittle),
- m_packet_timeout (5),
- m_sequence_mutex (Mutex::eMutexTypeRecursive),
- m_is_running (false),
- m_session_key (0u),
- m_request_sequence_id (0u),
- m_exception_sequence_id (0u),
- m_kdp_version_version (0u),
- m_kdp_version_feature (0u),
- m_kdp_hostinfo_cpu_mask (0u),
- m_kdp_hostinfo_cpu_type (0u),
- m_kdp_hostinfo_cpu_subtype (0u)
+CommunicationKDP::CommunicationKDP(const char *comm_name)
+ : Communication(comm_name),
+ m_addr_byte_size(4),
+ m_byte_order(eByteOrderLittle),
+ m_packet_timeout(5),
+ m_sequence_mutex(),
+ m_is_running(false),
+ m_session_key(0u),
+ m_request_sequence_id(0u),
+ m_exception_sequence_id(0u),
+ m_kdp_version_version(0u),
+ m_kdp_version_feature(0u),
+ m_kdp_hostinfo_cpu_mask(0u),
+ m_kdp_hostinfo_cpu_type(0u),
+ m_kdp_hostinfo_cpu_subtype(0u)
{
}
@@ -69,7 +69,7 @@ CommunicationKDP::~CommunicationKDP()
bool
CommunicationKDP::SendRequestPacket (const PacketStreamType &request_packet)
{
- Mutex::Locker locker(m_sequence_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
return SendRequestPacketNoLock (request_packet);
}
@@ -111,7 +111,7 @@ CommunicationKDP::SendRequestAndGetReply (const CommandType command,
return false;
}
- Mutex::Locker locker(m_sequence_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
#ifdef LLDB_CONFIGURATION_DEBUG
// NOTE: this only works for packets that are in native endian byte order
assert (request_packet.GetSize() == *((uint16_t *)(request_packet.GetData() + 2)));
@@ -205,9 +205,9 @@ CommunicationKDP::SendRequestPacketNoLock (const PacketStreamType &request_packe
}
bool
-CommunicationKDP::GetSequenceMutex (Mutex::Locker& locker)
+CommunicationKDP::GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock)
{
- return locker.TryLock (m_sequence_mutex);
+ return (lock = std::unique_lock<std::recursive_mutex>(m_sequence_mutex, std::try_to_lock)).owns_lock();
}
@@ -220,7 +220,7 @@ CommunicationKDP::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
size_t
CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds (DataExtractor &packet, uint32_t timeout_usec)
{
- Mutex::Locker locker(m_sequence_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
return WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec);
}
@@ -284,8 +284,8 @@ bool
CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtractor &packet)
{
// Put the packet data into the buffer in a thread safe fashion
- Mutex::Locker locker(m_bytes_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
+
Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
if (src && src_len > 0)
@@ -326,6 +326,7 @@ CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtrac
SendRequestPacketNoLock (request_ack_packet);
}
// Fall through to case below to get packet contents
+ LLVM_FALLTHROUGH;
case ePacketTypeReply | KDP_CONNECT:
case ePacketTypeReply | KDP_DISCONNECT:
case ePacketTypeReply | KDP_HOSTINFO:
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
index 98a146d5a06d..89e55a561e74 100644
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <list>
+#include <mutex>
#include <string>
// Other libraries and framework includes
@@ -21,7 +22,6 @@
#include "lldb/Core/Communication.h"
#include "lldb/Core/Listener.h"
#include "lldb/Core/StreamBuffer.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/Predicate.h"
#include "lldb/Host/TimeValue.h"
@@ -109,7 +109,7 @@ public:
uint32_t usec);
bool
- GetSequenceMutex(lldb_private::Mutex::Locker& locker);
+ GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock);
bool
CheckForPacket (const uint8_t *src,
@@ -324,7 +324,7 @@ protected:
uint32_t m_addr_byte_size;
lldb::ByteOrder m_byte_order;
uint32_t m_packet_timeout;
- lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
+ std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
lldb_private::Predicate<bool> m_is_running;
uint32_t m_session_key;
uint8_t m_request_sequence_id;
diff --git a/source/Plugins/Process/MacOSX-Kernel/Makefile b/source/Plugins/Process/MacOSX-Kernel/Makefile
deleted file mode 100644
index e42f390ffe0d..000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Process/MacOSX-Darwin/Makefile -------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginProcessDarwin
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index 628f76d104fe..898677df616b 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -132,12 +132,12 @@ ProcessKDP::Terminate()
lldb::ProcessSP
ProcessKDP::CreateInstance (TargetSP target_sp,
- Listener &listener,
+ ListenerSP listener_sp,
const FileSpec *crash_file_path)
{
lldb::ProcessSP process_sp;
if (crash_file_path == NULL)
- process_sp.reset(new ProcessKDP (target_sp, listener));
+ process_sp.reset(new ProcessKDP (target_sp, listener_sp));
return process_sp;
}
@@ -178,8 +178,8 @@ ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name)
//----------------------------------------------------------------------
// ProcessKDP constructor
//----------------------------------------------------------------------
-ProcessKDP::ProcessKDP(TargetSP target_sp, Listener &listener) :
- Process (target_sp, listener),
+ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp) :
+ Process (target_sp, listener_sp),
m_comm("lldb.process.kdp-remote.communication"),
m_async_broadcaster (NULL, "lldb.process.kdp-remote.async-broadcaster"),
m_dyld_plugin_name (),
@@ -927,13 +927,13 @@ ProcessKDP::AsyncThread (void *arg)
if (log)
log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread starting...", arg, pid);
- Listener listener ("ProcessKDP::AsyncThread");
+ ListenerSP listener_sp (Listener::MakeListener("ProcessKDP::AsyncThread"));
EventSP event_sp;
const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
eBroadcastBitAsyncThreadShouldExit;
- if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
+ if (listener_sp->StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
{
bool done = false;
while (!done)
@@ -941,7 +941,7 @@ ProcessKDP::AsyncThread (void *arg)
if (log)
log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...",
pid);
- if (listener.WaitForEvent (NULL, event_sp))
+ if (listener_sp->WaitForEvent (NULL, event_sp))
{
uint32_t event_type = event_sp->GetType();
if (log)
@@ -981,7 +981,7 @@ ProcessKDP::AsyncThread (void *arg)
// Check to see if we are supposed to exit. There is no way to
// interrupt a running kernel, so all we can do is wait for an
// exception or detach...
- if (listener.GetNextEvent(event_sp))
+ if (listener_sp->GetNextEvent(event_sp))
{
// We got an event, go through the loop again
event_type = event_sp->GetType();
@@ -1187,11 +1187,9 @@ public:
class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword
{
public:
- CommandObjectMultiwordProcessKDP (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "process plugin",
- "A set of commands for operating on a ProcessKDP process.",
- "process plugin <subcommand> [<subcommand-options>]")
+ CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "process plugin", "Commands for operating on a ProcessKDP process.",
+ "process plugin <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessKDPPacket (interpreter)));
}
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
index fe9a4e2844bf..49f636242510 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
@@ -40,7 +40,7 @@ public:
//------------------------------------------------------------------
static lldb::ProcessSP
CreateInstance (lldb::TargetSP target_sp,
- lldb_private::Listener &listener,
+ lldb::ListenerSP listener_sp,
const lldb_private::FileSpec *crash_file_path);
static void
@@ -61,7 +61,7 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- ProcessKDP(lldb::TargetSP target_sp, lldb_private::Listener &listener);
+ ProcessKDP(lldb::TargetSP target_sp, lldb::ListenerSP listener);
virtual
~ProcessKDP();
diff --git a/source/Plugins/Process/POSIX/Makefile b/source/Plugins/Process/POSIX/Makefile
deleted file mode 100644
index e8ac3a8ae0ed..000000000000
--- a/source/Plugins/Process/POSIX/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-##===- source/Plugins/Process/POSIX/Makefile ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginProcessPOSIX
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/../../Makefile.config
-
-# Extend the include path so we may locate UnwindLLDB.h
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Utility
-
-ifeq ($(HOST_OS),Linux)
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/Linux
-
-# Disable warning for now as offsetof is used with an index into a structure member array
-# in defining register info tables.
-CPP.Flags += -Wno-extended-offsetof
-endif
-
-ifneq (,$(filter $(HOST_OS), FreeBSD GNU/kFreeBSD))
-# Extend the include path so we may locate ProcessMonitor
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/FreeBSD
-endif
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Process/Utility/CMakeLists.txt b/source/Plugins/Process/Utility/CMakeLists.txt
index 4a847b4f966a..eb0c81fd7979 100644
--- a/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/source/Plugins/Process/Utility/CMakeLists.txt
@@ -28,16 +28,19 @@ add_lldb_library(lldbPluginProcessUtility
RegisterContextLinux_x86_64.cpp
RegisterContextLinux_mips64.cpp
RegisterContextLinux_mips.cpp
+ RegisterContextLinux_s390x.cpp
RegisterContextLLDB.cpp
RegisterContextMacOSXFrameBackchain.cpp
RegisterContextMach_arm.cpp
RegisterContextMach_i386.cpp
RegisterContextMach_x86_64.cpp
RegisterContextMemory.cpp
+ RegisterContextNetBSD_x86_64.cpp
RegisterContextPOSIX_arm.cpp
RegisterContextPOSIX_arm64.cpp
RegisterContextPOSIX_mips64.cpp
RegisterContextPOSIX_powerpc.cpp
+ RegisterContextPOSIX_s390x.cpp
RegisterContextPOSIX_x86.cpp
RegisterContextThreadMemory.cpp
StopInfoMachException.cpp
diff --git a/source/Plugins/Process/Utility/HistoryThread.cpp b/source/Plugins/Process/Utility/HistoryThread.cpp
index 206b8290c5fd..956539da219c 100644
--- a/source/Plugins/Process/Utility/HistoryThread.cpp
+++ b/source/Plugins/Process/Utility/HistoryThread.cpp
@@ -22,28 +22,24 @@ using namespace lldb_private;
// Constructor
-HistoryThread::HistoryThread (lldb_private::Process &process,
- lldb::tid_t tid,
- std::vector<lldb::addr_t> pcs,
- uint32_t stop_id,
- bool stop_id_is_valid) :
- Thread (process, tid, true),
- m_framelist_mutex(),
- m_framelist(),
- m_pcs (pcs),
- m_stop_id (stop_id),
- m_stop_id_is_valid (stop_id_is_valid),
- m_extended_unwind_token (LLDB_INVALID_ADDRESS),
- m_queue_name (),
- m_thread_name (),
- m_originating_unique_thread_id (tid),
- m_queue_id (LLDB_INVALID_QUEUE_ID)
+HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid, std::vector<lldb::addr_t> pcs,
+ uint32_t stop_id, bool stop_id_is_valid)
+ : Thread(process, tid, true),
+ m_framelist_mutex(),
+ m_framelist(),
+ m_pcs(pcs),
+ m_stop_id(stop_id),
+ m_stop_id_is_valid(stop_id_is_valid),
+ m_extended_unwind_token(LLDB_INVALID_ADDRESS),
+ m_queue_name(),
+ m_thread_name(),
+ m_originating_unique_thread_id(tid),
+ m_queue_id(LLDB_INVALID_QUEUE_ID)
{
- m_unwinder_ap.reset (new HistoryUnwind (*this, pcs, stop_id_is_valid));
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ m_unwinder_ap.reset(new HistoryUnwind(*this, pcs, stop_id_is_valid));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
if (log)
- log->Printf ("%p HistoryThread::HistoryThread",
- static_cast<void*>(this));
+ log->Printf("%p HistoryThread::HistoryThread", static_cast<void *>(this));
}
// Destructor
@@ -78,7 +74,9 @@ HistoryThread::CreateRegisterContextForFrame (StackFrame *frame)
lldb::StackFrameListSP
HistoryThread::GetStackFrameList ()
{
- Mutex::Locker (m_framelist_mutex); // FIXME do not throw away the lock after we acquire it..
+ // FIXME do not throw away the lock after we acquire it..
+ std::unique_lock<std::mutex> lock(m_framelist_mutex);
+ lock.unlock();
if (m_framelist.get() == NULL)
{
m_framelist.reset (new StackFrameList (*this, StackFrameListSP(), true));
diff --git a/source/Plugins/Process/Utility/HistoryThread.h b/source/Plugins/Process/Utility/HistoryThread.h
index e87f6496134b..43ac13c2d8bc 100644
--- a/source/Plugins/Process/Utility/HistoryThread.h
+++ b/source/Plugins/Process/Utility/HistoryThread.h
@@ -12,10 +12,11 @@
// C Includes
// C++ Includes
+#include <mutex>
+
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/UserID.h"
@@ -125,7 +126,7 @@ protected:
virtual lldb::StackFrameListSP
GetStackFrameList ();
- mutable Mutex m_framelist_mutex;
+ mutable std::mutex m_framelist_mutex;
lldb::StackFrameListSP m_framelist;
std::vector<lldb::addr_t> m_pcs;
uint32_t m_stop_id;
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.cpp b/source/Plugins/Process/Utility/HistoryUnwind.cpp
index 14afcbee0b49..01d8c3ebdcd3 100644
--- a/source/Plugins/Process/Utility/HistoryUnwind.cpp
+++ b/source/Plugins/Process/Utility/HistoryUnwind.cpp
@@ -40,7 +40,7 @@ HistoryUnwind::~HistoryUnwind ()
void
HistoryUnwind::DoClear ()
{
- Mutex::Locker locker(m_unwind_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
m_pcs.clear();
m_stop_id_is_valid = false;
}
@@ -64,7 +64,9 @@ HistoryUnwind::DoCreateRegisterContextForFrame (StackFrame *frame)
bool
HistoryUnwind::DoGetFrameInfoAtIndex (uint32_t frame_idx, lldb::addr_t& cfa, lldb::addr_t& pc)
{
- Mutex::Locker (m_unwind_mutex); // FIXME do not throw away the lock after we acquire it..
+ // 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;
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.h b/source/Plugins/Process/Utility/HistoryUnwind.h
index 2cb78bc1dc63..890604fcb680 100644
--- a/source/Plugins/Process/Utility/HistoryUnwind.h
+++ b/source/Plugins/Process/Utility/HistoryUnwind.h
@@ -17,7 +17,6 @@
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/Unwind.h"
namespace lldb_private {
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index ebeba8c46a74..b694b833cb48 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -11,6 +11,8 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/DiagnosticManager.h"
+#include "lldb/Host/Config.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ExecutionContext.h"
@@ -18,7 +20,6 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
-#include "lldb/Host/Config.h"
#ifndef LLDB_DISABLE_POSIX
#include <sys/mman.h>
@@ -43,7 +44,7 @@ lldb_private::InferiorCallMmap (Process *process,
addr_t fd,
addr_t offset)
{
- Thread *thread = process->GetThreadList().GetSelectedThread().get();
+ Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
if (thread == NULL)
return false;
@@ -96,27 +97,21 @@ lldb_private::InferiorCallMmap (Process *process,
ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset };
- lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
- mmap_range.GetBaseAddress(),
- clang_void_ptr_type,
- args,
- options));
+ lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
+ clang_void_ptr_type, args, options));
if (call_plan_sp)
{
- StreamFile error_strm;
-
- StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
+ 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,
- error_strm);
+ ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
if (result == eExpressionCompleted)
{
-
+
allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
if (process->GetAddressByteSize() == 4)
{
@@ -144,7 +139,7 @@ lldb_private::InferiorCallMunmap (Process *process,
addr_t addr,
addr_t length)
{
- Thread *thread = process->GetThreadList().GetSelectedThread().get();
+ Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
if (thread == NULL)
return false;
@@ -179,24 +174,18 @@ lldb_private::InferiorCallMunmap (Process *process,
if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
{
lldb::addr_t args[] = { addr, length };
- lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
- munmap_range.GetBaseAddress(),
- CompilerType(),
- args,
- options));
+ lldb::ThreadPlanSP call_plan_sp(
+ new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), CompilerType(), args, options));
if (call_plan_sp)
{
- StreamFile error_strm;
-
- StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
+ 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,
- error_strm);
+ ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
if (result == eExpressionCompleted)
{
return true;
@@ -219,7 +208,7 @@ lldb_private::InferiorCall (Process *process,
addr_t &returned_func,
bool trap_exceptions)
{
- Thread *thread = process->GetThreadList().GetSelectedThread().get();
+ Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
if (thread == NULL || address == NULL)
return false;
@@ -234,24 +223,18 @@ lldb_private::InferiorCall (Process *process,
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));
+ lldb::ThreadPlanSP call_plan_sp(
+ new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type, llvm::ArrayRef<addr_t>(), options));
if (call_plan_sp)
{
- StreamString error_strm;
+ DiagnosticManager diagnostics;
- StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
+ 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,
- error_strm);
+ ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
if (result == eExpressionCompleted)
{
returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
diff --git a/source/Plugins/Process/Utility/Makefile b/source/Plugins/Process/Utility/Makefile
deleted file mode 100644
index eb0caf3f92fe..000000000000
--- a/source/Plugins/Process/Utility/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Utility/Makefile ---------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginProcessUtility
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
index 452fb47ebc8a..aa1bace77203 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
@@ -596,6 +596,7 @@ RegisterContextDarwin_arm::ReadRegisterSet (uint32_t set, bool force)
switch (set)
{
case GPRRegSet: return ReadGPR(force);
+ case GPRAltRegSet: return ReadGPR(force);
case FPURegSet: return ReadFPU(force);
case EXCRegSet: return ReadEXC(force);
case DBGRegSet: return ReadDBG(force);
@@ -613,6 +614,7 @@ RegisterContextDarwin_arm::WriteRegisterSet (uint32_t set)
switch (set)
{
case GPRRegSet: return WriteGPR();
+ case GPRAltRegSet: return WriteGPR();
case FPURegSet: return WriteFPU();
case EXCRegSet: return WriteEXC();
case DBGRegSet: return WriteDBG();
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
index f4d82259f9df..4e831b5a8da7 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
@@ -162,10 +162,11 @@ public:
protected:
enum
{
- GPRRegSet = 1, // ARM_THREAD_STATE
- FPURegSet = 2, // ARM_VFP_STATE
- EXCRegSet = 3, // ARM_EXCEPTION_STATE
- DBGRegSet = 4 // ARM_DEBUG_STATE
+ GPRRegSet = 1, // ARM_THREAD_STATE
+ GPRAltRegSet = 9, // ARM_THREAD_STATE32
+ FPURegSet = 2, // ARM_VFP_STATE
+ EXCRegSet = 3, // ARM_EXCEPTION_STATE
+ DBGRegSet = 4 // ARM_DEBUG_STATE
};
enum
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index efda0edb70c9..8bbaeb8e9a59 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -470,11 +470,13 @@ RegisterContextLLDB::InitializeNonZerothFrame()
return;
}
- bool resolve_tail_call_address = true; // m_current_pc can be one past the address range of the function...
- // This will handle the case where 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. ResolveSymbolContextForAddress
- // will fail to find a symbol, back up the pc by 1 and re-search.
+ bool resolve_tail_call_address = false; // m_current_pc can be one past the address range of the function...
+ // If the saved pc does not point to a function/symbol because it is
+ // beyond the bounds of the correct function and there's no symbol there,
+ // we do *not* want ResolveSymbolContextForAddress to back up the pc by 1,
+ // because then we might not find the correct unwind information later.
+ // Instead, let ResolveSymbolContextForAddress fail, and handle the case
+ // via decr_pc_and_recompute_addr_range below.
const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress (m_current_pc,
resolve_scope,
@@ -1390,45 +1392,28 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
}
}
- if (have_unwindplan_regloc == false)
- {
- // Did the UnwindPlan fail to give us the caller's stack pointer?
- // The stack pointer is defined to be the same as THIS frame's CFA, so return the CFA value as
- // the caller's stack pointer. This is true on x86-32/x86-64 at least.
-
- RegisterNumber sp_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- if (sp_regnum.GetAsKind (eRegisterKindLLDB) != LLDB_INVALID_REGNUM
- && sp_regnum.GetAsKind (eRegisterKindLLDB) == regnum.GetAsKind (eRegisterKindLLDB))
- {
- // make sure we won't lose precision copying an addr_t (m_cfa) into a uint64_t (.inferred_value)
- assert (sizeof (addr_t) <= sizeof (uint64_t));
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
- regloc.location.inferred_value = m_cfa;
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's stack pointer %s (%d) value, computed from CFA",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- }
-
ExecutionContext exe_ctx(m_thread.shared_from_this());
Process *process = exe_ctx.GetProcessPtr();
if (have_unwindplan_regloc == false)
{
- // If a volatile register is being requested, we don't want to forward the next frame's register contents
- // up the stack -- the register is not retrievable at this frame.
+ // If the UnwindPlan failed to give us an unwind location for this register, we may be able to fall back
+ // to some ABI-defined default. For example, some ABIs allow to determine the caller's SP via the CFA.
+ // Also, the ABI may set volatile registers to the undefined state.
ABI *abi = process ? process->GetABI().get() : NULL;
if (abi)
{
const RegisterInfo *reg_info = GetRegisterInfoAtIndex(regnum.GetAsKind (eRegisterKindLLDB));
- if (reg_info && abi->RegisterIsVolatile (reg_info))
+ if (reg_info && abi->GetFallbackRegisterLocation (reg_info, unwindplan_regloc))
{
- UnwindLogMsg ("did not supply reg location for %s (%d) because it is volatile",
+ UnwindLogMsg ("supplying caller's saved %s (%d)'s location using ABI default",
regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
+ have_unwindplan_regloc = true;
}
}
+ }
+ if (have_unwindplan_regloc == false)
+ {
if (IsFrameZero ())
{
// This is frame 0 - we should return the actual live register context value
@@ -1468,15 +1453,33 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
+ if (unwindplan_regloc.IsUndefined())
+ {
+ UnwindLogMsg ("did not supply reg location for %s (%d) because it is volatile",
+ regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
+ }
+
if (unwindplan_regloc.IsSame())
{
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
- regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ if (IsFrameZero() == false
+ && (regnum.GetAsKind (eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_PC
+ || regnum.GetAsKind (eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_RA))
+ {
+ UnwindLogMsg ("register %s (%d) is marked as 'IsSame' - it is a pc or return address reg on a non-zero frame -- treat as if we have no information",
+ regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ }
+ else
+ {
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
+ regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
+ m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)",
+ regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
+ regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
}
if (unwindplan_regloc.IsCFAPlusOffset())
@@ -1536,7 +1539,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
dwarfexpr.SetRegisterKind (unwindplan_registerkind);
Value result;
Error error;
- if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, this, 0, NULL, result, &error))
+ if (dwarfexpr.Evaluate (&exe_ctx, nullptr, nullptr, this, 0, nullptr, nullptr, result, &error))
{
addr_t val;
val = result.GetScalar().ULongLong();
@@ -1836,7 +1839,7 @@ RegisterContextLLDB::ReadCFAValueForRow (lldb::RegisterKind row_register_kind,
dwarfexpr.SetRegisterKind (row_register_kind);
Value result;
Error error;
- if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, this, 0, NULL, result, &error))
+ if (dwarfexpr.Evaluate (&exe_ctx, nullptr, nullptr, this, 0, nullptr, nullptr, result, &error))
{
cfa_value = result.GetScalar().ULongLong();
@@ -1897,12 +1900,13 @@ RegisterContextLLDB::ReadGPRValue (lldb::RegisterKind register_kind, uint32_t re
bool pc_register = false;
uint32_t generic_regnum;
- if (register_kind == eRegisterKindGeneric && regnum == LLDB_REGNUM_GENERIC_PC)
+ if (register_kind == eRegisterKindGeneric
+ && (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA))
{
pc_register = true;
}
else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (register_kind, regnum, eRegisterKindGeneric, generic_regnum)
- && generic_regnum == LLDB_REGNUM_GENERIC_PC)
+ && (generic_regnum == LLDB_REGNUM_GENERIC_PC || generic_regnum == LLDB_REGNUM_GENERIC_RA))
{
pc_register = true;
}
@@ -1944,9 +1948,16 @@ RegisterContextLLDB::ReadRegister (const RegisterInfo *reg_info, RegisterValue &
return m_thread.GetRegisterContext()->ReadRegister (reg_info, value);
}
+ bool is_pc_regnum = false;
+ if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC
+ || reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA)
+ {
+ is_pc_regnum = true;
+ }
+
lldb_private::UnwindLLDB::RegisterLocation regloc;
// Find out where the NEXT frame saved THIS frame's register contents
- if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, false))
+ if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum))
return false;
return ReadRegisterValueFromRegisterLocation (regloc, reg_info, value);
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp
new file mode 100644
index 000000000000..9aef1e9830e2
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp
@@ -0,0 +1,98 @@
+//===-- RegisterContextLinux_s390x.cpp --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextPOSIX_s390x.h"
+#include "RegisterContextLinux_s390x.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+//---------------------------------------------------------------------------
+// Include RegisterInfos_s390x to declare our g_register_infos_s390x structure.
+//---------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_S390X_STRUCT
+#include "RegisterInfos_s390x.h"
+#undef DECLARE_REGISTER_INFOS_S390X_STRUCT
+
+static const RegisterInfo *
+GetRegisterInfoPtr(const ArchSpec &target_arch)
+{
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::systemz:
+ return g_register_infos_s390x;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
+}
+
+static uint32_t
+GetRegisterInfoCount(const ArchSpec &target_arch)
+{
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::systemz:
+ return k_num_registers_s390x;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
+static uint32_t
+GetUserRegisterInfoCount(const ArchSpec &target_arch)
+{
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::systemz:
+ return k_num_user_registers_s390x + k_num_linux_registers_s390x;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
+RegisterContextLinux_s390x::RegisterContextLinux_s390x(const ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)),
+ m_user_register_count(GetUserRegisterInfoCount(target_arch))
+{
+}
+
+const std::vector<lldb_private::RegisterInfo> *
+RegisterContextLinux_s390x::GetDynamicRegisterInfoP() const
+{
+ return &d_register_infos;
+}
+
+const RegisterInfo *
+RegisterContextLinux_s390x::GetRegisterInfo() const
+{
+ return m_register_info_p;
+}
+
+uint32_t
+RegisterContextLinux_s390x::GetRegisterCount() const
+{
+ return m_register_info_count;
+}
+
+uint32_t
+RegisterContextLinux_s390x::GetUserRegisterCount() const
+{
+ return m_user_register_count;
+}
+
+size_t
+RegisterContextLinux_s390x::GetGPRSize() const
+{
+ return 0;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h b/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h
new file mode 100644
index 000000000000..bdc7f34f62e7
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h
@@ -0,0 +1,42 @@
+//===-- RegisterContextLinux_s390x.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextLinux_s390x_h_
+#define liblldb_RegisterContextLinux_s390x_h_
+
+#include "RegisterInfoInterface.h"
+
+class RegisterContextLinux_s390x : public lldb_private::RegisterInfoInterface
+{
+public:
+ RegisterContextLinux_s390x(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;
+
+ const std::vector<lldb_private::RegisterInfo> *
+ GetDynamicRegisterInfoP() const override;
+
+private:
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+ uint32_t m_user_register_count;
+ std::vector<lldb_private::RegisterInfo> d_register_infos;
+};
+
+#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
new file mode 100644
index 000000000000..71ece160d4d4
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
@@ -0,0 +1,357 @@
+//===-- RegisterContextNetBSD_x86_64.cpp ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#include <cstddef>
+#include <vector>
+
+#include "llvm/Support/Compiler.h"
+
+#include "RegisterContextPOSIX_x86.h"
+#include "RegisterContextNetBSD_x86_64.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+// src/sys/arch/amd64/include/frame_regs.h
+typedef struct _GPR
+{
+ uint64_t rdi; /* 0 */
+ uint64_t rsi; /* 1 */
+ uint64_t rdx; /* 2 */
+ uint64_t rcx; /* 3 */
+ uint64_t r8; /* 4 */
+ uint64_t r9; /* 5 */
+ uint64_t r10; /* 6 */
+ uint64_t r11; /* 7 */
+ uint64_t r12; /* 8 */
+ uint64_t r13; /* 9 */
+ uint64_t r14; /* 10 */
+ uint64_t r15; /* 11 */
+ uint64_t rbp; /* 12 */
+ uint64_t rbx; /* 13 */
+ uint64_t rax; /* 14 */
+ uint64_t gs; /* 15 */
+ uint64_t fs; /* 16 */
+ uint64_t es; /* 17 */
+ uint64_t ds; /* 18 */
+ uint64_t trapno; /* 19 */
+ uint64_t err; /* 20 */
+ uint64_t rip; /* 21 */
+ uint64_t cs; /* 22 */
+ uint64_t rflags; /* 23 */
+ uint64_t rsp; /* 24 */
+ uint64_t ss; /* 25 */
+} GPR;
+
+/*
+ * As of NetBSD-7.99.25 there is no support for debug registers
+ * https://en.wikipedia.org/wiki/X86_debug_register
+ */
+
+/*
+ * src/sys/arch/amd64/include/mcontext.h
+ *
+ * typedef struct {
+ * __gregset_t __gregs;
+ * __greg_t _mc_tlsbase;
+ * __fpregset_t __fpregs;
+ * } mcontext_t;
+ */
+
+struct UserArea {
+ GPR gpr;
+ uint64_t mc_tlsbase;
+ FPR fpr;
+};
+
+
+//---------------------------------------------------------------------------
+// Cherry-pick parts of RegisterInfos_x86_64.h, without debug registers
+//---------------------------------------------------------------------------
+// Computes the offset of the given GPR in the user data area.
+#define GPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(GPR, regname))
+
+// Computes the offset of the given FPR in the extended data area.
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FXSAVE, regname))
+
+// Computes the offset of the YMM register assembled from register halves.
+// Based on DNBArchImplX86_64.cpp from debugserver
+#define YMM_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + \
+ (32 * reg_index))
+
+// Number of bytes needed to represent a FPR.
+#define FPR_SIZE(reg) sizeof(((FXSAVE*)NULL)->reg)
+
+// Number of bytes needed to represent the i'th FP register.
+#define FP_SIZE sizeof(((MMSReg*)NULL)->bytes)
+
+// Number of bytes needed to represent an XMM register.
+#define XMM_SIZE sizeof(XMMReg)
+
+// Number of bytes needed to represent a YMM register.
+#define YMM_SIZE sizeof(YMMReg)
+
+// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
+
+// Note that the size and offset will be updated by platform-specific classes.
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \
+ eFormatHex, { kind1, kind2, kind3, kind4, lldb_##reg##_x86_64 }, NULL, NULL }
+
+#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
+ { #name, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
+ eFormatHex, { kind1, kind2, kind3, kind4, lldb_##name##_x86_64 }, NULL, NULL }
+
+#define DEFINE_FP_ST(reg, i) \
+ { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
+ eEncodingVector, eFormatVectorOfUInt8, \
+ { dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \
+ NULL, NULL }
+
+#define DEFINE_FP_MM(reg, i) \
+ { #reg#i, NULL, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
+ eEncodingUint, eFormatHex, \
+ { dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_mm##i##_x86_64 }, \
+ NULL, NULL }
+
+#define DEFINE_XMM(reg, i) \
+ { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
+ eEncodingVector, eFormatVectorOfUInt8, \
+ { dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_x86_64}, \
+ NULL, NULL }
+
+#define DEFINE_YMM(reg, i) \
+ { #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(i), \
+ eEncodingVector, eFormatVectorOfUInt8, \
+ { dwarf_##reg##i##h_x86_64, dwarf_##reg##i##h_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_x86_64 }, \
+ NULL, NULL }
+
+#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \
+ { #reg32, NULL, 4, GPR_OFFSET(reg64), eEncodingUint, \
+ eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg32##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
+#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \
+ { #reg16, NULL, 2, GPR_OFFSET(reg64), eEncodingUint, \
+ eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg16##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
+#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \
+ { #reg8, NULL, 1, GPR_OFFSET(reg64)+1, eEncodingUint, \
+ eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
+#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \
+ { #reg8, NULL, 1, GPR_OFFSET(reg64), eEncodingUint, \
+ eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
+
+static RegisterInfo
+g_register_infos_x86_64[] =
+{
+ // General purpose registers. EH_Frame, DWARF, Generic, Process Plugin
+ DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+
+ DEFINE_GPR_PSEUDO_32(eax, rax),
+ DEFINE_GPR_PSEUDO_32(ebx, rbx),
+ DEFINE_GPR_PSEUDO_32(ecx, rcx),
+ DEFINE_GPR_PSEUDO_32(edx, rdx),
+ DEFINE_GPR_PSEUDO_32(edi, rdi),
+ DEFINE_GPR_PSEUDO_32(esi, rsi),
+ DEFINE_GPR_PSEUDO_32(ebp, rbp),
+ DEFINE_GPR_PSEUDO_32(esp, rsp),
+ DEFINE_GPR_PSEUDO_32(r8d, r8),
+ DEFINE_GPR_PSEUDO_32(r9d, r9),
+ DEFINE_GPR_PSEUDO_32(r10d, r10),
+ DEFINE_GPR_PSEUDO_32(r11d, r11),
+ DEFINE_GPR_PSEUDO_32(r12d, r12),
+ DEFINE_GPR_PSEUDO_32(r13d, r13),
+ DEFINE_GPR_PSEUDO_32(r14d, r14),
+ DEFINE_GPR_PSEUDO_32(r15d, r15),
+ DEFINE_GPR_PSEUDO_16(ax, rax),
+ DEFINE_GPR_PSEUDO_16(bx, rbx),
+ DEFINE_GPR_PSEUDO_16(cx, rcx),
+ DEFINE_GPR_PSEUDO_16(dx, rdx),
+ DEFINE_GPR_PSEUDO_16(di, rdi),
+ DEFINE_GPR_PSEUDO_16(si, rsi),
+ DEFINE_GPR_PSEUDO_16(bp, rbp),
+ DEFINE_GPR_PSEUDO_16(sp, rsp),
+ DEFINE_GPR_PSEUDO_16(r8w, r8),
+ DEFINE_GPR_PSEUDO_16(r9w, r9),
+ DEFINE_GPR_PSEUDO_16(r10w, r10),
+ DEFINE_GPR_PSEUDO_16(r11w, r11),
+ DEFINE_GPR_PSEUDO_16(r12w, r12),
+ DEFINE_GPR_PSEUDO_16(r13w, r13),
+ DEFINE_GPR_PSEUDO_16(r14w, r14),
+ DEFINE_GPR_PSEUDO_16(r15w, r15),
+ DEFINE_GPR_PSEUDO_8H(ah, rax),
+ DEFINE_GPR_PSEUDO_8H(bh, rbx),
+ DEFINE_GPR_PSEUDO_8H(ch, rcx),
+ DEFINE_GPR_PSEUDO_8H(dh, rdx),
+ DEFINE_GPR_PSEUDO_8L(al, rax),
+ DEFINE_GPR_PSEUDO_8L(bl, rbx),
+ DEFINE_GPR_PSEUDO_8L(cl, rcx),
+ DEFINE_GPR_PSEUDO_8L(dl, rdx),
+ DEFINE_GPR_PSEUDO_8L(dil, rdi),
+ DEFINE_GPR_PSEUDO_8L(sil, rsi),
+ DEFINE_GPR_PSEUDO_8L(bpl, rbp),
+ DEFINE_GPR_PSEUDO_8L(spl, rsp),
+ DEFINE_GPR_PSEUDO_8L(r8l, r8),
+ DEFINE_GPR_PSEUDO_8L(r9l, r9),
+ DEFINE_GPR_PSEUDO_8L(r10l, r10),
+ DEFINE_GPR_PSEUDO_8L(r11l, r11),
+ DEFINE_GPR_PSEUDO_8L(r12l, r12),
+ DEFINE_GPR_PSEUDO_8L(r13l, r13),
+ DEFINE_GPR_PSEUDO_8L(r14l, r14),
+ DEFINE_GPR_PSEUDO_8L(r15l, r15),
+
+ // i387 Floating point registers. EH_frame, DWARF, Generic, Process Plugin
+ DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+
+ // FP registers.
+ DEFINE_FP_ST(st, 0),
+ DEFINE_FP_ST(st, 1),
+ DEFINE_FP_ST(st, 2),
+ DEFINE_FP_ST(st, 3),
+ DEFINE_FP_ST(st, 4),
+ DEFINE_FP_ST(st, 5),
+ DEFINE_FP_ST(st, 6),
+ DEFINE_FP_ST(st, 7),
+ DEFINE_FP_MM(mm, 0),
+ DEFINE_FP_MM(mm, 1),
+ DEFINE_FP_MM(mm, 2),
+ DEFINE_FP_MM(mm, 3),
+ DEFINE_FP_MM(mm, 4),
+ DEFINE_FP_MM(mm, 5),
+ DEFINE_FP_MM(mm, 6),
+ DEFINE_FP_MM(mm, 7),
+
+ // XMM registers
+ DEFINE_XMM(xmm, 0),
+ DEFINE_XMM(xmm, 1),
+ DEFINE_XMM(xmm, 2),
+ DEFINE_XMM(xmm, 3),
+ DEFINE_XMM(xmm, 4),
+ DEFINE_XMM(xmm, 5),
+ DEFINE_XMM(xmm, 6),
+ DEFINE_XMM(xmm, 7),
+ DEFINE_XMM(xmm, 8),
+ DEFINE_XMM(xmm, 9),
+ DEFINE_XMM(xmm, 10),
+ DEFINE_XMM(xmm, 11),
+ DEFINE_XMM(xmm, 12),
+ DEFINE_XMM(xmm, 13),
+ DEFINE_XMM(xmm, 14),
+ DEFINE_XMM(xmm, 15),
+
+ // Copy of YMM registers assembled from xmm and ymmh
+ DEFINE_YMM(ymm, 0),
+ DEFINE_YMM(ymm, 1),
+ DEFINE_YMM(ymm, 2),
+ DEFINE_YMM(ymm, 3),
+ DEFINE_YMM(ymm, 4),
+ DEFINE_YMM(ymm, 5),
+ DEFINE_YMM(ymm, 6),
+ DEFINE_YMM(ymm, 7),
+ DEFINE_YMM(ymm, 8),
+ DEFINE_YMM(ymm, 9),
+ DEFINE_YMM(ymm, 10),
+ DEFINE_YMM(ymm, 11),
+ DEFINE_YMM(ymm, 12),
+ DEFINE_YMM(ymm, 13),
+ DEFINE_YMM(ymm, 14),
+ DEFINE_YMM(ymm, 15),
+};
+
+//---------------------------------------------------------------------------
+// End of cherry-pick of RegisterInfos_x86_64.h
+//---------------------------------------------------------------------------
+
+static const RegisterInfo *
+PrivateGetRegisterInfoPtr (const lldb_private::ArchSpec& target_arch)
+{
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::x86_64:
+ return g_register_infos_x86_64;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
+}
+
+static uint32_t
+PrivateGetRegisterCount (const lldb_private::ArchSpec& target_arch)
+{
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
+RegisterContextNetBSD_x86_64::RegisterContextNetBSD_x86_64(const ArchSpec &target_arch) :
+ lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p (PrivateGetRegisterInfoPtr (target_arch)),
+ m_register_count (PrivateGetRegisterCount (target_arch))
+{
+}
+
+size_t
+RegisterContextNetBSD_x86_64::GetGPRSize() const
+{
+ return sizeof(GPR);
+}
+
+const RegisterInfo *
+RegisterContextNetBSD_x86_64::GetRegisterInfo() const
+{
+ return m_register_info_p;
+}
+
+uint32_t
+RegisterContextNetBSD_x86_64::GetRegisterCount () const
+{
+ return m_register_count;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h b/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
new file mode 100644
index 000000000000..c267278c418c
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
@@ -0,0 +1,35 @@
+//===-- RegisterContextNetBSD_x86_64.h -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextNetBSD_x86_64_H_
+#define liblldb_RegisterContextNetBSD_x86_64_H_
+
+#include "RegisterInfoInterface.h"
+
+class RegisterContextNetBSD_x86_64:
+ public lldb_private::RegisterInfoInterface
+{
+public:
+ RegisterContextNetBSD_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;
+
+private:
+ const lldb_private::RegisterInfo *m_register_info_p;
+ const uint32_t m_register_count;
+};
+
+#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
new file mode 100644
index 000000000000..960be50c7be3
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
@@ -0,0 +1,265 @@
+//===-- RegisterContextPOSIX_x86.cpp ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstring>
+#include <errno.h>
+#include <stdint.h>
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "llvm/Support/Compiler.h"
+
+#include "RegisterContext_s390x.h"
+#include "RegisterContextPOSIX_s390x.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+// s390x 64-bit general purpose registers.
+static const uint32_t g_gpr_regnums_s390x[] =
+{
+ lldb_r0_s390x,
+ lldb_r1_s390x,
+ lldb_r2_s390x,
+ lldb_r3_s390x,
+ lldb_r4_s390x,
+ lldb_r5_s390x,
+ lldb_r6_s390x,
+ lldb_r7_s390x,
+ lldb_r8_s390x,
+ lldb_r9_s390x,
+ lldb_r10_s390x,
+ lldb_r11_s390x,
+ lldb_r12_s390x,
+ lldb_r13_s390x,
+ lldb_r14_s390x,
+ lldb_r15_s390x,
+ lldb_acr0_s390x,
+ lldb_acr1_s390x,
+ lldb_acr2_s390x,
+ lldb_acr3_s390x,
+ lldb_acr4_s390x,
+ lldb_acr5_s390x,
+ lldb_acr6_s390x,
+ lldb_acr7_s390x,
+ lldb_acr8_s390x,
+ lldb_acr9_s390x,
+ lldb_acr10_s390x,
+ lldb_acr11_s390x,
+ lldb_acr12_s390x,
+ lldb_acr13_s390x,
+ lldb_acr14_s390x,
+ lldb_acr15_s390x,
+ lldb_pswm_s390x,
+ lldb_pswa_s390x,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) - 1 == k_num_gpr_registers_s390x,
+ "g_gpr_regnums_s390x has wrong number of register infos");
+
+// s390x 64-bit floating point registers.
+static const uint32_t g_fpu_regnums_s390x[] =
+{
+ lldb_f0_s390x,
+ lldb_f1_s390x,
+ lldb_f2_s390x,
+ lldb_f3_s390x,
+ lldb_f4_s390x,
+ lldb_f5_s390x,
+ lldb_f6_s390x,
+ lldb_f7_s390x,
+ lldb_f8_s390x,
+ lldb_f9_s390x,
+ lldb_f10_s390x,
+ lldb_f11_s390x,
+ lldb_f12_s390x,
+ lldb_f13_s390x,
+ lldb_f14_s390x,
+ lldb_f15_s390x,
+ lldb_fpc_s390x,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) - 1 == k_num_fpr_registers_s390x,
+ "g_fpu_regnums_s390x has wrong number of register infos");
+
+// Number of register sets provided by this context.
+enum
+{
+ k_num_register_sets = 2
+};
+
+// Register sets for s390x 64-bit.
+static const RegisterSet g_reg_sets_s390x[k_num_register_sets] =
+{
+ { "General Purpose Registers", "gpr", k_num_gpr_registers_s390x, g_gpr_regnums_s390x },
+ { "Floating Point Registers", "fpr", k_num_fpr_registers_s390x, g_fpu_regnums_s390x },
+};
+
+bool
+RegisterContextPOSIX_s390x::IsGPR(unsigned reg)
+{
+ return reg <= m_reg_info.last_gpr; // GPRs come first.
+}
+
+bool
+RegisterContextPOSIX_s390x::IsFPR(unsigned reg)
+{
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+}
+
+RegisterContextPOSIX_s390x::RegisterContextPOSIX_s390x(Thread &thread, uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContext(thread, concrete_frame_idx)
+{
+ m_register_info_ap.reset(register_info);
+
+ switch (register_info->m_target_arch.GetMachine())
+ {
+ case llvm::Triple::systemz:
+ m_reg_info.num_registers = k_num_registers_s390x;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
+ m_reg_info.last_gpr = k_last_gpr_s390x;
+ m_reg_info.first_fpr = k_first_fpr_s390x;
+ m_reg_info.last_fpr = k_last_fpr_s390x;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+}
+
+RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x()
+{
+}
+
+void
+RegisterContextPOSIX_s390x::Invalidate()
+{
+}
+
+void
+RegisterContextPOSIX_s390x::InvalidateAllRegisters()
+{
+}
+
+const RegisterInfo *
+RegisterContextPOSIX_s390x::GetRegisterInfo()
+{
+ return m_register_info_ap->GetRegisterInfo();
+}
+
+const RegisterInfo *
+RegisterContextPOSIX_s390x::GetRegisterInfoAtIndex(size_t reg)
+{
+ if (reg < m_reg_info.num_registers)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
+}
+
+size_t
+RegisterContextPOSIX_s390x::GetRegisterCount()
+{
+ return m_reg_info.num_registers;
+}
+
+unsigned
+RegisterContextPOSIX_s390x::GetRegisterOffset(unsigned reg)
+{
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
+}
+
+unsigned
+RegisterContextPOSIX_s390x::GetRegisterSize(unsigned reg)
+{
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
+}
+
+const char *
+RegisterContextPOSIX_s390x::GetRegisterName(unsigned reg)
+{
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
+}
+
+bool
+RegisterContextPOSIX_s390x::IsRegisterSetAvailable(size_t set_index)
+{
+ return set_index < k_num_register_sets;
+}
+
+size_t
+RegisterContextPOSIX_s390x::GetRegisterSetCount()
+{
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set)
+ {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
+
+ return sets;
+}
+
+const RegisterSet *
+RegisterContextPOSIX_s390x::GetRegisterSet(size_t set)
+{
+ if (IsRegisterSetAvailable(set))
+ {
+ switch (m_register_info_ap->m_target_arch.GetMachine())
+ {
+ case llvm::Triple::systemz:
+ return &g_reg_sets_s390x[set];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
+ }
+ return NULL;
+}
+
+lldb::ByteOrder
+RegisterContextPOSIX_s390x::GetByteOrder()
+{
+ // Get the target process whose privileged thread was used for the register read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
+
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
+}
+
+// Used when parsing DWARF and EH frame information and any other
+// object file sections that contain register numbers in them.
+uint32_t
+RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
+{
+ const uint32_t num_regs = GetRegisterCount();
+
+ assert(kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
+ {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
+
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
+
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
new file mode 100644
index 000000000000..4904b2857c43
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
@@ -0,0 +1,103 @@
+//===-- RegisterContextPOSIX_s390x.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextPOSIX_s390x_h_
+#define liblldb_RegisterContextPOSIX_s390x_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
+#include "RegisterInfoInterface.h"
+#include "RegisterContext_s390x.h"
+#include "lldb-s390x-register-enums.h"
+
+class ProcessMonitor;
+
+class RegisterContextPOSIX_s390x : public lldb_private::RegisterContext
+{
+public:
+ RegisterContextPOSIX_s390x(lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
+
+ ~RegisterContextPOSIX_s390x() override;
+
+ void
+ Invalidate();
+
+ void
+ InvalidateAllRegisters() override;
+
+ size_t
+ GetRegisterCount() override;
+
+ virtual unsigned
+ GetRegisterSize(unsigned reg);
+
+ virtual unsigned
+ GetRegisterOffset(unsigned reg);
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t
+ GetRegisterSetCount() override;
+
+ const lldb_private::RegisterSet *
+ GetRegisterSet(size_t set) override;
+
+ const char *
+ GetRegisterName(unsigned reg);
+
+ uint32_t
+ ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+
+protected:
+ struct RegInfo
+ {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+ };
+
+ RegInfo m_reg_info;
+ std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap;
+
+ virtual bool
+ IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *
+ GetRegisterInfo();
+
+ bool
+ IsGPR(unsigned reg);
+
+ bool
+ IsFPR(unsigned reg);
+
+ lldb::ByteOrder
+ GetByteOrder();
+
+ virtual bool
+ ReadGPR() = 0;
+ virtual bool
+ ReadFPR() = 0;
+ virtual bool
+ WriteGPR() = 0;
+ virtual bool
+ WriteFPR() = 0;
+};
+
+#endif // liblldb_RegisterContextPOSIX_s390x_h_
diff --git a/source/Plugins/Process/Utility/RegisterContext_s390x.h b/source/Plugins/Process/Utility/RegisterContext_s390x.h
new file mode 100644
index 000000000000..9777c7744409
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContext_s390x.h
@@ -0,0 +1,93 @@
+//===-- RegisterContext_s390x.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContext_s390x_h_
+#define liblldb_RegisterContext_s390x_h_
+
+//---------------------------------------------------------------------------
+// SystemZ ehframe, dwarf regnums
+//---------------------------------------------------------------------------
+
+// EHFrame and DWARF Register numbers (eRegisterKindEHFrame & eRegisterKindDWARF)
+enum
+{
+ // General Purpose Registers
+ dwarf_r0_s390x = 0,
+ dwarf_r1_s390x,
+ dwarf_r2_s390x,
+ dwarf_r3_s390x,
+ dwarf_r4_s390x,
+ dwarf_r5_s390x,
+ dwarf_r6_s390x,
+ dwarf_r7_s390x,
+ dwarf_r8_s390x,
+ dwarf_r9_s390x,
+ dwarf_r10_s390x,
+ dwarf_r11_s390x,
+ dwarf_r12_s390x,
+ dwarf_r13_s390x,
+ dwarf_r14_s390x,
+ dwarf_r15_s390x,
+ // Floating Point Registers / Vector Registers 0-15
+ dwarf_f0_s390x = 16,
+ dwarf_f2_s390x,
+ dwarf_f4_s390x,
+ dwarf_f6_s390x,
+ dwarf_f1_s390x,
+ dwarf_f3_s390x,
+ dwarf_f5_s390x,
+ dwarf_f7_s390x,
+ dwarf_f8_s390x,
+ dwarf_f10_s390x,
+ dwarf_f12_s390x,
+ dwarf_f14_s390x,
+ dwarf_f9_s390x,
+ dwarf_f11_s390x,
+ dwarf_f13_s390x,
+ dwarf_f15_s390x,
+ // Access Registers
+ dwarf_acr0_s390x = 48,
+ dwarf_acr1_s390x,
+ dwarf_acr2_s390x,
+ dwarf_acr3_s390x,
+ dwarf_acr4_s390x,
+ dwarf_acr5_s390x,
+ dwarf_acr6_s390x,
+ dwarf_acr7_s390x,
+ dwarf_acr8_s390x,
+ dwarf_acr9_s390x,
+ dwarf_acr10_s390x,
+ dwarf_acr11_s390x,
+ dwarf_acr12_s390x,
+ dwarf_acr13_s390x,
+ dwarf_acr14_s390x,
+ dwarf_acr15_s390x,
+ // Program Status Word
+ dwarf_pswm_s390x = 64,
+ dwarf_pswa_s390x,
+ // Vector Registers 16-31
+ dwarf_v16_s390x = 68,
+ dwarf_v18_s390x,
+ dwarf_v20_s390x,
+ dwarf_v22_s390x,
+ dwarf_v17_s390x,
+ dwarf_v19_s390x,
+ dwarf_v21_s390x,
+ dwarf_v23_s390x,
+ dwarf_v24_s390x,
+ dwarf_v26_s390x,
+ dwarf_v28_s390x,
+ dwarf_v30_s390x,
+ dwarf_v25_s390x,
+ dwarf_v27_s390x,
+ dwarf_v29_s390x,
+ dwarf_v31_s390x,
+};
+
+#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfos_mips.h b/source/Plugins/Process/Utility/RegisterInfos_mips.h
index eef27f0208e0..3b81acf26146 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_mips.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_mips.h
@@ -39,8 +39,12 @@
eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips }, NULL, NULL }
#define DEFINE_FPR(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((FPR_linux_mips*)NULL)->reg), FPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL }
+ { #reg, alt, sizeof(((FPR_linux_mips*)NULL)->reg), FPR_OFFSET(reg), eEncodingIEEE754, \
+ eFormatFloat, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL }
+
+#define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3, kind4) \
+ { #reg, alt, sizeof(((FPR_linux_mips*)NULL)->reg), FPR_OFFSET(reg), eEncodingUint, \
+ eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL }
#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \
{ #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingVector, \
@@ -126,9 +130,9 @@ g_register_infos_mips[] =
DEFINE_FPR (f29, nullptr, dwarf_f29_mips, dwarf_f29_mips, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_FPR (f30, nullptr, dwarf_f30_mips, dwarf_f30_mips, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_FPR (f31, nullptr, dwarf_f31_mips, dwarf_f31_mips, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR (fcsr, nullptr, dwarf_fcsr_mips, dwarf_fcsr_mips, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR (fir, nullptr, dwarf_fir_mips, dwarf_fir_mips, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR (config5, nullptr, dwarf_config5_mips, dwarf_config5_mips, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR_INFO (fcsr, nullptr, dwarf_fcsr_mips, dwarf_fcsr_mips, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR_INFO (fir, nullptr, dwarf_fir_mips, dwarf_fir_mips, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR_INFO (config5, nullptr, dwarf_config5_mips, dwarf_config5_mips, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_MSA (w0, nullptr, dwarf_w0_mips, dwarf_w0_mips, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_MSA (w1, nullptr, dwarf_w1_mips, dwarf_w1_mips, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_MSA (w2, nullptr, dwarf_w2_mips, dwarf_w2_mips, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
@@ -176,6 +180,7 @@ static_assert((sizeof(g_register_infos_mips) / sizeof(g_register_infos_mips[0]))
#undef MSA_OFFSET
#undef DEFINE_GPR
#undef DEFINE_FPR
+#undef DEFINE_FPR_INFO
#undef DEFINE_MSA
#undef DEFINE_MSA_INFO
diff --git a/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/source/Plugins/Process/Utility/RegisterInfos_mips64.h
index 45853d7931dd..8dbfa6da94a2 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_mips64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_mips64.h
@@ -56,6 +56,10 @@
eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL }
#define DEFINE_FPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { #reg, alt, sizeof(((FPR_linux_mips*)0)->reg), FPR_OFFSET(reg), eEncodingIEEE754, \
+ eFormatFloat, { kind1, kind2, kind3, kind4, fpr_##reg##_mips64 }, NULL, NULL }
+
+#define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3, kind4) \
{ #reg, alt, sizeof(((FPR_linux_mips*)0)->reg), FPR_OFFSET(reg), eEncodingUint, \
eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips64 }, NULL, NULL }
@@ -184,9 +188,9 @@ g_register_infos_mips64[] =
DEFINE_FPR (f29, nullptr, dwarf_f29_mips64, dwarf_f29_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_FPR (f30, nullptr, dwarf_f30_mips64, dwarf_f30_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_FPR (f31, nullptr, dwarf_f31_mips64, dwarf_f31_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR (fcsr, nullptr, dwarf_fcsr_mips64, dwarf_fcsr_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR (fir, nullptr, dwarf_fir_mips64, dwarf_fir_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR (config5, nullptr, dwarf_config5_mips64, dwarf_config5_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR_INFO (fcsr, nullptr, dwarf_fcsr_mips64, dwarf_fcsr_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR_INFO (fir, nullptr, dwarf_fir_mips64, dwarf_fir_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR_INFO (config5, nullptr, dwarf_config5_mips64, dwarf_config5_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_MSA (w0, nullptr, dwarf_w0_mips64, dwarf_w0_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_MSA (w1, nullptr, dwarf_w1_mips64, dwarf_w1_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_MSA (w2, nullptr, dwarf_w2_mips64, dwarf_w2_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
@@ -233,6 +237,7 @@ static_assert((sizeof(g_register_infos_mips64) / sizeof(g_register_infos_mips64[
#undef DEFINE_GPR
#undef DEFINE_GPR_INFO
#undef DEFINE_FPR
+#undef DEFINE_FPR_INFO
#undef DEFINE_MSA
#undef DEFINE_MSA_INFO
#undef GPR_OFFSET
diff --git a/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/source/Plugins/Process/Utility/RegisterInfos_s390x.h
new file mode 100644
index 000000000000..43152640297e
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterInfos_s390x.h
@@ -0,0 +1,132 @@
+//===-- RegisterInfos_s390x.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <stddef.h>
+
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/Support/Compiler.h"
+
+// Project includes
+
+#ifdef DECLARE_REGISTER_INFOS_S390X_STRUCT
+
+// Computes the offset of the given GPR in the user data area.
+#define GPR_OFFSET(num) (16 + 8 * num)
+// Computes the offset of the given ACR in the user data area.
+#define ACR_OFFSET(num) (16 + 8 * 16 + 4 * num)
+// Computes the offset of the given FPR in the extended data area.
+#define FPR_OFFSET(num) (8 + 8 * num)
+
+// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
+
+#define DEFINE_GPR(name, size, offset, alt, generic) \
+ { \
+ #name, alt, size, offset, eEncodingUint, eFormatHex, \
+ { dwarf_##name##_s390x, dwarf_##name##_s390x, generic, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
+ NULL, NULL, \
+ }
+
+#define DEFINE_GPR_NODWARF(name, size, offset, alt, generic) \
+ { \
+ #name, alt, size, offset, eEncodingUint, eFormatHex, \
+ { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, generic, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
+ NULL, NULL, \
+ }
+
+#define DEFINE_FPR(name, size, offset) \
+ { \
+ #name, NULL, size, offset, eEncodingUint, eFormatHex, \
+ { dwarf_##name##_s390x, dwarf_##name##_s390x, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
+ NULL, NULL, \
+ }
+
+#define DEFINE_FPR_NODWARF(name, size, offset) \
+ { \
+ #name, NULL, size, offset, eEncodingUint, eFormatHex, \
+ { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
+ NULL, NULL, \
+ }
+
+static RegisterInfo g_register_infos_s390x[] =
+{
+ // General purpose registers.
+ DEFINE_GPR(r0, 8, GPR_OFFSET(0), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r1, 8, GPR_OFFSET(1), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r2, 8, GPR_OFFSET(2), "arg1", LLDB_REGNUM_GENERIC_ARG1),
+ DEFINE_GPR(r3, 8, GPR_OFFSET(3), "arg2", LLDB_REGNUM_GENERIC_ARG2),
+ DEFINE_GPR(r4, 8, GPR_OFFSET(4), "arg3", LLDB_REGNUM_GENERIC_ARG3),
+ DEFINE_GPR(r5, 8, GPR_OFFSET(5), "arg4", LLDB_REGNUM_GENERIC_ARG4),
+ DEFINE_GPR(r6, 8, GPR_OFFSET(6), "arg5", LLDB_REGNUM_GENERIC_ARG5),
+ DEFINE_GPR(r7, 8, GPR_OFFSET(7), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, 8, GPR_OFFSET(8), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, 8, GPR_OFFSET(9), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, 8, GPR_OFFSET(10), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, 8, GPR_OFFSET(11), "fp", LLDB_REGNUM_GENERIC_FP),
+ DEFINE_GPR(r12, 8, GPR_OFFSET(12), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, 8, GPR_OFFSET(13), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, 8, GPR_OFFSET(14), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, 8, GPR_OFFSET(15), "sp", LLDB_REGNUM_GENERIC_SP),
+ DEFINE_GPR(acr0, 4, ACR_OFFSET(0), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr1, 4, ACR_OFFSET(1), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr2, 4, ACR_OFFSET(2), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr3, 4, ACR_OFFSET(3), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr4, 4, ACR_OFFSET(4), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr5, 4, ACR_OFFSET(5), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr6, 4, ACR_OFFSET(6), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr7, 4, ACR_OFFSET(7), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr8, 4, ACR_OFFSET(8), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr9, 4, ACR_OFFSET(9), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr10, 4, ACR_OFFSET(10), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr11, 4, ACR_OFFSET(11), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr12, 4, ACR_OFFSET(12), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr13, 4, ACR_OFFSET(13), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr14, 4, ACR_OFFSET(14), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(acr15, 4, ACR_OFFSET(15), nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(pswm, 8, 0, "flags", LLDB_REGNUM_GENERIC_FLAGS),
+ DEFINE_GPR(pswa, 8, 8, "pc", LLDB_REGNUM_GENERIC_PC),
+
+ // Floating point registers.
+ DEFINE_FPR(f0, 8, FPR_OFFSET(0)),
+ DEFINE_FPR(f1, 8, FPR_OFFSET(1)),
+ DEFINE_FPR(f2, 8, FPR_OFFSET(2)),
+ DEFINE_FPR(f3, 8, FPR_OFFSET(3)),
+ DEFINE_FPR(f4, 8, FPR_OFFSET(4)),
+ DEFINE_FPR(f5, 8, FPR_OFFSET(5)),
+ DEFINE_FPR(f6, 8, FPR_OFFSET(6)),
+ DEFINE_FPR(f7, 8, FPR_OFFSET(7)),
+ DEFINE_FPR(f8, 8, FPR_OFFSET(8)),
+ DEFINE_FPR(f9, 8, FPR_OFFSET(9)),
+ DEFINE_FPR(f10, 8, FPR_OFFSET(10)),
+ DEFINE_FPR(f11, 8, FPR_OFFSET(11)),
+ DEFINE_FPR(f12, 8, FPR_OFFSET(12)),
+ DEFINE_FPR(f13, 8, FPR_OFFSET(13)),
+ DEFINE_FPR(f14, 8, FPR_OFFSET(14)),
+ DEFINE_FPR(f15, 8, FPR_OFFSET(15)),
+ DEFINE_FPR_NODWARF(fpc, 4, 0),
+
+ // Linux operating-specific info.
+ DEFINE_GPR_NODWARF(orig_r2, 8, 16 + 16 * 8 + 16 * 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR_NODWARF(last_break, 8, 0, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR_NODWARF(system_call, 4, 0, nullptr, LLDB_INVALID_REGNUM),
+};
+
+static_assert((sizeof(g_register_infos_s390x) / sizeof(g_register_infos_s390x[0])) == k_num_registers_s390x,
+ "g_register_infos_s390x has wrong number of register infos");
+
+#undef GPR_OFFSET
+#undef ACR_OFFSET
+#undef FPR_OFFSET
+#undef DEFINE_GPR
+#undef DEFINE_GPR_NODWARF
+#undef DEFINE_FPR
+#undef DEFINE_FPR_NODWARF
+
+#endif // DECLARE_REGISTER_INFOS_S390X_STRUCT
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.cpp b/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 3bf766e875c9..7c0487b1d43b 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -507,6 +507,8 @@ StopInfoMachException::CreateStopReasonWithMachException
// report the breakpoint regardless of the thread.
if (bp_site_sp->ValidForThisThread (&thread) || thread.GetProcess()->GetOperatingSystem () != NULL)
return StopInfo::CreateStopReasonWithBreakpointSiteID (thread, bp_site_sp->GetID());
+ else if (is_trace_if_actual_breakpoint_missing)
+ return StopInfo::CreateStopReasonToTrace (thread);
else
return StopInfoSP();
}
diff --git a/source/Plugins/Process/Utility/lldb-s390x-register-enums.h b/source/Plugins/Process/Utility/lldb-s390x-register-enums.h
new file mode 100644
index 000000000000..174daa25e21b
--- /dev/null
+++ b/source/Plugins/Process/Utility/lldb-s390x-register-enums.h
@@ -0,0 +1,94 @@
+//===-- lldb-s390x-register-enums.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_s390x_register_enums_h
+#define lldb_s390x_register_enums_h
+
+namespace lldb_private
+{
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+
+//---------------------------------------------------------------------------
+// Internal codes for all s390x registers.
+//---------------------------------------------------------------------------
+enum
+{
+ k_first_gpr_s390x,
+ lldb_r0_s390x = k_first_gpr_s390x,
+ lldb_r1_s390x,
+ lldb_r2_s390x,
+ lldb_r3_s390x,
+ lldb_r4_s390x,
+ lldb_r5_s390x,
+ lldb_r6_s390x,
+ lldb_r7_s390x,
+ lldb_r8_s390x,
+ lldb_r9_s390x,
+ lldb_r10_s390x,
+ lldb_r11_s390x,
+ lldb_r12_s390x,
+ lldb_r13_s390x,
+ lldb_r14_s390x,
+ lldb_r15_s390x,
+ lldb_acr0_s390x,
+ lldb_acr1_s390x,
+ lldb_acr2_s390x,
+ lldb_acr3_s390x,
+ lldb_acr4_s390x,
+ lldb_acr5_s390x,
+ lldb_acr6_s390x,
+ lldb_acr7_s390x,
+ lldb_acr8_s390x,
+ lldb_acr9_s390x,
+ lldb_acr10_s390x,
+ lldb_acr11_s390x,
+ lldb_acr12_s390x,
+ lldb_acr13_s390x,
+ lldb_acr14_s390x,
+ lldb_acr15_s390x,
+ lldb_pswm_s390x,
+ lldb_pswa_s390x,
+ k_last_gpr_s390x = lldb_pswa_s390x,
+
+ k_first_fpr_s390x,
+ lldb_f0_s390x = k_first_fpr_s390x,
+ lldb_f1_s390x,
+ lldb_f2_s390x,
+ lldb_f3_s390x,
+ lldb_f4_s390x,
+ lldb_f5_s390x,
+ lldb_f6_s390x,
+ lldb_f7_s390x,
+ lldb_f8_s390x,
+ lldb_f9_s390x,
+ lldb_f10_s390x,
+ lldb_f11_s390x,
+ lldb_f12_s390x,
+ lldb_f13_s390x,
+ lldb_f14_s390x,
+ lldb_f15_s390x,
+ lldb_fpc_s390x,
+ k_last_fpr_s390x = lldb_fpc_s390x,
+
+ // These are only available on Linux.
+ k_first_linux_s390x,
+ lldb_orig_r2_s390x = k_first_linux_s390x,
+ lldb_last_break_s390x,
+ lldb_system_call_s390x,
+ k_last_linux_s390x = lldb_system_call_s390x,
+
+ k_num_registers_s390x,
+ k_num_gpr_registers_s390x = k_last_gpr_s390x - k_first_gpr_s390x + 1,
+ k_num_fpr_registers_s390x = k_last_fpr_s390x - k_first_fpr_s390x + 1,
+ k_num_linux_registers_s390x = k_last_linux_s390x - k_first_linux_s390x + 1,
+ k_num_user_registers_s390x = k_num_gpr_registers_s390x + k_num_fpr_registers_s390x,
+};
+}
+
+#endif // #ifndef lldb_s390x_register_enums_h
diff --git a/source/Plugins/Process/Windows/Common/NtStructures.h b/source/Plugins/Process/Windows/Common/NtStructures.h
new file mode 100644
index 000000000000..6c688d9068d5
--- /dev/null
+++ b/source/Plugins/Process/Windows/Common/NtStructures.h
@@ -0,0 +1,32 @@
+//===-- NtStructures.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Plugins_Process_Windows_Common_NtStructures_h_
+#define liblldb_Plugins_Process_Windows_Common_NtStructures_h_
+
+#include "lldb/Host/windows/windows.h"
+
+// This describes the layout of a TEB (Thread Environment Block) for a 64-bit
+// process. It's adapted from the 32-bit TEB in winternl.h. Currently, we care
+// only about the position of the TlsSlots.
+struct TEB64
+{
+ ULONG64 Reserved1[12];
+ ULONG64 ProcessEnvironmentBlock;
+ ULONG64 Reserved2[399];
+ BYTE Reserved3[1952];
+ ULONG64 TlsSlots[64];
+ BYTE Reserved4[8];
+ ULONG64 Reserved5[26];
+ ULONG64 ReservedForOle; // Windows 2000 only
+ ULONG64 Reserved6[4];
+ ULONG64 TlsExpansionSlots;
+};
+
+#endif
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index 0e6900d8fb7f..2c3f9fbecf92 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -29,8 +29,8 @@ namespace lldb_private
//------------------------------------------------------------------------------
// Constructors and destructors.
-ProcessWindows::ProcessWindows(lldb::TargetSP target_sp, Listener &listener)
- : lldb_private::Process(target_sp, listener)
+ProcessWindows::ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
+ : lldb_private::Process(target_sp, listener_sp)
{
}
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.h b/source/Plugins/Process/Windows/Common/ProcessWindows.h
index 2a437c0ca909..0ee42e2ae1f1 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.h
+++ b/source/Plugins/Process/Windows/Common/ProcessWindows.h
@@ -25,7 +25,7 @@ public:
// Constructors and destructors
//------------------------------------------------------------------
ProcessWindows(lldb::TargetSP target_sp,
- lldb_private::Listener &listener);
+ lldb::ListenerSP listener_sp);
~ProcessWindows();
diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
index 103cff4a2a56..3a9c31a0b776 100644
--- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
+++ b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
@@ -136,6 +136,8 @@ RegisterInfo g_register_infos[] = {
nullptr},
};
+static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+
// Array of lldb register numbers used to define the set of all General Purpose Registers
uint32_t g_gpr_reg_indices[] = {eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx, eRegisterIndexRdx,
eRegisterIndexRdi, eRegisterIndexRsi, eRegisterIndexR8, eRegisterIndexR9,
@@ -169,7 +171,9 @@ RegisterContextWindows_x64::GetRegisterCount()
const RegisterInfo *
RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg)
{
- return &g_register_infos[reg];
+ if (reg < k_num_register_infos)
+ return &g_register_infos[reg];
+ return NULL;
}
size_t
diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
index e57e1effec9c..11733eee7cb4 100644
--- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
+++ b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
@@ -64,6 +64,7 @@ RegisterInfo g_register_infos[] =
{ DEFINE_GPR(eip, "pc"), { ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, lldb_eip_i386 }, nullptr, nullptr},
{ DEFINE_GPR_BIN(eflags, "flags"), { ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, lldb_eflags_i386}, nullptr, nullptr},
};
+static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
// Array of lldb register numbers used to define the set of all General Purpose Registers
uint32_t g_gpr_reg_indices[] =
@@ -106,7 +107,9 @@ RegisterContextWindows_x86::GetRegisterCount()
const RegisterInfo *
RegisterContextWindows_x86::GetRegisterInfoAtIndex(size_t reg)
{
- return &g_register_infos[reg];
+ if (reg < k_num_register_infos)
+ return &g_register_infos[reg];
+ return NULL;
}
size_t
@@ -131,48 +134,42 @@ RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info, RegisterV
switch (reg)
{
case lldb_eax_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EAX", m_context.Eax);
- reg_value.SetUInt32(m_context.Eax);
- break;
+ return ReadRegisterHelper(CONTEXT_INTEGER, "EAX", m_context.Eax, reg_value);
case lldb_ebx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EBX", m_context.Ebx);
- reg_value.SetUInt32(m_context.Ebx);
- break;
+ return ReadRegisterHelper(CONTEXT_INTEGER, "EBX", m_context.Ebx, reg_value);
case lldb_ecx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from ECX", m_context.Ecx);
- reg_value.SetUInt32(m_context.Ecx);
- break;
+ return ReadRegisterHelper(CONTEXT_INTEGER, "ECX", m_context.Ecx, reg_value);
case lldb_edx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EDX", m_context.Edx);
- reg_value.SetUInt32(m_context.Edx);
- break;
+ return ReadRegisterHelper(CONTEXT_INTEGER, "EDX", m_context.Edx, reg_value);
case lldb_edi_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EDI", m_context.Edi);
- reg_value.SetUInt32(m_context.Edi);
- break;
+ return ReadRegisterHelper(CONTEXT_INTEGER, "EDI", m_context.Edi, reg_value);
case lldb_esi_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from ESI", m_context.Esi);
- reg_value.SetUInt32(m_context.Esi);
- break;
+ return ReadRegisterHelper(CONTEXT_INTEGER, "ESI", m_context.Esi, reg_value);
case lldb_ebp_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EBP", m_context.Ebp);
- reg_value.SetUInt32(m_context.Ebp);
- break;
+ return ReadRegisterHelper(CONTEXT_CONTROL, "EBP", m_context.Ebp, reg_value);
case lldb_esp_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from ESP", m_context.Esp);
- reg_value.SetUInt32(m_context.Esp);
- break;
+ return ReadRegisterHelper(CONTEXT_CONTROL, "ESP", m_context.Esp, reg_value);
case lldb_eip_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EIP", m_context.Eip);
- reg_value.SetUInt32(m_context.Eip);
- break;
+ return ReadRegisterHelper(CONTEXT_CONTROL, "EIP", m_context.Eip, reg_value);
case lldb_eflags_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EFLAGS", m_context.EFlags);
- reg_value.SetUInt32(m_context.EFlags);
- break;
+ return ReadRegisterHelper(CONTEXT_CONTROL, "EFLAGS", m_context.EFlags, reg_value);
default:
WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Requested unknown register %u", reg);
break;
}
+ return false;
+}
+
+bool
+RegisterContextWindows_x86::ReadRegisterHelper(DWORD flags_required, const char *reg_name, DWORD value,
+ RegisterValue &reg_value) const
+{
+ if ((m_context.ContextFlags & flags_required) != flags_required)
+ {
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Thread context doesn't have %s", reg_name);
+ return false;
+ }
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from %s", value, reg_name);
+ reg_value.SetUInt32(value);
return true;
}
diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h
index 7d854ef64a5c..6c29d54dcae2 100644
--- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h
+++ b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h
@@ -41,6 +41,9 @@ class RegisterContextWindows_x86 : public RegisterContextWindows
bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+private:
+ bool
+ ReadRegisterHelper(DWORD flags_required, const char *reg_name, DWORD value, RegisterValue &reg_value) const;
};
}
diff --git a/source/Plugins/Process/Windows/Live/DebuggerThread.cpp b/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
index d058a412c896..2823474cbd5e 100644
--- a/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
+++ b/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
@@ -27,6 +27,7 @@
#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/raw_ostream.h"
using namespace lldb;
@@ -378,7 +379,7 @@ DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thr
{
WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_PROCESS,
"Breakpoint exception is cue to detach from process 0x%x",
- m_pid_to_detach);
+ m_pid_to_detach.load());
::DebugActiveProcessStop(m_pid_to_detach);
m_detached = true;
}
@@ -484,13 +485,15 @@ DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread
return DBG_CONTINUE;
}
- std::vector<char> buffer(1);
- DWORD required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
+ std::vector<wchar_t> buffer(1);
+ DWORD required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
if (required_size > 0)
{
buffer.resize(required_size + 1);
- required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], required_size + 1, VOLUME_NAME_DOS);
- llvm::StringRef path_str(&buffer[0]);
+ required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], required_size, VOLUME_NAME_DOS);
+ std::string path_str_utf8;
+ llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
+ llvm::StringRef path_str = path_str_utf8;
const char *path = path_str.data();
if (path_str.startswith("\\\\?\\"))
path += 4;
diff --git a/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp b/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
index 855289d67bc7..300e0caa4378 100644
--- a/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
+++ b/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
@@ -47,6 +47,7 @@
#include "ProcessWindowsLive.h"
#include "TargetThreadWindowsLive.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -61,17 +62,19 @@ namespace
std::string
GetProcessExecutableName(HANDLE process_handle)
{
- std::vector<char> file_name;
+ std::vector<wchar_t> file_name;
DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit
DWORD copied = 0;
do
{
file_name_size *= 2;
file_name.resize(file_name_size);
- copied = ::GetModuleFileNameEx(process_handle, NULL, file_name.data(), file_name_size);
+ copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(), file_name_size);
} while (copied >= file_name_size);
file_name.resize(copied);
- return std::string(file_name.begin(), file_name.end());
+ std::string result;
+ llvm::convertWideToUTF8(file_name.data(), result);
+ return result;
}
std::string
@@ -121,9 +124,9 @@ class ProcessWindowsData
// Static functions.
ProcessSP
-ProcessWindowsLive::CreateInstance(lldb::TargetSP target_sp, Listener &listener, const FileSpec *)
+ProcessWindowsLive::CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *)
{
- return ProcessSP(new ProcessWindowsLive(target_sp, listener));
+ return ProcessSP(new ProcessWindowsLive(target_sp, listener_sp));
}
void
@@ -142,8 +145,8 @@ ProcessWindowsLive::Initialize()
//------------------------------------------------------------------------------
// Constructors and destructors.
-ProcessWindowsLive::ProcessWindowsLive(lldb::TargetSP target_sp, Listener &listener)
- : lldb_private::ProcessWindows(target_sp, listener)
+ProcessWindowsLive::ProcessWindowsLive(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
+ : lldb_private::ProcessWindows(target_sp, listener_sp)
{
}
@@ -189,7 +192,7 @@ ProcessWindowsLive::DisableBreakpointSite(BreakpointSite *bp_site)
{
WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS, "DisableBreakpointSite called with bp_site 0x%p "
"(id=%d, addr=0x%x)",
- bp_site->GetID(), bp_site->GetLoadAddress());
+ bp_site, bp_site->GetID(), bp_site->GetLoadAddress());
Error error = DisableSoftwareBreakpoint(bp_site);
@@ -554,11 +557,25 @@ ProcessWindowsLive::RefreshStateAfterStop()
{
case EXCEPTION_SINGLE_STEP:
{
- stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
- stop_thread->SetStopInfo(stop_info);
- WINLOG_IFANY(WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP, "RefreshStateAfterStop single stepping thread %u",
- stop_thread->GetID());
- stop_thread->SetStopInfo(stop_info);
+ RegisterContextSP register_context = stop_thread->GetRegisterContext();
+ const uint64_t pc = register_context->GetPC();
+ BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
+ if (site && site->ValidForThisThread(stop_thread.get()))
+ {
+ WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP,
+ "Single-stepped onto a breakpoint in process %I64u at "
+ "address 0x%I64x with breakpoint site %d",
+ m_session_data->m_debugger->GetProcess().GetProcessId(), pc, site->GetID());
+ stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread, site->GetID());
+ stop_thread->SetStopInfo(stop_info);
+ }
+ else
+ {
+ WINLOG_IFANY(WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP,
+ "RefreshStateAfterStop single stepping thread %u", stop_thread->GetID());
+ stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
+ stop_thread->SetStopInfo(stop_info);
+ }
return;
}
@@ -731,6 +748,7 @@ ProcessWindowsLive::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &
{
Error error;
llvm::sys::ScopedLock lock(m_mutex);
+ info.Clear();
if (!m_session_data)
{
@@ -738,7 +756,6 @@ ProcessWindowsLive::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &
WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString());
return error;
}
-
HostProcess process = m_session_data->m_debugger->GetProcess();
lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
if (handle == nullptr || handle == LLDB_INVALID_PROCESS)
@@ -755,22 +772,67 @@ ProcessWindowsLive::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &
SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
if (result == 0)
{
- error.SetError(::GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_MEMORY,
- "VirtualQueryEx returned error %u while getting memory region info for address 0x%I64x",
- error.GetError(), vm_addr);
- return error;
+ if (::GetLastError() == ERROR_INVALID_PARAMETER)
+ {
+ // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with an address
+ // past the highest accessible address. We should return a range from the vm_addr
+ // to LLDB_INVALID_ADDRESS
+ info.GetRange().SetRangeBase(vm_addr);
+ info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+ info.SetReadable(MemoryRegionInfo::eNo);
+ info.SetExecutable(MemoryRegionInfo::eNo);
+ info.SetWritable(MemoryRegionInfo::eNo);
+ info.SetMapped(MemoryRegionInfo::eNo);
+ return error;
+ }
+ else
+ {
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(WINDOWS_LOG_MEMORY,
+ "VirtualQueryEx returned error %u while getting memory region info for address 0x%I64x",
+ error.GetError(), vm_addr);
+ return error;
+ }
+ }
+
+ // Protect bits are only valid for MEM_COMMIT regions.
+ if (mem_info.State == MEM_COMMIT) {
+ const bool readable = IsPageReadable(mem_info.Protect);
+ const bool executable = IsPageExecutable(mem_info.Protect);
+ const bool writable = IsPageWritable(mem_info.Protect);
+ info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+ info.SetExecutable(executable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+ info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+ }
+ else
+ {
+ info.SetReadable(MemoryRegionInfo::eNo);
+ info.SetExecutable(MemoryRegionInfo::eNo);
+ info.SetWritable(MemoryRegionInfo::eNo);
+ }
+
+ // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
+ if (mem_info.State != MEM_FREE) {
+ info.GetRange().SetRangeBase(reinterpret_cast<addr_t>(mem_info.AllocationBase));
+ info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) + mem_info.RegionSize);
+ info.SetMapped(MemoryRegionInfo::eYes);
+ }
+ else
+ {
+ // In the unmapped case we need to return the distance to the next block of memory.
+ // VirtualQueryEx nearly does that except that it gives the distance from the start
+ // of the page containing vm_addr.
+ SYSTEM_INFO data;
+ GetSystemInfo(&data);
+ DWORD page_offset = vm_addr % data.dwPageSize;
+ info.GetRange().SetRangeBase(vm_addr);
+ info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
+ info.SetMapped(MemoryRegionInfo::eNo);
}
- const bool readable = IsPageReadable(mem_info.Protect);
- const bool executable = IsPageExecutable(mem_info.Protect);
- const bool writable = IsPageWritable(mem_info.Protect);
- info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetExecutable(executable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
error.SetError(::GetLastError(), eErrorTypeWin32);
WINLOGV_IFALL(WINDOWS_LOG_MEMORY, "Memory region info for address 0x%I64u: readable=%s, executable=%s, writable=%s",
- BOOL_STR(readable), BOOL_STR(executable), BOOL_STR(writable));
+ BOOL_STR(info.GetReadable()), BOOL_STR(info.GetExecutable()), BOOL_STR(info.GetWritable()));
return error;
}
@@ -803,7 +865,7 @@ ProcessWindowsLive::OnExitProcess(uint32_t exit_code)
target->ModulesDidUnload(unloaded_modules, true);
}
- SetProcessExitStatus(nullptr, GetID(), true, 0, exit_code);
+ SetProcessExitStatus(GetID(), true, 0, exit_code);
SetPrivateState(eStateExited);
}
diff --git a/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h b/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h
index 2429f873c823..657877f529b2 100644
--- a/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h
+++ b/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h
@@ -43,7 +43,7 @@ public:
//------------------------------------------------------------------
static lldb::ProcessSP
CreateInstance(lldb::TargetSP target_sp,
- lldb_private::Listener &listener,
+ lldb::ListenerSP listener_sp,
const lldb_private::FileSpec *);
static void
@@ -62,7 +62,7 @@ public:
// Constructors and destructors
//------------------------------------------------------------------
ProcessWindowsLive(lldb::TargetSP target_sp,
- lldb_private::Listener &listener);
+ lldb::ListenerSP listener_sp);
~ProcessWindowsLive();
diff --git a/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp b/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
index fbc96f085ed4..05839667688f 100644
--- a/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
+++ b/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
@@ -35,137 +35,131 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
+#include "Plugins/Process/Windows/Common/NtStructures.h"
+#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
+
#include "ExceptionRecord.h"
#include "ThreadWinMiniDump.h"
using namespace lldb_private;
-namespace
+// Implementation class for ProcessWinMiniDump encapsulates the Windows-specific
+// code, keeping non-portable types out of the header files.
+// TODO(amccarth): Determine if we need a mutex for access. Given that this is
+// postmortem debugging, I don't think so.
+class ProcessWinMiniDump::Impl
{
+public:
+ Impl(const FileSpec &core_file, ProcessWinMiniDump *self);
+ ~Impl();
-// Getting a string out of a mini dump is a chore. You're usually given a
-// relative virtual address (RVA), which points to a counted string that's in
-// Windows Unicode (UTF-16). This wrapper handles all the redirection and
-// returns a UTF-8 copy of the string.
-std::string
-GetMiniDumpString(const void *base_addr, const RVA rva)
-{
- std::string result;
- if (!base_addr)
+ Error
+ DoLoadCore();
+
+ bool
+ UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list);
+
+ void
+ RefreshStateAfterStop();
+
+ size_t
+ DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error);
+
+ Error
+ GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info);
+
+private:
+ // Describes a range of memory captured in the mini dump.
+ struct Range
{
- return result;
- }
- auto md_string = reinterpret_cast<const MINIDUMP_STRING *>(static_cast<const char *>(base_addr) + rva);
- auto source_start = reinterpret_cast<const UTF16 *>(md_string->Buffer);
- const auto source_length = ::wcslen(md_string->Buffer);
- const auto source_end = source_start + source_length;
- result.resize(4*source_length); // worst case length
- auto result_start = reinterpret_cast<UTF8 *>(&result[0]);
- const auto result_end = result_start + result.size();
- ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end, strictConversion);
- const auto result_size = std::distance(reinterpret_cast<UTF8 *>(&result[0]), result_start);
- result.resize(result_size); // shrink to actual length
- return result;
-}
+ lldb::addr_t start; // virtual address of the beginning of the range
+ size_t size; // size of the range in bytes
+ const uint8_t *ptr; // absolute pointer to the first byte of the range
+ };
-} // anonymous namespace
+ // If the mini dump has a memory range that contains the desired address, it
+ // returns true with the details of the range in *range_out. Otherwise, it
+ // returns false.
+ bool
+ FindMemoryRange(lldb::addr_t addr, Range *range_out) const;
-// Encapsulates the private data for ProcessWinMiniDump.
-// TODO(amccarth): Determine if we need a mutex for access.
-class ProcessWinMiniDump::Data
-{
-public:
- Data();
- ~Data();
+ lldb_private::Error
+ MapMiniDumpIntoMemory();
+ lldb_private::ArchSpec
+ DetermineArchitecture();
+
+ void
+ ReadExceptionRecord();
+
+ void
+ ReadMiscInfo();
+
+ void
+ ReadModuleList();
+
+ // A thin wrapper around WinAPI's MiniDumpReadDumpStream to avoid redundant
+ // checks. If there's a failure (e.g., if the requested stream doesn't exist),
+ // the function returns nullptr and sets *size_out to 0.
+ void *
+ FindDumpStream(unsigned stream_number, size_t *size_out) const;
+
+ // Getting a string out of a mini dump is a chore. You're usually given a
+ // relative virtual address (RVA), which points to a counted string that's in
+ // Windows Unicode (UTF-16). This wrapper handles all the redirection and
+ // returns a UTF-8 copy of the string.
+ std::string
+ GetMiniDumpString(RVA rva) const;
+
+ ProcessWinMiniDump *m_self; // non-owning back pointer
FileSpec m_core_file;
HANDLE m_dump_file; // handle to the open minidump file
HANDLE m_mapping; // handle to the file mapping for the minidump file
void * m_base_addr; // base memory address of the minidump
std::shared_ptr<ExceptionRecord> m_exception_sp;
+ bool m_is_wow64; // minidump is of a 32-bit process captured with a 64-bit debugger
};
-ConstString
-ProcessWinMiniDump::GetPluginNameStatic()
+ProcessWinMiniDump::Impl::Impl(const FileSpec &core_file, ProcessWinMiniDump *self)
+ : m_self(self),
+ m_core_file(core_file),
+ m_dump_file(INVALID_HANDLE_VALUE),
+ m_mapping(NULL),
+ m_base_addr(nullptr),
+ m_exception_sp(),
+ m_is_wow64(false)
{
- static ConstString g_name("win-minidump");
- return g_name;
}
-const char *
-ProcessWinMiniDump::GetPluginDescriptionStatic()
+ProcessWinMiniDump::Impl::~Impl()
{
- return "Windows minidump plug-in.";
-}
-
-void
-ProcessWinMiniDump::Terminate()
-{
- PluginManager::UnregisterPlugin(ProcessWinMiniDump::CreateInstance);
-}
-
-
-lldb::ProcessSP
-ProcessWinMiniDump::CreateInstance(lldb::TargetSP target_sp, Listener &listener, const FileSpec *crash_file)
-{
- lldb::ProcessSP process_sp;
- if (crash_file)
+ if (m_base_addr)
{
- process_sp.reset(new ProcessWinMiniDump(target_sp, listener, *crash_file));
+ ::UnmapViewOfFile(m_base_addr);
+ m_base_addr = nullptr;
+ }
+ if (m_mapping)
+ {
+ ::CloseHandle(m_mapping);
+ m_mapping = NULL;
+ }
+ if (m_dump_file != INVALID_HANDLE_VALUE)
+ {
+ ::CloseHandle(m_dump_file);
+ m_dump_file = INVALID_HANDLE_VALUE;
}
- return process_sp;
-}
-
-bool
-ProcessWinMiniDump::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- // TODO(amccarth): Eventually, this needs some actual logic.
- return true;
-}
-
-ProcessWinMiniDump::ProcessWinMiniDump(lldb::TargetSP target_sp, Listener &listener,
- const FileSpec &core_file) :
- ProcessWindows(target_sp, listener),
- m_data_up(new Data)
-{
- m_data_up->m_core_file = core_file;
-}
-
-ProcessWinMiniDump::~ProcessWinMiniDump()
-{
- Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
- Finalize();
-}
-
-ConstString
-ProcessWinMiniDump::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-ProcessWinMiniDump::GetPluginVersion()
-{
- return 1;
}
-
Error
-ProcessWinMiniDump::DoLoadCore()
+ProcessWinMiniDump::Impl::DoLoadCore()
{
- Error error;
-
- error = MapMiniDumpIntoMemory(m_data_up->m_core_file.GetCString());
+ Error error = MapMiniDumpIntoMemory();
if (error.Fail())
{
return error;
}
- GetTarget().SetArchitecture(DetermineArchitecture());
+ m_self->GetTarget().SetArchitecture(DetermineArchitecture());
ReadMiscInfo(); // notably for process ID
ReadModuleList();
ReadExceptionRecord();
@@ -174,16 +168,8 @@ ProcessWinMiniDump::DoLoadCore()
}
-DynamicLoader *
-ProcessWinMiniDump::GetDynamicLoader()
-{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, DynamicLoaderWindowsDYLD::GetPluginNameStatic().GetCString()));
- return m_dyld_ap.get();
-}
-
bool
-ProcessWinMiniDump::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
+ProcessWinMiniDump::Impl::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
{
size_t size = 0;
auto thread_list_ptr = static_cast<const MINIDUMP_THREAD_LIST *>(FindDumpStream(ThreadListStream, &size));
@@ -192,10 +178,50 @@ ProcessWinMiniDump::UpdateThreadList(ThreadList &old_thread_list, ThreadList &ne
const ULONG32 thread_count = thread_list_ptr->NumberOfThreads;
for (ULONG32 i = 0; i < thread_count; ++i) {
const auto &mini_dump_thread = thread_list_ptr->Threads[i];
- auto thread_sp = std::make_shared<ThreadWinMiniDump>(*this, mini_dump_thread.ThreadId);
+ auto thread_sp = std::make_shared<ThreadWinMiniDump>(*m_self, mini_dump_thread.ThreadId);
if (mini_dump_thread.ThreadContext.DataSize >= sizeof(CONTEXT))
{
- const CONTEXT *context = reinterpret_cast<const CONTEXT *>(static_cast<const char *>(m_data_up->m_base_addr) + mini_dump_thread.ThreadContext.Rva);
+ const CONTEXT *context = reinterpret_cast<const CONTEXT *>(static_cast<const char *>(m_base_addr) +
+ mini_dump_thread.ThreadContext.Rva);
+
+ if (m_is_wow64)
+ {
+ // On Windows, a 32-bit process can run on a 64-bit machine under WOW64.
+ // If the minidump was captured with a 64-bit debugger, then the CONTEXT
+ // we just grabbed from the mini_dump_thread is the one for the 64-bit
+ // "native" process rather than the 32-bit "guest" process we care about.
+ // In this case, we can get the 32-bit CONTEXT from the TEB (Thread
+ // Environment Block) of the 64-bit process.
+ Error error;
+ TEB64 wow64teb = {0};
+ m_self->ReadMemory(mini_dump_thread.Teb, &wow64teb, sizeof(wow64teb), error);
+ if (error.Success())
+ {
+ // Slot 1 of the thread-local storage in the 64-bit TEB points to a structure
+ // that includes the 32-bit CONTEXT (after a ULONG).
+ // See: https://msdn.microsoft.com/en-us/library/ms681670.aspx
+ const size_t addr = wow64teb.TlsSlots[1];
+ Range range = {0};
+ if (FindMemoryRange(addr, &range))
+ {
+ lldbassert(range.start <= addr);
+ const size_t offset = addr - range.start + sizeof(ULONG);
+ if (offset < range.size)
+ {
+ const size_t overlap = range.size - offset;
+ if (overlap >= sizeof(CONTEXT))
+ {
+ context = reinterpret_cast<const CONTEXT *>(range.ptr + offset);
+ }
+ }
+ }
+ }
+
+ // NOTE: We don't currently use the TEB for anything else. If we need it in
+ // the future, the 32-bit TEB is located according to the address stored in the
+ // first slot of the 64-bit TEB (wow64teb.Reserved1[0]).
+ }
+
thread_sp->SetContext(context);
}
new_thread_list.AddThread(thread_sp);
@@ -206,54 +232,24 @@ ProcessWinMiniDump::UpdateThreadList(ThreadList &old_thread_list, ThreadList &ne
}
void
-ProcessWinMiniDump::RefreshStateAfterStop()
+ProcessWinMiniDump::Impl::RefreshStateAfterStop()
{
- if (!m_data_up) return;
- if (!m_data_up->m_exception_sp) return;
+ if (!m_exception_sp)
+ return;
- auto active_exception = m_data_up->m_exception_sp;
+ auto active_exception = m_exception_sp;
std::string desc;
llvm::raw_string_ostream desc_stream(desc);
- desc_stream << "Exception "
- << llvm::format_hex(active_exception->GetExceptionCode(), 8)
- << " encountered at address "
- << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
- m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
- auto stop_thread = m_thread_list.GetSelectedThread();
+ desc_stream << "Exception " << llvm::format_hex(active_exception->GetExceptionCode(), 8)
+ << " encountered at address " << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
+ m_self->m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
+ auto stop_thread = m_self->m_thread_list.GetSelectedThread();
auto stop_info = StopInfo::CreateStopReasonWithException(*stop_thread, desc_stream.str().c_str());
stop_thread->SetStopInfo(stop_info);
}
-Error
-ProcessWinMiniDump::DoDestroy()
-{
- return Error();
-}
-
-bool
-ProcessWinMiniDump::IsAlive()
-{
- return true;
-}
-
-bool
-ProcessWinMiniDump::WarnBeforeDetach () const
-{
- // Since this is post-mortem debugging, there's no need to warn the user
- // that quitting the debugger will terminate the process.
- return false;
-}
-
size_t
-ProcessWinMiniDump::ReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
-{
- // Don't allow the caching that lldb_private::Process::ReadMemory does
- // since we have it all cached our our dump file anyway.
- return DoReadMemory(addr, buf, size, error);
-}
-
-size_t
-ProcessWinMiniDump::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
+ProcessWinMiniDump::Impl::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
{
// I don't have a sense of how frequently this is called or how many memory
// ranges a mini dump typically has, so I'm not sure if searching for the
@@ -277,10 +273,11 @@ ProcessWinMiniDump::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Erro
}
Error
-ProcessWinMiniDump::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info)
+ProcessWinMiniDump::Impl::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info)
{
Error error;
size_t size;
+ info.Clear();
const auto list = reinterpret_cast<const MINIDUMP_MEMORY_INFO_LIST *>(FindDumpStream(MemoryInfoListStream, &size));
if (list == nullptr || size < sizeof(MINIDUMP_MEMORY_INFO_LIST))
{
@@ -300,6 +297,8 @@ ProcessWinMiniDump::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::Me
return error;
}
+ const MINIDUMP_MEMORY_INFO *next_entry = nullptr;
+
for (int i = 0; i < list->NumberOfEntries; ++i)
{
const auto entry = reinterpret_cast<const MINIDUMP_MEMORY_INFO *>(reinterpret_cast<const char *>(list) +
@@ -308,80 +307,46 @@ ProcessWinMiniDump::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::Me
const auto tail = head + entry->RegionSize;
if (head <= load_addr && load_addr < tail)
{
+ info.GetRange().SetRangeBase((entry->State != MEM_FREE) ? head : load_addr);
+ info.GetRange().SetRangeEnd(tail);
info.SetReadable(IsPageReadable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
info.SetWritable(IsPageWritable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
info.SetExecutable(IsPageExecutable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+ info.SetMapped((entry->State != MEM_FREE) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
return error;
}
+ else if (head > load_addr && (next_entry == nullptr || head < next_entry->BaseAddress) )
+ {
+ // In case there is no region containing load_addr keep track of the nearest region
+ // after load_addr so we can return the distance to it.
+ next_entry = entry;
+ }
}
+
+ // No containing region found. Create an unmapped region that extends to the next region
+ // or LLDB_INVALID_ADDRESS
+ info.GetRange().SetRangeBase(load_addr);
+ info.GetRange().SetRangeEnd((next_entry != nullptr)?next_entry->BaseAddress:LLDB_INVALID_ADDRESS);
+ info.SetReadable(MemoryRegionInfo::eNo);
+ info.SetWritable(MemoryRegionInfo::eNo);
+ info.SetExecutable(MemoryRegionInfo::eNo);
+ info.SetMapped(MemoryRegionInfo::eNo);
+
// Note that the memory info list doesn't seem to contain ranges in kernel space,
// so if you're walking a stack that has kernel frames, the stack may appear
// truncated.
- error.SetErrorString("address is not in a known range");
return error;
}
-void
-ProcessWinMiniDump::Clear()
-{
- m_thread_list.Clear();
-}
-
-void
-ProcessWinMiniDump::Initialize()
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []()
- {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
- });
-}
-
-ArchSpec
-ProcessWinMiniDump::GetArchitecture()
-{
- // TODO
- return ArchSpec();
-}
-
-
-ProcessWinMiniDump::Data::Data() :
- m_dump_file(INVALID_HANDLE_VALUE),
- m_mapping(NULL),
- m_base_addr(nullptr)
-{
-}
-
-ProcessWinMiniDump::Data::~Data()
-{
- if (m_base_addr)
- {
- ::UnmapViewOfFile(m_base_addr);
- m_base_addr = nullptr;
- }
- if (m_mapping)
- {
- ::CloseHandle(m_mapping);
- m_mapping = NULL;
- }
- if (m_dump_file != INVALID_HANDLE_VALUE)
- {
- ::CloseHandle(m_dump_file);
- m_dump_file = INVALID_HANDLE_VALUE;
- }
-}
-
bool
-ProcessWinMiniDump::FindMemoryRange(lldb::addr_t addr, Range *range_out) const
+ProcessWinMiniDump::Impl::FindMemoryRange(lldb::addr_t addr, Range *range_out) const
{
size_t stream_size = 0;
auto mem_list_stream = static_cast<const MINIDUMP_MEMORY_LIST *>(FindDumpStream(MemoryListStream, &stream_size));
if (mem_list_stream)
{
- for (ULONG32 i = 0; i < mem_list_stream->NumberOfMemoryRanges; ++i) {
+ for (ULONG32 i = 0; i < mem_list_stream->NumberOfMemoryRanges; ++i)
+ {
const MINIDUMP_MEMORY_DESCRIPTOR &mem_desc = mem_list_stream->MemoryRanges[i];
const MINIDUMP_LOCATION_DESCRIPTOR &loc_desc = mem_desc.Memory;
const lldb::addr_t range_start = mem_desc.StartOfMemoryRange;
@@ -390,7 +355,7 @@ ProcessWinMiniDump::FindMemoryRange(lldb::addr_t addr, Range *range_out) const
{
range_out->start = range_start;
range_out->size = range_size;
- range_out->ptr = reinterpret_cast<const uint8_t *>(m_data_up->m_base_addr) + loc_desc.Rva;
+ range_out->ptr = reinterpret_cast<const uint8_t *>(m_base_addr) + loc_desc.Rva;
return true;
}
}
@@ -411,7 +376,7 @@ ProcessWinMiniDump::FindMemoryRange(lldb::addr_t addr, Range *range_out) const
{
range_out->start = range_start;
range_out->size = range_size;
- range_out->ptr = reinterpret_cast<const uint8_t *>(m_data_up->m_base_addr) + base_rva;
+ range_out->ptr = reinterpret_cast<const uint8_t *>(m_base_addr) + base_rva;
return true;
}
base_rva += range_size;
@@ -421,31 +386,34 @@ ProcessWinMiniDump::FindMemoryRange(lldb::addr_t addr, Range *range_out) const
return false;
}
-
Error
-ProcessWinMiniDump::MapMiniDumpIntoMemory(const char *file)
+ProcessWinMiniDump::Impl::MapMiniDumpIntoMemory()
{
Error error;
-
- m_data_up->m_dump_file = ::CreateFile(file, GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (m_data_up->m_dump_file == INVALID_HANDLE_VALUE)
+ const char *file = m_core_file.GetCString();
+ std::wstring wfile;
+ if (!llvm::ConvertUTF8toWide(file, wfile))
+ {
+ error.SetErrorString("Error converting path to UTF-16");
+ return error;
+ }
+ m_dump_file =
+ ::CreateFileW(wfile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (m_dump_file == INVALID_HANDLE_VALUE)
{
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
}
- m_data_up->m_mapping = ::CreateFileMapping(m_data_up->m_dump_file, NULL,
- PAGE_READONLY, 0, 0, NULL);
- if (m_data_up->m_mapping == NULL)
+ m_mapping = ::CreateFileMappingW(m_dump_file, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (m_mapping == NULL)
{
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
}
- m_data_up->m_base_addr = ::MapViewOfFile(m_data_up->m_mapping, FILE_MAP_READ, 0, 0, 0);
- if (m_data_up->m_base_addr == NULL)
+ m_base_addr = ::MapViewOfFile(m_mapping, FILE_MAP_READ, 0, 0, 0);
+ if (m_base_addr == nullptr)
{
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
@@ -454,9 +422,8 @@ ProcessWinMiniDump::MapMiniDumpIntoMemory(const char *file)
return error;
}
-
ArchSpec
-ProcessWinMiniDump::DetermineArchitecture()
+ProcessWinMiniDump::Impl::DetermineArchitecture()
{
size_t size = 0;
auto system_info_ptr = static_cast<const MINIDUMP_SYSTEM_INFO *>(FindDumpStream(SystemInfoStream, &size));
@@ -465,9 +432,17 @@ ProcessWinMiniDump::DetermineArchitecture()
switch (system_info_ptr->ProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_INTEL:
- return ArchSpec(eArchTypeCOFF, IMAGE_FILE_MACHINE_I386, LLDB_INVALID_CPUTYPE);
+ if (system_info_ptr->ProcessorLevel == 6)
+ {
+ return ArchSpec("i686-pc-windows");
+ }
+ else
+ {
+ return ArchSpec("i386-pc-windows");
+ }
+ break;
case PROCESSOR_ARCHITECTURE_AMD64:
- return ArchSpec(eArchTypeCOFF, IMAGE_FILE_MACHINE_AMD64, LLDB_INVALID_CPUTYPE);
+ return ArchSpec("x86_64-pc-windows");
default:
break;
}
@@ -477,18 +452,24 @@ ProcessWinMiniDump::DetermineArchitecture()
}
void
-ProcessWinMiniDump::ReadExceptionRecord()
+ProcessWinMiniDump::Impl::ReadExceptionRecord()
{
size_t size = 0;
auto exception_stream_ptr = static_cast<MINIDUMP_EXCEPTION_STREAM*>(FindDumpStream(ExceptionStream, &size));
if (exception_stream_ptr)
{
- m_data_up->m_exception_sp.reset(new ExceptionRecord(exception_stream_ptr->ExceptionRecord, exception_stream_ptr->ThreadId));
+ m_exception_sp.reset(
+ new ExceptionRecord(exception_stream_ptr->ExceptionRecord, exception_stream_ptr->ThreadId));
+ }
+ else
+ {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Minidump has no exception record.");
+ // TODO: See if we can recover the exception from the TEB.
}
}
void
-ProcessWinMiniDump::ReadMiscInfo()
+ProcessWinMiniDump::Impl::ReadMiscInfo()
{
size_t size = 0;
const auto misc_info_ptr = static_cast<MINIDUMP_MISC_INFO*>(FindDumpStream(MiscInfoStream, &size));
@@ -498,12 +479,12 @@ ProcessWinMiniDump::ReadMiscInfo()
if ((misc_info_ptr->Flags1 & MINIDUMP_MISC1_PROCESS_ID) != 0) {
// This misc info record has the process ID.
- SetID(misc_info_ptr->ProcessId);
+ m_self->SetID(misc_info_ptr->ProcessId);
}
}
void
-ProcessWinMiniDump::ReadModuleList()
+ProcessWinMiniDump::Impl::ReadModuleList()
{
size_t size = 0;
auto module_list_ptr = static_cast<MINIDUMP_MODULE_LIST*>(FindDumpStream(ModuleListStream, &size));
@@ -515,36 +496,215 @@ ProcessWinMiniDump::ReadModuleList()
for (ULONG32 i = 0; i < module_list_ptr->NumberOfModules; ++i)
{
const auto &module = module_list_ptr->Modules[i];
- const auto file_name = GetMiniDumpString(m_data_up->m_base_addr, module.ModuleNameRva);
- ModuleSpec module_spec = FileSpec(file_name, true);
+ const auto file_name = GetMiniDumpString(module.ModuleNameRva);
+ const auto file_spec = FileSpec(file_name, true);
+ if (FileSpec::Compare(file_spec, FileSpec("wow64.dll", false), false) == 0)
+ {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Minidump is for a WOW64 process.");
+ m_is_wow64 = true;
+ }
+ ModuleSpec module_spec = file_spec;
- lldb::ModuleSP module_sp = GetTarget().GetSharedModule(module_spec);
+ lldb::ModuleSP module_sp = m_self->GetTarget().GetSharedModule(module_spec);
if (!module_sp)
{
continue;
}
bool load_addr_changed = false;
- module_sp->SetLoadAddress(GetTarget(), module.BaseOfImage, false, load_addr_changed);
+ module_sp->SetLoadAddress(m_self->GetTarget(), module.BaseOfImage, false, load_addr_changed);
}
}
void *
-ProcessWinMiniDump::FindDumpStream(unsigned stream_number, size_t *size_out) const
+ProcessWinMiniDump::Impl::FindDumpStream(unsigned stream_number, size_t *size_out) const
{
void *stream = nullptr;
*size_out = 0;
- assert(m_data_up != nullptr);
- assert(m_data_up->m_base_addr != 0);
-
MINIDUMP_DIRECTORY *dir = nullptr;
- if (::MiniDumpReadDumpStream(m_data_up->m_base_addr, stream_number, &dir, nullptr, nullptr) &&
- dir != nullptr && dir->Location.DataSize > 0)
+ if (::MiniDumpReadDumpStream(m_base_addr, stream_number, &dir, nullptr, nullptr) && dir != nullptr &&
+ dir->Location.DataSize > 0)
{
assert(dir->StreamType == stream_number);
*size_out = dir->Location.DataSize;
- stream = static_cast<void*>(static_cast<char*>(m_data_up->m_base_addr) + dir->Location.Rva);
+ stream = static_cast<void *>(static_cast<char *>(m_base_addr) + dir->Location.Rva);
}
return stream;
}
+
+std::string
+ProcessWinMiniDump::Impl::GetMiniDumpString(RVA rva) const
+{
+ std::string result;
+ if (!m_base_addr)
+ {
+ return result;
+ }
+ auto md_string = reinterpret_cast<const MINIDUMP_STRING *>(static_cast<const char *>(m_base_addr) + rva);
+ auto source_start = reinterpret_cast<const UTF16 *>(md_string->Buffer);
+ const auto source_length = ::wcslen(md_string->Buffer);
+ const auto source_end = source_start + source_length;
+ result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT * source_length); // worst case length
+ auto result_start = reinterpret_cast<UTF8 *>(&result[0]);
+ const auto result_end = result_start + result.size();
+ ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end, strictConversion);
+ const auto result_size = std::distance(reinterpret_cast<UTF8 *>(&result[0]), result_start);
+ result.resize(result_size); // shrink to actual length
+ return result;
+}
+
+ConstString
+ProcessWinMiniDump::GetPluginNameStatic()
+{
+ static ConstString g_name("win-minidump");
+ return g_name;
+}
+
+const char *
+ProcessWinMiniDump::GetPluginDescriptionStatic()
+{
+ return "Windows minidump plug-in.";
+}
+
+void
+ProcessWinMiniDump::Terminate()
+{
+ PluginManager::UnregisterPlugin(ProcessWinMiniDump::CreateInstance);
+}
+
+lldb::ProcessSP
+ProcessWinMiniDump::CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file)
+{
+ lldb::ProcessSP process_sp;
+ if (crash_file)
+ {
+ process_sp.reset(new ProcessWinMiniDump(target_sp, listener_sp, *crash_file));
+ }
+ return process_sp;
+}
+
+bool
+ProcessWinMiniDump::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
+{
+ // TODO(amccarth): Eventually, this needs some actual logic.
+ return true;
+}
+
+ProcessWinMiniDump::ProcessWinMiniDump(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec &core_file)
+ : ProcessWindows(target_sp, listener_sp), m_impl_up(new Impl(core_file, this))
+{
+}
+
+ProcessWinMiniDump::~ProcessWinMiniDump()
+{
+ Clear();
+ // We need to call finalize on the process before destroying ourselves
+ // to make sure all of the broadcaster cleanup goes as planned. If we
+ // destruct this class, then Process::~Process() might have problems
+ // trying to fully destroy the broadcaster.
+ Finalize();
+}
+
+ConstString
+ProcessWinMiniDump::GetPluginName()
+{
+ return GetPluginNameStatic();
+}
+
+uint32_t
+ProcessWinMiniDump::GetPluginVersion()
+{
+ return 1;
+}
+
+Error
+ProcessWinMiniDump::DoLoadCore()
+{
+ return m_impl_up->DoLoadCore();
+}
+
+DynamicLoader *
+ProcessWinMiniDump::GetDynamicLoader()
+{
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(this, DynamicLoaderWindowsDYLD::GetPluginNameStatic().GetCString()));
+ return m_dyld_ap.get();
+}
+
+bool
+ProcessWinMiniDump::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
+{
+ return m_impl_up->UpdateThreadList(old_thread_list, new_thread_list);
+}
+
+void
+ProcessWinMiniDump::RefreshStateAfterStop()
+{
+ if (!m_impl_up)
+ return;
+ return m_impl_up->RefreshStateAfterStop();
+}
+
+Error
+ProcessWinMiniDump::DoDestroy()
+{
+ return Error();
+}
+
+bool
+ProcessWinMiniDump::IsAlive()
+{
+ return true;
+}
+
+bool
+ProcessWinMiniDump::WarnBeforeDetach() const
+{
+ // Since this is post-mortem debugging, there's no need to warn the user
+ // that quitting the debugger will terminate the process.
+ return false;
+}
+
+size_t
+ProcessWinMiniDump::ReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
+{
+ // Don't allow the caching that lldb_private::Process::ReadMemory does
+ // since we have it all cached our our dump file anyway.
+ return DoReadMemory(addr, buf, size, error);
+}
+
+size_t
+ProcessWinMiniDump::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
+{
+ return m_impl_up->DoReadMemory(addr, buf, size, error);
+}
+
+Error
+ProcessWinMiniDump::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info)
+{
+ return m_impl_up->GetMemoryRegionInfo(load_addr, info);
+}
+
+void
+ProcessWinMiniDump::Clear()
+{
+ m_thread_list.Clear();
+}
+
+void
+ProcessWinMiniDump::Initialize()
+{
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance);
+ });
+}
+
+ArchSpec
+ProcessWinMiniDump::GetArchitecture()
+{
+ // TODO
+ return ArchSpec();
+}
diff --git a/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h b/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
index 12864be37127..3e1ac4bffbe3 100644
--- a/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
+++ b/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
@@ -26,7 +26,7 @@ class ProcessWinMiniDump : public lldb_private::ProcessWindows
public:
static lldb::ProcessSP
CreateInstance (lldb::TargetSP target_sp,
- lldb_private::Listener &listener,
+ lldb::ListenerSP listener_sp,
const lldb_private::FileSpec *crash_file_path);
static void
@@ -42,7 +42,7 @@ class ProcessWinMiniDump : public lldb_private::ProcessWindows
GetPluginDescriptionStatic();
ProcessWinMiniDump(lldb::TargetSP target_sp,
- lldb_private::Listener &listener,
+ lldb::ListenerSP listener_sp,
const lldb_private::FileSpec &core_file);
virtual
@@ -96,45 +96,9 @@ class ProcessWinMiniDump : public lldb_private::ProcessWindows
lldb_private::ThreadList &new_thread_list) override;
private:
- // Describes a range of memory captured in the mini dump.
- struct Range {
- lldb::addr_t start; // virtual address of the beginning of the range
- size_t size; // size of the range in bytes
- const uint8_t *ptr; // absolute pointer to the first byte of the range
- };
-
- // If the mini dump has a memory range that contains the desired address, it
- // returns true with the details of the range in *range_out. Otherwise, it
- // returns false.
- bool
- FindMemoryRange(lldb::addr_t addr, Range *range_out) const;
-
- lldb_private::Error
- MapMiniDumpIntoMemory(const char *file);
-
- lldb_private::ArchSpec
- DetermineArchitecture();
-
- void
- ReadExceptionRecord();
-
- void
- ReadMiscInfo();
-
- void
- ReadModuleList();
-
- // A thin wrapper around WinAPI's MiniDumpReadDumpStream to avoid redundant
- // checks. If there's a failure (e.g., if the requested stream doesn't exist),
- // the function returns nullptr and sets *size_out to 0.
- void *
- FindDumpStream(unsigned stream_number, size_t *size_out) const;
-
- // Isolate the data to keep Windows-specific types out of this header. Can't
- // use the typical pimpl idiom because the implementation of this class also
- // needs access to public and protected members of the base class.
- class Data;
- std::unique_ptr<Data> m_data_up;
+ // Keep Windows-specific types out of this header.
+ class Impl;
+ std::unique_ptr<Impl> m_impl_up;
};
#endif // liblldb_ProcessWinMiniDump_h_
diff --git a/source/Plugins/Process/elf-core/CMakeLists.txt b/source/Plugins/Process/elf-core/CMakeLists.txt
index 1a4dd7e9d333..b9f0b6cdfb7c 100644
--- a/source/Plugins/Process/elf-core/CMakeLists.txt
+++ b/source/Plugins/Process/elf-core/CMakeLists.txt
@@ -7,5 +7,6 @@ add_lldb_library(lldbPluginProcessElfCore
RegisterContextPOSIXCore_arm64.cpp
RegisterContextPOSIXCore_mips64.cpp
RegisterContextPOSIXCore_powerpc.cpp
+ RegisterContextPOSIXCore_s390x.cpp
RegisterContextPOSIXCore_x86_64.cpp
)
diff --git a/source/Plugins/Process/elf-core/Makefile b/source/Plugins/Process/elf-core/Makefile
deleted file mode 100644
index 8c5b3b800f5a..000000000000
--- a/source/Plugins/Process/elf-core/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Process/elf-core/Makefile -----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginProcessElfCore
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 5b5d98a86d5e..a729d2beee77 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -14,15 +14,16 @@
#include <mutex>
// Other libraries and framework includes
-#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/State.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
#include "llvm/Support/ELF.h"
@@ -57,7 +58,7 @@ ProcessElfCore::Terminate()
lldb::ProcessSP
-ProcessElfCore::CreateInstance (lldb::TargetSP target_sp, Listener &listener, const FileSpec *crash_file)
+ProcessElfCore::CreateInstance (lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file)
{
lldb::ProcessSP process_sp;
if (crash_file)
@@ -75,7 +76,7 @@ ProcessElfCore::CreateInstance (lldb::TargetSP target_sp, Listener &listener, co
if (elf_header.Parse(data, &data_offset))
{
if (elf_header.e_type == llvm::ELF::ET_CORE)
- process_sp.reset(new ProcessElfCore (target_sp, listener, *crash_file));
+ process_sp.reset(new ProcessElfCore (target_sp, listener_sp, *crash_file));
}
}
}
@@ -104,9 +105,9 @@ ProcessElfCore::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name
//----------------------------------------------------------------------
// ProcessElfCore constructor
//----------------------------------------------------------------------
-ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp, Listener &listener,
+ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
const FileSpec &core_file) :
- Process (target_sp, listener),
+ Process (target_sp, listener_sp),
m_core_module_sp (),
m_core_file (core_file),
m_dyld_plugin_name (),
@@ -148,7 +149,7 @@ ProcessElfCore::GetPluginVersion()
lldb::addr_t
ProcessElfCore::AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header)
{
- lldb::addr_t addr = header->p_vaddr;
+ const lldb::addr_t addr = header->p_vaddr;
FileRange file_range (header->p_offset, header->p_filesz);
VMRangeToFileOffset::Entry range_entry(addr, header->p_memsz, file_range);
@@ -166,6 +167,14 @@ ProcessElfCore::AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *head
m_core_aranges.Append(range_entry);
}
+ // Keep a separate map of permissions that that isn't coalesced so all ranges
+ // are maintained.
+ const uint32_t permissions = ((header->p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0) |
+ ((header->p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0) |
+ ((header->p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0);
+
+ m_core_range_infos.Append(VMRangeToPermissions::Entry(addr, header->p_memsz, permissions));
+
return addr;
}
@@ -227,7 +236,10 @@ ProcessElfCore::DoLoadCore ()
}
if (!ranges_are_sorted)
+ {
m_core_aranges.Sort();
+ m_core_range_infos.Sort();
+ }
// Even if the architecture is set in the target, we need to override
// it to match the core file which is always single arch.
@@ -315,6 +327,47 @@ ProcessElfCore::ReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &er
return DoReadMemory (addr, buf, size, error);
}
+Error
+ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &region_info)
+{
+ region_info.Clear();
+ const VMRangeToPermissions::Entry *permission_entry = m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
+ if (permission_entry)
+ {
+ if (permission_entry->Contains(load_addr))
+ {
+ region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
+ region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
+ const Flags permissions(permission_entry->data);
+ region_info.SetReadable(permissions.Test(lldb::ePermissionsReadable) ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetWritable(permissions.Test(lldb::ePermissionsWritable) ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetExecutable(permissions.Test(lldb::ePermissionsExecutable) ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eYes);
+ }
+ else if (load_addr < permission_entry->GetRangeBase())
+ {
+ region_info.GetRange().SetRangeBase(load_addr);
+ region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
+ }
+ return Error();
+ }
+
+ region_info.GetRange().SetRangeBase(load_addr);
+ region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
+ return Error();
+}
+
size_t
ProcessElfCore::DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
{
@@ -517,7 +570,7 @@ ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *
size_t note_start, note_size;
note_start = offset;
- note_size = llvm::RoundUpToAlignment(note.n_descsz, 4);
+ note_size = llvm::alignTo(note.n_descsz, 4);
// Store the NOTE information in the current thread
DataExtractor note_data (segment_data, note_start, note_size);
@@ -559,11 +612,10 @@ ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *
have_prstatus = true;
prstatus.Parse(note_data, arch);
thread_data->signo = prstatus.pr_cursig;
+ thread_data->tid = prstatus.pr_pid;
header_size = ELFLinuxPrStatus::GetSize(arch);
len = note_data.GetByteSize() - header_size;
thread_data->gpregset = DataExtractor(note_data, header_size, len);
- // FIXME: Obtain actual tid on Linux
- thread_data->tid = m_thread_data.size();
break;
case NT_FPREGSET:
thread_data->fpregset = note_data;
@@ -572,6 +624,7 @@ ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *
have_prpsinfo = true;
prpsinfo.Parse(note_data, arch);
thread_data->name = prpsinfo.pr_fname;
+ SetID(prpsinfo.pr_pid);
break;
case NT_AUXV:
m_auxv = DataExtractor(note_data);
@@ -637,3 +690,18 @@ ProcessElfCore::GetAuxvData()
lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));
return buffer;
}
+
+bool
+ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info)
+{
+ info.Clear();
+ info.SetProcessID(GetID());
+ info.SetArchitecture(GetArchitecture());
+ lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
+ if (module_sp)
+ {
+ const bool add_exe_file_as_first_arg = false;
+ info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(), add_exe_file_as_first_arg);
+ }
+ return true;
+}
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.h b/source/Plugins/Process/elf-core/ProcessElfCore.h
index 12ce04c5ce38..4bcbb363d3f8 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -40,7 +40,7 @@ public:
//------------------------------------------------------------------
static lldb::ProcessSP
CreateInstance (lldb::TargetSP target_sp,
- lldb_private::Listener &listener,
+ lldb::ListenerSP listener_sp,
const lldb_private::FileSpec *crash_file_path);
static void
@@ -59,7 +59,7 @@ public:
// Constructors and Destructors
//------------------------------------------------------------------
ProcessElfCore(lldb::TargetSP target_sp,
- lldb_private::Listener &listener,
+ lldb::ListenerSP listener_sp,
const lldb_private::FileSpec &core_file);
~ProcessElfCore() override;
@@ -102,6 +102,9 @@ public:
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
+ lldb_private::Error
+ GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &region_info) override;
+
lldb::addr_t GetImageInfoAddress() override;
lldb_private::ArchSpec
@@ -111,6 +114,9 @@ public:
const lldb::DataBufferSP
GetAuxvData() override;
+ bool
+ GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override;
+
protected:
void
Clear ( );
@@ -132,6 +138,7 @@ private:
//------------------------------------------------------------------
typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1> VMRangeToFileOffset;
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> VMRangeToPermissions;
lldb::ModuleSP m_core_module_sp;
lldb_private::FileSpec m_core_file;
@@ -152,6 +159,9 @@ private:
// Address ranges found in the core
VMRangeToFileOffset m_core_aranges;
+ // Permissions for all ranges
+ VMRangeToPermissions m_core_range_infos;
+
// NT_FILE entries found from the NOTE segment
std::vector<NT_FILE_Entry> m_nt_file_entries;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
new file mode 100644
index 000000000000..d2f0a8dd3671
--- /dev/null
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
@@ -0,0 +1,115 @@
+//===-- RegisterContextCorePOSIX_s390x.cpp ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Target/Thread.h"
+#include "RegisterContextPOSIXCore_s390x.h"
+
+using namespace lldb_private;
+
+RegisterContextCorePOSIX_s390x::RegisterContextCorePOSIX_s390x(Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset,
+ const DataExtractor &fpregset)
+ : RegisterContextPOSIX_s390x(thread, 0, register_info)
+{
+ m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+ m_fpr_buffer.reset(new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
+ m_fpr.SetData(m_fpr_buffer);
+ m_fpr.SetByteOrder(fpregset.GetByteOrder());
+}
+
+RegisterContextCorePOSIX_s390x::~RegisterContextCorePOSIX_s390x()
+{
+}
+
+bool
+RegisterContextCorePOSIX_s390x::ReadGPR()
+{
+ return true;
+}
+
+bool
+RegisterContextCorePOSIX_s390x::ReadFPR()
+{
+ return true;
+}
+
+bool
+RegisterContextCorePOSIX_s390x::WriteGPR()
+{
+ assert(0);
+ return false;
+}
+
+bool
+RegisterContextCorePOSIX_s390x::WriteFPR()
+{
+ assert(0);
+ return false;
+}
+
+bool
+RegisterContextCorePOSIX_s390x::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
+{
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM)
+ return false;
+
+ if (IsGPR(reg))
+ {
+ lldb::offset_t offset = reg_info->byte_offset;
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size)
+ {
+ value.SetUInt(v, reg_info->byte_size);
+ return true;
+ }
+ }
+
+ if (IsFPR(reg))
+ {
+ lldb::offset_t offset = reg_info->byte_offset;
+ uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size)
+ {
+ value.SetUInt(v, reg_info->byte_size);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+RegisterContextCorePOSIX_s390x::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
+{
+ return false;
+}
+
+bool
+RegisterContextCorePOSIX_s390x::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
+{
+ return false;
+}
+
+bool
+RegisterContextCorePOSIX_s390x::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
+{
+ return false;
+}
+
+bool
+RegisterContextCorePOSIX_s390x::HardwareSingleStep(bool enable)
+{
+ return false;
+}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
new file mode 100644
index 000000000000..8bb6fe1771ef
--- /dev/null
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
@@ -0,0 +1,65 @@
+//===-- RegisterContextCorePOSIX_s390x.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextCorePOSIX_s390x_h_
+#define liblldb_RegisterContextCorePOSIX_s390x_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/DataBufferHeap.h"
+#include "Plugins/Process/Utility/RegisterContextPOSIX_s390x.h"
+
+class RegisterContextCorePOSIX_s390x : public RegisterContextPOSIX_s390x
+{
+public:
+ RegisterContextCorePOSIX_s390x(lldb_private::Thread &thread, lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset);
+
+ ~RegisterContextCorePOSIX_s390x() override;
+
+ bool
+ ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value) override;
+
+ bool
+ WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override;
+
+ bool
+ ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool
+ WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ bool
+ HardwareSingleStep(bool enable) override;
+
+protected:
+ bool
+ ReadGPR() override;
+
+ bool
+ ReadFPR() override;
+
+ bool
+ WriteGPR() override;
+
+ bool
+ WriteFPR() override;
+
+private:
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb_private::DataExtractor m_gpr;
+
+ lldb::DataBufferSP m_fpr_buffer;
+ lldb_private::DataExtractor m_fpr;
+};
+
+#endif // liblldb_RegisterContextCorePOSIX_s390x_h_
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index 9cc7829fc391..e4cfa68044f1 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -18,6 +18,7 @@
#include "ProcessElfCore.h"
#include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h"
@@ -29,6 +30,7 @@
#include "RegisterContextPOSIXCore_arm64.h"
#include "RegisterContextPOSIXCore_mips64.h"
#include "RegisterContextPOSIXCore_powerpc.h"
+#include "RegisterContextPOSIXCore_s390x.h"
#include "RegisterContextPOSIXCore_x86_64.h"
using namespace lldb;
@@ -139,6 +141,9 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
case llvm::Triple::aarch64:
reg_interface = new RegisterContextLinux_arm64(arch);
break;
+ case llvm::Triple::systemz:
+ reg_interface = new RegisterContextLinux_s390x(arch);
+ break;
case llvm::Triple::x86_64:
reg_interface = new RegisterContextLinux_x86_64(arch);
break;
@@ -174,6 +179,9 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
case llvm::Triple::ppc64:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data));
break;
+ case llvm::Triple::systemz:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x (*this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
@@ -218,6 +226,7 @@ ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
size_t len;
switch(arch.GetCore())
{
+ case ArchSpec::eCore_s390x_generic:
case ArchSpec::eCore_x86_64_x86_64:
len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this);
return len == ELFLINUXPRSTATUS64_SIZE;
@@ -241,6 +250,7 @@ ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
size_t len;
switch(arch.GetCore())
{
+ case ArchSpec::eCore_s390x_generic:
case ArchSpec::eCore_x86_64_x86_64:
len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this);
return len == ELFLINUXPRPSINFO64_SIZE;
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.h b/source/Plugins/Process/elf-core/ThreadElfCore.h
index d3a42e0eb54d..b4e990140675 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.h
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.h
@@ -68,6 +68,7 @@ struct ELFLinuxPrStatus
{
switch(arch.GetCore())
{
+ case lldb_private::ArchSpec::eCore_s390x_generic:
case lldb_private::ArchSpec::eCore_x86_64_x86_64:
return ELFLINUXPRSTATUS64_SIZE;
default:
@@ -102,6 +103,7 @@ struct ELFLinuxPrPsInfo
{
switch(arch.GetCore())
{
+ case lldb_private::ArchSpec::eCore_s390x_generic:
case lldb_private::ArchSpec::eCore_x86_64_x86_64:
return ELFLINUXPRPSINFO64_SIZE;
default:
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 2ea1f206008a..f164b1411be8 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -793,8 +793,8 @@ GDBRemoteCommunication::PacketType
GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet)
{
// Put the packet data into the buffer in a thread safe fashion
- Mutex::Locker locker(m_bytes_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
+
Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
if (src && src_len > 0)
@@ -845,7 +845,7 @@ GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, Stri
case '%': // Async notify packet
isNotifyPacket = true;
- // Intentional fall through
+ LLVM_FALLTHROUGH;
case '$':
// Look for a standard gdb packet?
@@ -1120,7 +1120,7 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *url,
{
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));
+ log->Printf ("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")", __FUNCTION__, url ? url : "<empty>", port ? *port : uint16_t(0));
Error error;
// If we locate debugserver, keep that located version around
@@ -1352,7 +1352,14 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *url,
launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true);
launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true);
-
+
+ if (log)
+ {
+ StreamString string_stream;
+ Platform *const platform = nullptr;
+ launch_info.Dump(string_stream, platform);
+ log->Printf("launch info for gdb-remote stub:\n%s", string_stream.GetString().c_str());
+ }
error = Host::LaunchProcess(launch_info);
if (error.Success() &&
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index c0ea9cceea2e..c90706a88b84 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -55,79 +55,79 @@ using namespace lldb_private::process_gdb_remote;
//----------------------------------------------------------------------
// GDBRemoteCommunicationClient constructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() :
- GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"),
- m_supports_not_sending_acks (eLazyBoolCalculate),
- m_supports_thread_suffix (eLazyBoolCalculate),
- m_supports_threads_in_stop_reply (eLazyBoolCalculate),
- m_supports_vCont_all (eLazyBoolCalculate),
- m_supports_vCont_any (eLazyBoolCalculate),
- m_supports_vCont_c (eLazyBoolCalculate),
- m_supports_vCont_C (eLazyBoolCalculate),
- m_supports_vCont_s (eLazyBoolCalculate),
- m_supports_vCont_S (eLazyBoolCalculate),
- m_qHostInfo_is_valid (eLazyBoolCalculate),
- m_curr_pid_is_valid (eLazyBoolCalculate),
- m_qProcessInfo_is_valid (eLazyBoolCalculate),
- m_qGDBServerVersion_is_valid (eLazyBoolCalculate),
- m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
- m_supports_memory_region_info (eLazyBoolCalculate),
- m_supports_watchpoint_support_info (eLazyBoolCalculate),
- m_supports_detach_stay_stopped (eLazyBoolCalculate),
- m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
- m_attach_or_wait_reply(eLazyBoolCalculate),
- m_prepare_for_reg_writing_reply (eLazyBoolCalculate),
- m_supports_p (eLazyBoolCalculate),
- m_supports_x (eLazyBoolCalculate),
- m_avoid_g_packets (eLazyBoolCalculate),
- m_supports_QSaveRegisterState (eLazyBoolCalculate),
- m_supports_qXfer_auxv_read (eLazyBoolCalculate),
- m_supports_qXfer_libraries_read (eLazyBoolCalculate),
- m_supports_qXfer_libraries_svr4_read (eLazyBoolCalculate),
- m_supports_qXfer_features_read (eLazyBoolCalculate),
- m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate),
- m_supports_jThreadExtendedInfo (eLazyBoolCalculate),
- m_supports_jLoadedDynamicLibrariesInfos (eLazyBoolCalculate),
- m_supports_qProcessInfoPID (true),
- m_supports_qfProcessInfo (true),
- m_supports_qUserName (true),
- m_supports_qGroupName (true),
- m_supports_qThreadStopInfo (true),
- m_supports_z0 (true),
- m_supports_z1 (true),
- m_supports_z2 (true),
- m_supports_z3 (true),
- m_supports_z4 (true),
- m_supports_QEnvironment (true),
- m_supports_QEnvironmentHexEncoded (true),
- m_supports_qSymbol (true),
- m_qSymbol_requests_done (false),
- m_supports_qModuleInfo (true),
- m_supports_jThreadsInfo (true),
- m_curr_pid (LLDB_INVALID_PROCESS_ID),
- m_curr_tid (LLDB_INVALID_THREAD_ID),
- m_curr_tid_run (LLDB_INVALID_THREAD_ID),
- m_num_supported_hardware_watchpoints (0),
- m_async_mutex (Mutex::eMutexTypeRecursive),
- m_async_packet_predicate (false),
- m_async_packet (),
- m_async_result (PacketResult::Success),
- m_async_response (),
- m_async_signal (-1),
- m_interrupt_sent (false),
- m_thread_id_to_used_usec_map (),
- m_host_arch(),
- m_process_arch(),
- m_os_version_major (UINT32_MAX),
- m_os_version_minor (UINT32_MAX),
- m_os_version_update (UINT32_MAX),
- m_os_build (),
- m_os_kernel (),
- m_hostname (),
- m_gdb_server_name(),
- m_gdb_server_version(UINT32_MAX),
- m_default_packet_timeout (0),
- m_max_packet_size (0)
+GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
+ : GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"),
+ m_supports_not_sending_acks(eLazyBoolCalculate),
+ m_supports_thread_suffix(eLazyBoolCalculate),
+ m_supports_threads_in_stop_reply(eLazyBoolCalculate),
+ m_supports_vCont_all(eLazyBoolCalculate),
+ m_supports_vCont_any(eLazyBoolCalculate),
+ m_supports_vCont_c(eLazyBoolCalculate),
+ m_supports_vCont_C(eLazyBoolCalculate),
+ m_supports_vCont_s(eLazyBoolCalculate),
+ m_supports_vCont_S(eLazyBoolCalculate),
+ m_qHostInfo_is_valid(eLazyBoolCalculate),
+ m_curr_pid_is_valid(eLazyBoolCalculate),
+ m_qProcessInfo_is_valid(eLazyBoolCalculate),
+ m_qGDBServerVersion_is_valid(eLazyBoolCalculate),
+ m_supports_alloc_dealloc_memory(eLazyBoolCalculate),
+ m_supports_memory_region_info(eLazyBoolCalculate),
+ m_supports_watchpoint_support_info(eLazyBoolCalculate),
+ m_supports_detach_stay_stopped(eLazyBoolCalculate),
+ m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
+ m_attach_or_wait_reply(eLazyBoolCalculate),
+ m_prepare_for_reg_writing_reply(eLazyBoolCalculate),
+ m_supports_p(eLazyBoolCalculate),
+ m_supports_x(eLazyBoolCalculate),
+ m_avoid_g_packets(eLazyBoolCalculate),
+ m_supports_QSaveRegisterState(eLazyBoolCalculate),
+ m_supports_qXfer_auxv_read(eLazyBoolCalculate),
+ m_supports_qXfer_libraries_read(eLazyBoolCalculate),
+ m_supports_qXfer_libraries_svr4_read(eLazyBoolCalculate),
+ m_supports_qXfer_features_read(eLazyBoolCalculate),
+ m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate),
+ m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
+ m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
+ m_supports_qProcessInfoPID(true),
+ m_supports_qfProcessInfo(true),
+ m_supports_qUserName(true),
+ m_supports_qGroupName(true),
+ m_supports_qThreadStopInfo(true),
+ m_supports_z0(true),
+ m_supports_z1(true),
+ m_supports_z2(true),
+ m_supports_z3(true),
+ m_supports_z4(true),
+ m_supports_QEnvironment(true),
+ m_supports_QEnvironmentHexEncoded(true),
+ m_supports_qSymbol(true),
+ m_qSymbol_requests_done(false),
+ m_supports_qModuleInfo(true),
+ m_supports_jThreadsInfo(true),
+ m_curr_pid(LLDB_INVALID_PROCESS_ID),
+ m_curr_tid(LLDB_INVALID_THREAD_ID),
+ m_curr_tid_run(LLDB_INVALID_THREAD_ID),
+ m_num_supported_hardware_watchpoints(0),
+ m_async_mutex(),
+ m_async_packet_predicate(false),
+ m_async_packet(),
+ m_async_result(PacketResult::Success),
+ m_async_response(),
+ m_async_signal(-1),
+ m_interrupt_sent(false),
+ m_thread_id_to_used_usec_map(),
+ m_host_arch(),
+ m_process_arch(),
+ m_os_version_major(UINT32_MAX),
+ m_os_version_minor(UINT32_MAX),
+ m_os_version_update(UINT32_MAX),
+ m_os_build(),
+ m_os_kernel(),
+ m_hostname(),
+ m_gdb_server_name(),
+ m_gdb_server_version(UINT32_MAX),
+ m_default_packet_timeout(0),
+ m_max_packet_size(0)
{
}
@@ -623,6 +623,7 @@ GDBRemoteCommunicationClient::GetThreadsInfo()
if (m_supports_jThreadsInfo)
{
StringExtractorGDBRemote response;
+ response.SetResponseValidatorToJSON();
if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) == PacketResult::Success)
{
if (response.IsUnsupportedResponse())
@@ -765,9 +766,29 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponseNoLock (const char *pa
size_t payload_length,
StringExtractorGDBRemote &response)
{
- PacketResult packet_result = SendPacketNoLock (payload, payload_length);
+ PacketResult packet_result = SendPacketNoLock(payload, payload_length);
if (packet_result == PacketResult::Success)
- packet_result = ReadPacket (response, GetPacketTimeoutInMicroSeconds (), true);
+ {
+ const size_t max_response_retries = 3;
+ for (size_t i=0; i<max_response_retries; ++i)
+ {
+ packet_result = ReadPacket(response, GetPacketTimeoutInMicroSeconds (), true);
+ // Make sure we received a response
+ if (packet_result != PacketResult::Success)
+ return packet_result;
+ // Make sure our response is valid for the payload that was sent
+ if (response.ValidateResponse())
+ return packet_result;
+ // Response says it wasn't valid
+ Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
+ if (log)
+ log->Printf("error: packet with payload \"%*s\" got invalid response \"%s\": %s",
+ (int)payload_length,
+ payload,
+ response.GetStringRef().c_str(),
+ (i == (max_response_retries - 1)) ? "using invalid response and giving up" : "ignoring response and waiting for another");
+ }
+ }
return packet_result;
}
@@ -786,8 +807,8 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
// In order to stop async notifications from being processed in the middle of the
// send/receive sequence Hijack the broadcast. Then rebroadcast any events when we are done.
- static Listener hijack_listener("lldb.NotifyHijacker");
- HijackBroadcaster(&hijack_listener, eBroadcastBitGdbReadThreadGotNotify);
+ static ListenerSP hijack_listener_sp(Listener::MakeListener("lldb.NotifyHijacker"));
+ HijackBroadcaster(hijack_listener_sp, eBroadcastBitGdbReadThreadGotNotify);
if (GetSequenceMutex (locker))
{
@@ -799,8 +820,9 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
{
if (IsRunning())
{
- Mutex::Locker async_locker (m_async_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_async_mutex);
m_async_packet.assign(payload, payload_length);
+ m_async_response.CopyResponseValidator(response);
m_async_packet_predicate.SetValue (true, eBroadcastNever);
if (log)
@@ -867,6 +889,9 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
if (log)
log->Printf ("async: failed to interrupt");
}
+
+ m_async_response.SetResponseValidator(nullptr, nullptr);
+
}
else
{
@@ -886,7 +911,7 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
// If a notification event occurred, rebroadcast since it can now be processed safely.
EventSP event_sp;
- if (hijack_listener.GetNextEvent(event_sp))
+ if (hijack_listener_sp->GetNextEvent(event_sp))
BroadcastEvent(event_sp);
return packet_result;
@@ -1136,13 +1161,17 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
// which will just re-send a copy of the last stop reply
// packet. If we don't do this, then the reply for our
// async packet will be the repeat stop reply packet and cause
- // a lot of trouble for us!
- if (signo != sigint_signo && signo != sigstop_signo)
+ // a lot of trouble for us! We also have some debugserver
+ // binaries that would send two stop replies anytime the process
+ // was interrupted, so we need to also check for an extra
+ // stop reply packet if we interrupted the process
+ const bool received_nonstop_signal = signo != sigint_signo && signo != sigstop_signo;
+ if (m_interrupt_sent || received_nonstop_signal)
{
- continue_after_async = false;
+ if (received_nonstop_signal)
+ continue_after_async = false;
- // We didn't get a SIGINT or SIGSTOP, so try for a
- // very brief time (0.1s) to get another stop reply
+ // Try for a very brief time (0.1s) to get another stop reply
// packet to make sure it doesn't get in the way
StringExtractorGDBRemote extra_stop_reply_packet;
uint32_t timeout_usec = 100000;
@@ -1343,7 +1372,7 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
bool
GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
{
- Mutex::Locker async_locker (m_async_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_async_mutex);
m_async_signal = signo;
bool timed_out = false;
Mutex::Locker locker;
@@ -2064,7 +2093,8 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
if (pointer_byte_size != 0)
++num_keys_decoded;
}
- else if (name.compare("os_version") == 0)
+ else if ((name.compare("os_version") == 0) ||
+ (name.compare("version") == 0)) // Older debugserver binaries used the "version" key instead of "os_version"...
{
Args::StringToVersion (value.c_str(),
m_os_version_major,
@@ -2114,20 +2144,6 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
assert (byte_order == m_host_arch.GetByteOrder());
}
- if (!os_name.empty() && vendor_name.compare("apple") == 0 && os_name.find("darwin") == 0)
- {
- switch (m_host_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- os_name = "ios";
- break;
- default:
- os_name = "macosx";
- break;
- }
- }
if (!vendor_name.empty())
m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
if (!os_name.empty())
@@ -2411,6 +2427,8 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
region_info.SetExecutable (MemoryRegionInfo::eYes);
else
region_info.SetExecutable (MemoryRegionInfo::eNo);
+
+ region_info.SetMapped(MemoryRegionInfo::eYes);
}
else
{
@@ -2418,6 +2436,7 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
region_info.SetReadable (MemoryRegionInfo::eNo);
region_info.SetWritable (MemoryRegionInfo::eNo);
region_info.SetExecutable (MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
}
}
else if (name.compare ("error") == 0)
@@ -2437,6 +2456,7 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
region_info.SetReadable (MemoryRegionInfo::eNo);
region_info.SetWritable (MemoryRegionInfo::eNo);
region_info.SetExecutable (MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
}
}
else
@@ -3571,6 +3591,8 @@ GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type,
// Check we haven't overwritten the end of the packet buffer
assert (packet_len + 1 < (int)sizeof(packet));
StringExtractorGDBRemote response;
+ // Make sure the response is either "OK", "EXX" where XX are two hex digits, or "" (unsupported)
+ response.SetResponseValidatorToOKErrorNotSupported();
// Try to send the breakpoint packet, and check that it was correctly sent
if (SendPacketAndWaitForResponse(packet, packet_len, response, true) == PacketResult::Success)
{
@@ -4417,7 +4439,7 @@ GDBRemoteCommunicationClient::ReadExtFeature (const lldb_private::ConstString ob
// last chunk
case ( 'l' ):
active = false;
- // fall through intentional
+ LLVM_FALLTHROUGH;
// more chunks
case ( 'm' ) :
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 311b0f3267c8..096c4cf81015 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
#include <string>
#include <vector>
@@ -527,7 +528,7 @@ public:
bool
ReadRegister(lldb::tid_t tid,
- uint32_t reg_num,
+ uint32_t reg_num, // Must be the eRegisterKindProcessPlugin register number, to be sent to the remote
StringExtractorGDBRemote &response);
bool
@@ -631,7 +632,7 @@ protected:
// If we need to send a packet while the target is running, the m_async_XXX
// member variables take care of making this happen.
- Mutex m_async_mutex;
+ std::recursive_mutex m_async_mutex;
Predicate<bool> m_async_packet_predicate;
std::string m_async_packet;
PacketResult m_async_result;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
index f55b2eb3f4dc..d2fd70042ccc 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
@@ -17,7 +17,6 @@
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private-forward.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/Process.h"
#include "GDBRemoteCommunicationServer.h"
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 921369c7ef21..fc6b31ec088e 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -39,7 +39,6 @@
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/FileAction.h"
#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/Platform.h"
#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
@@ -76,25 +75,21 @@ namespace
//----------------------------------------------------------------------
// GDBRemoteCommunicationServerLLGS constructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(
- const lldb::PlatformSP& platform_sp,
- MainLoop &mainloop) :
- GDBRemoteCommunicationServerCommon ("gdb-remote.server", "gdb-remote.server.rx_packet"),
- m_platform_sp (platform_sp),
- m_mainloop (mainloop),
- m_current_tid (LLDB_INVALID_THREAD_ID),
- m_continue_tid (LLDB_INVALID_THREAD_ID),
- m_debugged_process_mutex (Mutex::eMutexTypeRecursive),
- m_debugged_process_sp (),
- m_stdio_communication ("process.stdio"),
- m_inferior_prev_state (StateType::eStateInvalid),
- m_active_auxv_buffer_sp (),
- m_saved_registers_mutex (),
- m_saved_registers_map (),
- m_next_saved_registers_id (1),
- m_handshake_completed (false)
-{
- assert(platform_sp);
+GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(MainLoop &mainloop)
+ : GDBRemoteCommunicationServerCommon("gdb-remote.server", "gdb-remote.server.rx_packet"),
+ m_mainloop(mainloop),
+ m_current_tid(LLDB_INVALID_THREAD_ID),
+ m_continue_tid(LLDB_INVALID_THREAD_ID),
+ m_debugged_process_mutex(),
+ m_debugged_process_sp(),
+ m_stdio_communication("process.stdio"),
+ m_inferior_prev_state(StateType::eStateInvalid),
+ m_active_auxv_buffer_sp(),
+ m_saved_registers_mutex(),
+ m_saved_registers_map(),
+ m_next_saved_registers_id(1),
+ m_handshake_completed(false)
+{
RegisterPacketHandlers();
}
@@ -210,7 +205,7 @@ GDBRemoteCommunicationServerLLGS::LaunchProcess ()
Error error;
{
- Mutex::Locker locker (m_debugged_process_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
assert (!m_debugged_process_sp && "lldb-gdbserver creating debugged process but one already exists");
error = NativeProcessProtocol::Launch(
m_process_launch_info,
@@ -1367,7 +1362,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont (StringExtractorGDBRemote &packet
thread_action.signal = packet.GetHexMaxU32 (false, 0);
if (thread_action.signal == 0)
return SendIllFormedResponse (packet, "Could not parse signal in vCont packet C action");
- // Fall through to next case...
+ LLVM_FALLTHROUGH;
case 'c':
// Continue
@@ -1378,7 +1373,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont (StringExtractorGDBRemote &packet
thread_action.signal = packet.GetHexMaxU32 (false, 0);
if (thread_action.signal == 0)
return SendIllFormedResponse (packet, "Could not parse signal in vCont packet S action");
- // Fall through to next case...
+ LLVM_FALLTHROUGH;
case 's':
// Step
@@ -2593,7 +2588,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState (StringExtractorGDBR
// Save the register data buffer under the save id.
{
- Mutex::Locker locker (m_saved_registers_mutex);
+ std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
m_saved_registers_map[save_id] = register_data_sp;
}
@@ -2643,7 +2638,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState (StringExtractorG
// Retrieve register state buffer, then remove from the list.
DataBufferSP register_data_sp;
{
- Mutex::Locker locker (m_saved_registers_mutex);
+ std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
// Find the register set buffer for the given save id.
auto it = m_saved_registers_map.find (save_id);
@@ -2947,7 +2942,7 @@ GDBRemoteCommunicationServerLLGS::GetCurrentThreadID () const
uint32_t
GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID ()
{
- Mutex::Locker locker (m_saved_registers_mutex);
+ std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
return m_next_saved_registers_id++;
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index f16057781ddc..caf6eb319e63 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -12,12 +12,12 @@
// C Includes
// C++ Includes
+#include <mutex>
#include <unordered_map>
// Other libraries and framework includes
#include "lldb/lldb-private-forward.h"
#include "lldb/Core/Communication.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Host/MainLoop.h"
@@ -40,7 +40,7 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- GDBRemoteCommunicationServerLLGS(const lldb::PlatformSP& platform_sp, MainLoop &mainloop);
+ GDBRemoteCommunicationServerLLGS(MainLoop &mainloop);
//------------------------------------------------------------------
/// Specify the program to launch and its arguments.
@@ -114,12 +114,11 @@ public:
InitializeConnection (std::unique_ptr<Connection> &&connection);
protected:
- lldb::PlatformSP m_platform_sp;
MainLoop &m_mainloop;
MainLoop::ReadHandleUP m_network_handle_up;
lldb::tid_t m_current_tid;
lldb::tid_t m_continue_tid;
- Mutex m_debugged_process_mutex;
+ std::recursive_mutex m_debugged_process_mutex;
NativeProcessProtocolSP m_debugged_process_sp;
Communication m_stdio_communication;
@@ -127,7 +126,7 @@ protected:
lldb::StateType m_inferior_prev_state;
lldb::DataBufferSP m_active_auxv_buffer_sp;
- Mutex m_saved_registers_mutex;
+ std::mutex m_saved_registers_mutex;
std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
uint32_t m_next_saved_registers_id;
bool m_handshake_completed : 1;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index f88ac1247526..d6900c27293c 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -48,14 +48,13 @@ using namespace lldb_private::process_gdb_remote;
// GDBRemoteCommunicationServerPlatform constructor
//----------------------------------------------------------------------
GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(const Socket::SocketProtocol socket_protocol,
- const char* socket_scheme) :
- GDBRemoteCommunicationServerCommon ("gdb-remote.server", "gdb-remote.server.rx_packet"),
- m_socket_protocol(socket_protocol),
- m_socket_scheme(socket_scheme),
- m_spawned_pids_mutex (Mutex::eMutexTypeRecursive),
- m_platform_sp (Platform::GetHostPlatform ()),
- m_port_map (),
- m_port_offset(0)
+ const char *socket_scheme)
+ : GDBRemoteCommunicationServerCommon("gdb-remote.server", "gdb-remote.server.rx_packet"),
+ m_socket_protocol(socket_protocol),
+ m_socket_scheme(socket_scheme),
+ m_spawned_pids_mutex(),
+ m_port_map(),
+ m_port_offset(0)
{
m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID;
m_pending_gdb_server.port = 0;
@@ -78,11 +77,7 @@ GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(const
&GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
- [this](StringExtractorGDBRemote packet,
- Error &error,
- bool &interrupt,
- bool &quit)
- {
+ [this](StringExtractorGDBRemote packet, Error &error, bool &interrupt, bool &quit) {
error.SetErrorString("interrupt received");
interrupt = true;
return PacketResult::Success;
@@ -124,7 +119,8 @@ GDBRemoteCommunicationServerPlatform::LaunchGDBServer(const lldb_private::Args&
// Do not run in a new session so that it can not linger after the
// platform closes.
debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
- debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
+ debugserver_launch_info.SetMonitorProcessCallback(
+ std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, this, std::placeholders::_1), false);
std::string platform_scheme;
std::string platform_ip;
@@ -135,6 +131,10 @@ GDBRemoteCommunicationServerPlatform::LaunchGDBServer(const lldb_private::Args&
assert(ok);
std::ostringstream url;
+ // debugserver does not accept the URL scheme prefix.
+#if !defined(__APPLE__)
+ url << m_socket_scheme << "://";
+#endif
uint16_t* port_ptr = &port;
if (m_socket_protocol == Socket::ProtocolTcp)
url << platform_ip << ":" << port;
@@ -154,7 +154,7 @@ GDBRemoteCommunicationServerPlatform::LaunchGDBServer(const lldb_private::Args&
pid = debugserver_launch_info.GetProcessID();
if (pid != LLDB_INVALID_PROCESS_ID)
{
- Mutex::Locker locker (m_spawned_pids_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
m_spawned_pids.insert(pid);
if (port > 0)
AssociatePortWithProcess(port, pid);
@@ -259,7 +259,7 @@ GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess (StringExtracto
// verify that we know anything about this pid.
// Scope for locker
{
- Mutex::Locker locker (m_spawned_pids_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
{
// not a pid we know about
@@ -279,7 +279,7 @@ GDBRemoteCommunicationServerPlatform::KillSpawnedProcess (lldb::pid_t pid)
{
// make sure we know about this process
{
- Mutex::Locker locker (m_spawned_pids_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
return false;
}
@@ -291,7 +291,7 @@ GDBRemoteCommunicationServerPlatform::KillSpawnedProcess (lldb::pid_t pid)
for (size_t i=0; i<10; ++i)
{
{
- Mutex::Locker locker (m_spawned_pids_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
{
// it is now killed
@@ -303,7 +303,7 @@ GDBRemoteCommunicationServerPlatform::KillSpawnedProcess (lldb::pid_t pid)
// check one more time after the final usleep
{
- Mutex::Locker locker (m_spawned_pids_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
return true;
}
@@ -315,7 +315,7 @@ GDBRemoteCommunicationServerPlatform::KillSpawnedProcess (lldb::pid_t pid)
for (size_t i=0; i<10; ++i)
{
{
- Mutex::Locker locker (m_spawned_pids_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
{
// it is now killed
@@ -328,7 +328,7 @@ GDBRemoteCommunicationServerPlatform::KillSpawnedProcess (lldb::pid_t pid)
// check one more time after the final usleep
// Scope for locker
{
- Mutex::Locker locker (m_spawned_pids_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
return true;
}
@@ -442,20 +442,9 @@ GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(StringExtractorGDBRemo
bool
GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped (lldb::pid_t pid)
{
- Mutex::Locker locker (m_spawned_pids_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
FreePortForProcess(pid);
- return m_spawned_pids.erase(pid) > 0;
-}
-
-bool
-GDBRemoteCommunicationServerPlatform::ReapDebugserverProcess (void *callback_baton,
- lldb::pid_t pid,
- bool exited,
- int signal, // Zero for no signal
- int status) // Exit value of process if signal is zero
-{
- GDBRemoteCommunicationServerPlatform *server = (GDBRemoteCommunicationServerPlatform *)callback_baton;
- server->DebugserverProcessReaped (pid);
+ m_spawned_pids.erase(pid);
return true;
}
@@ -469,9 +458,11 @@ GDBRemoteCommunicationServerPlatform::LaunchProcess ()
// generally be what happens since we need to reap started
// processes.
if (!m_process_launch_info.GetMonitorProcessCallback ())
- m_process_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
+ m_process_launch_info.SetMonitorProcessCallback(
+ std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, this, std::placeholders::_1),
+ false);
- Error error = m_platform_sp->LaunchProcess (m_process_launch_info);
+ Error error = Host::LaunchProcess(m_process_launch_info);
if (!error.Success ())
{
fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0));
@@ -486,7 +477,7 @@ GDBRemoteCommunicationServerPlatform::LaunchProcess ()
if (pid != LLDB_INVALID_PROCESS_ID)
{
// add to spawned pids
- Mutex::Locker locker (m_spawned_pids_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
m_spawned_pids.insert(pid);
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
index 1fe7207d2bc2..1f4d08c64e00 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
#include <set>
// Other libraries and framework includes
@@ -82,9 +83,8 @@ public:
protected:
const Socket::SocketProtocol m_socket_protocol;
const std::string m_socket_scheme;
- Mutex m_spawned_pids_mutex;
+ std::recursive_mutex m_spawned_pids_mutex;
std::set<lldb::pid_t> m_spawned_pids;
- lldb::PlatformSP m_platform_sp;
PortMap m_port_map;
uint16_t m_port_offset;
@@ -121,13 +121,6 @@ private:
bool
DebugserverProcessReaped (lldb::pid_t pid);
- static bool
- ReapDebugserverProcess (void *callback_baton,
- lldb::pid_t pid,
- bool exited,
- int signal,
- int status);
-
static const FileSpec&
GetDomainSocketDir();
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index b0a1eaaeb79c..e5b347c9f72d 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -198,10 +198,11 @@ bool
GDBRemoteRegisterContext::GetPrimordialRegister(const RegisterInfo *reg_info,
GDBRemoteCommunicationClient &gdb_comm)
{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];
+ const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];
StringExtractorGDBRemote response;
- if (gdb_comm.ReadRegister(m_thread.GetProtocolID(), reg, response))
- return PrivateSetRegisterValue (reg, response);
+ if (gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg, response))
+ return PrivateSetRegisterValue (lldb_reg, response);
return false;
}
@@ -316,7 +317,7 @@ GDBRemoteRegisterContext::SetPrimordialRegister(const RegisterInfo *reg_info,
StreamString packet;
StringExtractorGDBRemote response;
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- packet.Printf ("P%x=", reg);
+ packet.Printf ("P%x=", reg_info->kinds[eRegisterKindProcessPlugin]);
packet.PutBytesAsRawHex8 (m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size),
reg_info->byte_size,
endian::InlHostByteOrder(),
@@ -813,7 +814,7 @@ GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data
if (restore_src)
{
StreamString packet;
- packet.Printf ("P%x=", reg);
+ packet.Printf ("P%x=", reg_info->kinds[eRegisterKindProcessPlugin]);
packet.PutBytesAsRawHex8 (restore_src,
reg_byte_size,
endian::InlHostByteOrder(),
@@ -836,7 +837,7 @@ GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data
if (write_reg)
{
StreamString packet;
- packet.Printf ("P%x=", reg);
+ packet.Printf ("P%x=", reg_info->kinds[eRegisterKindProcessPlugin]);
packet.PutBytesAsRawHex8 (restore_src,
reg_byte_size,
endian::InlHostByteOrder(),
@@ -894,7 +895,7 @@ GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data
continue;
}
StreamString packet;
- packet.Printf ("P%x=", reg_info->kinds[eRegisterKindLLDB]);
+ packet.Printf ("P%x=", reg_info->kinds[eRegisterKindProcessPlugin]);
packet.PutBytesAsRawHex8 (data_sp->GetBytes() + reg_info->byte_offset, reg_info->byte_size, endian::InlHostByteOrder(), endian::InlHostByteOrder());
if (thread_suffix_supported)
packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
diff --git a/source/Plugins/Process/gdb-remote/Makefile b/source/Plugins/Process/gdb-remote/Makefile
deleted file mode 100644
index 8a9b61077875..000000000000
--- a/source/Plugins/Process/gdb-remote/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Process/gdb-remote/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginProcessGDBRemote
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 856ea35aef99..4d56f6ea3ba1 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -223,11 +223,11 @@ ProcessGDBRemote::Terminate()
lldb::ProcessSP
-ProcessGDBRemote::CreateInstance (lldb::TargetSP target_sp, Listener &listener, const FileSpec *crash_file_path)
+ProcessGDBRemote::CreateInstance (lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec *crash_file_path)
{
lldb::ProcessSP process_sp;
if (crash_file_path == NULL)
- process_sp.reset (new ProcessGDBRemote (target_sp, listener));
+ process_sp.reset (new ProcessGDBRemote (target_sp, listener_sp));
return process_sp;
}
@@ -267,51 +267,51 @@ ProcessGDBRemote::CanDebug (lldb::TargetSP target_sp, bool plugin_specified_by_n
//----------------------------------------------------------------------
// ProcessGDBRemote constructor
//----------------------------------------------------------------------
-ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, Listener &listener) :
- Process (target_sp, listener),
- m_flags (0),
- m_gdb_comm (),
- m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
- m_last_stop_packet_mutex (Mutex::eMutexTypeRecursive),
- m_register_info (),
- m_async_broadcaster (NULL, "lldb.process.gdb-remote.async-broadcaster"),
- m_async_listener("lldb.process.gdb-remote.async-listener"),
- m_async_thread_state_mutex(Mutex::eMutexTypeRecursive),
- m_thread_ids (),
- m_thread_pcs (),
- m_jstopinfo_sp (),
- m_jthreadsinfo_sp (),
- m_continue_c_tids (),
- m_continue_C_tids (),
- m_continue_s_tids (),
- m_continue_S_tids (),
- m_max_memory_size (0),
- m_remote_stub_max_memory_size (0),
- m_addr_to_mmap_size (),
- m_thread_create_bp_sp (),
- m_waiting_for_attach (false),
- m_destroy_tried_resuming (false),
- m_command_sp (),
- m_breakpoint_pc_offset (0),
- m_initial_tid (LLDB_INVALID_THREAD_ID)
+ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, ListenerSP listener_sp)
+ : Process(target_sp, listener_sp),
+ m_flags(0),
+ m_gdb_comm(),
+ m_debugserver_pid(LLDB_INVALID_PROCESS_ID),
+ m_last_stop_packet_mutex(),
+ m_register_info(),
+ m_async_broadcaster(NULL, "lldb.process.gdb-remote.async-broadcaster"),
+ m_async_listener_sp(Listener::MakeListener("lldb.process.gdb-remote.async-listener")),
+ m_async_thread_state_mutex(),
+ m_thread_ids(),
+ m_thread_pcs(),
+ m_jstopinfo_sp(),
+ m_jthreadsinfo_sp(),
+ m_continue_c_tids(),
+ m_continue_C_tids(),
+ m_continue_s_tids(),
+ m_continue_S_tids(),
+ m_max_memory_size(0),
+ m_remote_stub_max_memory_size(0),
+ m_addr_to_mmap_size(),
+ m_thread_create_bp_sp(),
+ m_waiting_for_attach(false),
+ m_destroy_tried_resuming(false),
+ m_command_sp(),
+ m_breakpoint_pc_offset(0),
+ m_initial_tid(LLDB_INVALID_THREAD_ID)
{
- m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
- m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
- m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadDidExit, "async thread did exit");
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, "async thread continue");
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadDidExit, "async thread did exit");
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_ASYNC));
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC));
const uint32_t async_event_mask = eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
- if (m_async_listener.StartListeningForEvents(&m_async_broadcaster, async_event_mask) != async_event_mask)
+ if (m_async_listener_sp->StartListeningForEvents(&m_async_broadcaster, async_event_mask) != async_event_mask)
{
if (log)
log->Printf("ProcessGDBRemote::%s failed to listen for m_async_broadcaster events", __FUNCTION__);
}
- const uint32_t gdb_event_mask = Communication::eBroadcastBitReadThreadDidExit |
- GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
- if (m_async_listener.StartListeningForEvents(&m_gdb_comm, gdb_event_mask) != gdb_event_mask)
+ const uint32_t gdb_event_mask =
+ Communication::eBroadcastBitReadThreadDidExit | GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
+ if (m_async_listener_sp->StartListeningForEvents(&m_gdb_comm, gdb_event_mask) != gdb_event_mask)
{
if (log)
log->Printf("ProcessGDBRemote::%s failed to listen for m_gdb_comm events", __FUNCTION__);
@@ -500,7 +500,21 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
}
}
- if (GetGDBServerRegisterInfo ())
+ const ArchSpec &target_arch = GetTarget().GetArchitecture();
+ const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();
+ const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+
+ // Use the process' architecture instead of the host arch, if available
+ ArchSpec arch_to_use;
+ if (remote_process_arch.IsValid ())
+ arch_to_use = remote_process_arch;
+ else
+ arch_to_use = remote_host_arch;
+
+ if (!arch_to_use.IsValid())
+ arch_to_use = target_arch;
+
+ if (GetGDBServerRegisterInfo (arch_to_use))
return;
char packet[128];
@@ -640,7 +654,12 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
reg_info.invalidate_regs = invalidate_regs.data();
}
- AugmentRegisterInfoViaABI (reg_info, reg_name, GetABI ());
+ // We have to make a temporary ABI here, and not use the GetABI because this code
+ // gets called in DidAttach, when the target architecture (and consequently the ABI we'll get from
+ // the process) may be wrong.
+ ABISP abi_to_use = ABI::FindPlugin(arch_to_use);
+
+ AugmentRegisterInfoViaABI (reg_info, reg_name, abi_to_use);
m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
}
@@ -668,22 +687,11 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
// add composite registers to the existing primordial ones.
bool from_scratch = (m_register_info.GetNumRegisters() == 0);
- const ArchSpec &target_arch = GetTarget().GetArchitecture();
- const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();
- const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
-
- // Use the process' architecture instead of the host arch, if available
- ArchSpec remote_arch;
- if (remote_process_arch.IsValid ())
- remote_arch = remote_process_arch;
- else
- remote_arch = remote_host_arch;
-
if (!target_arch.IsValid())
{
- if (remote_arch.IsValid()
- && (remote_arch.GetMachine() == llvm::Triple::arm || remote_arch.GetMachine() == llvm::Triple::thumb)
- && remote_arch.GetTriple().getVendor() == llvm::Triple::Apple)
+ if (arch_to_use.IsValid()
+ && (arch_to_use.GetMachine() == llvm::Triple::arm || arch_to_use.GetMachine() == llvm::Triple::thumb)
+ && arch_to_use.GetTriple().getVendor() == llvm::Triple::Apple)
m_register_info.HardcodeARMRegisters(from_scratch);
}
else if (target_arch.GetMachine() == llvm::Triple::arm
@@ -1360,10 +1368,10 @@ ProcessGDBRemote::DoResume ()
if (log)
log->Printf ("ProcessGDBRemote::Resume()");
- Listener listener ("gdb-remote.resume-packet-sent");
- if (listener.StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
+ ListenerSP listener_sp (Listener::MakeListener("gdb-remote.resume-packet-sent"));
+ if (listener_sp->StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
{
- listener.StartListeningForEvents (&m_async_broadcaster, ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);
+ listener_sp->StartListeningForEvents (&m_async_broadcaster, ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);
const size_t num_threads = GetThreadList().GetSize();
@@ -1595,7 +1603,7 @@ ProcessGDBRemote::DoResume ()
m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (continue_packet.GetData(), continue_packet.GetSize()));
- if (listener.WaitForEvent (&timeout, event_sp) == false)
+ if (listener_sp->WaitForEvent (&timeout, event_sp) == false)
{
error.SetErrorString("Resume timed out.");
if (log)
@@ -1638,7 +1646,7 @@ ProcessGDBRemote::HandleStopReplySequence ()
void
ProcessGDBRemote::ClearThreadIDList ()
{
- Mutex::Locker locker(m_thread_list_real.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
m_thread_ids.clear();
m_thread_pcs.clear();
}
@@ -1688,7 +1696,7 @@ ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue (std::string &value)
bool
ProcessGDBRemote::UpdateThreadIDList ()
{
- Mutex::Locker locker(m_thread_list_real.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
if (m_jthreadsinfo_sp)
{
@@ -1721,8 +1729,8 @@ ProcessGDBRemote::UpdateThreadIDList ()
// Lock the thread stack while we access it
//Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex);
- Mutex::Locker stop_stack_lock;
- if (stop_stack_lock.TryLock(m_last_stop_packet_mutex))
+ std::unique_lock<std::recursive_mutex> stop_stack_lock(m_last_stop_packet_mutex, std::defer_lock);
+ if (stop_stack_lock.try_lock())
{
// Get the number of stop packets on the stack
int nItems = m_stop_packet_stack.size();
@@ -1832,7 +1840,7 @@ ProcessGDBRemote::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new
}
}
}
- new_thread_list.AddThread(thread_sp);
+ new_thread_list.AddThreadSortedByIndexID (thread_sp);
}
}
@@ -1936,7 +1944,7 @@ ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid,
// m_thread_list_real does have its own mutex, but we need to
// hold onto the mutex between the call to m_thread_list_real.FindThreadByID(...)
// and the m_thread_list_real.AddThread(...) so it doesn't change on us
- Mutex::Locker locker (m_thread_list_real.GetMutex ());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
thread_sp = m_thread_list_real.FindThreadByProtocolID(tid, false);
if (!thread_sp)
@@ -2001,7 +2009,18 @@ ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid,
{
if (reason.compare("trace") == 0)
{
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+ lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
+
+ // If the current pc is a breakpoint site then the StopInfo should be set to Breakpoint
+ // Otherwise, it will be set to Trace.
+ if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get()))
+ {
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp, bp_site_sp->GetID()));
+ }
+ else
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
handled = true;
}
else if (reason.compare("breakpoint") == 0)
@@ -2040,7 +2059,8 @@ ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid,
{
WatchpointSP wp_sp;
ArchSpec::Core core = GetTarget().GetArchitecture().GetCore();
- if (core >= ArchSpec::kCore_mips_first && core <= ArchSpec::kCore_mips_last)
+ if ((core >= ArchSpec::kCore_mips_first && core <= ArchSpec::kCore_mips_last) ||
+ (core >= ArchSpec::eCore_arm_generic && core <= ArchSpec::eCore_arm_aarch64))
wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_hit_addr);
if (!wp_sp)
wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
@@ -2070,6 +2090,23 @@ ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid,
handled = true;
}
}
+ else if (!signo)
+ {
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+ lldb::BreakpointSiteSP bp_site_sp =
+ thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
+
+ // If the current pc is a breakpoint site then the StopInfo should be set to Breakpoint
+ // even though the remote stub did not set it as such. This can happen when
+ // the thread is involuntarily interrupted (e.g. due to stops on other
+ // threads) just as it is about to execute the breakpoint instruction.
+ if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get()))
+ {
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp, bp_site_sp->GetID()));
+ handled = true;
+ }
+ }
if (!handled && signo && did_exec == false)
{
@@ -2404,7 +2441,8 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
}
else if (key.compare("threads") == 0)
{
- Mutex::Locker locker(m_thread_list_real.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
+
m_thread_ids.clear();
// A comma separated list of all threads in the current
// process that includes the thread for this stop reply
@@ -2627,7 +2665,8 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
void
ProcessGDBRemote::RefreshStateAfterStop ()
{
- Mutex::Locker locker(m_thread_list_real.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
+
m_thread_ids.clear();
m_thread_pcs.clear();
// Set the thread stop info. It might have a "threads" key whose value is
@@ -2637,7 +2676,7 @@ ProcessGDBRemote::RefreshStateAfterStop ()
// Scope for the lock
{
// Lock the thread stack while we access it
- Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
// Get the number of stop packets on the stack
int nItems = m_stop_packet_stack.size();
// Iterate over them
@@ -2782,7 +2821,7 @@ ProcessGDBRemote::DoDestroy ()
ThreadList &threads = GetThreadList();
{
- Mutex::Locker locker(threads.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
size_t num_threads = threads.GetSize();
for (size_t i = 0; i < num_threads; i++)
@@ -2817,7 +2856,7 @@ ProcessGDBRemote::DoDestroy ()
// have to run the risk of letting those threads proceed a bit.
{
- Mutex::Locker locker(threads.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
size_t num_threads = threads.GetSize();
for (size_t i = 0; i < num_threads; i++)
@@ -2939,7 +2978,7 @@ ProcessGDBRemote::SetLastStopPacket (const StringExtractorGDBRemote &response)
// Scope the lock
{
// Lock the thread stack while we access it
- Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
// We are are not using non-stop mode, there can only be one last stop
// reply packet, so clear the list.
@@ -3119,35 +3158,33 @@ ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &er
Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_EXPRESSIONS));
addr_t allocated_addr = LLDB_INVALID_ADDRESS;
- LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory();
- switch (supported)
+ if (m_gdb_comm.SupportsAllocDeallocMemory() != eLazyBoolNo)
{
- case eLazyBoolCalculate:
- case eLazyBoolYes:
- allocated_addr = m_gdb_comm.AllocateMemory (size, permissions);
- if (allocated_addr != LLDB_INVALID_ADDRESS || supported == eLazyBoolYes)
- return allocated_addr;
+ allocated_addr = m_gdb_comm.AllocateMemory (size, permissions);
+ if (allocated_addr != LLDB_INVALID_ADDRESS || m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolYes)
+ return allocated_addr;
+ }
- case eLazyBoolNo:
- // Call mmap() to create memory in the inferior..
- unsigned prot = 0;
- if (permissions & lldb::ePermissionsReadable)
- prot |= eMmapProtRead;
- if (permissions & lldb::ePermissionsWritable)
- prot |= eMmapProtWrite;
- if (permissions & lldb::ePermissionsExecutable)
- prot |= eMmapProtExec;
-
- if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
- eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0))
- m_addr_to_mmap_size[allocated_addr] = size;
- else
- {
- allocated_addr = LLDB_INVALID_ADDRESS;
- if (log)
- log->Printf ("ProcessGDBRemote::%s no direct stub support for memory allocation, and InferiorCallMmap also failed - is stub missing register context save/restore capability?", __FUNCTION__);
- }
- break;
+ if (m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolNo)
+ {
+ // Call mmap() to create memory in the inferior..
+ unsigned prot = 0;
+ if (permissions & lldb::ePermissionsReadable)
+ prot |= eMmapProtRead;
+ if (permissions & lldb::ePermissionsWritable)
+ prot |= eMmapProtWrite;
+ if (permissions & lldb::ePermissionsExecutable)
+ prot |= eMmapProtExec;
+
+ if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
+ eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0))
+ m_addr_to_mmap_size[allocated_addr] = size;
+ else
+ {
+ allocated_addr = LLDB_INVALID_ADDRESS;
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s no direct stub support for memory allocation, and InferiorCallMmap also failed - is stub missing register context save/restore capability?", __FUNCTION__);
+ }
}
if (allocated_addr == LLDB_INVALID_ADDRESS)
@@ -3273,7 +3310,8 @@ ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware) && (!bp_site->HardwareRequired()))
{
// Try to send off a software breakpoint packet ($Z0)
- if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, true, addr, bp_op_size) == 0)
+ uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, true, addr, bp_op_size);
+ if (error_no == 0)
{
// The breakpoint was placed successfully
bp_site->SetEnabled(true);
@@ -3289,7 +3327,13 @@ ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
// with the error code. If they are now unsupported, then we would like to fall through
// and try another form of breakpoint.
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))
+ {
+ if (error_no != UINT8_MAX)
+ error.SetErrorStringWithFormat("error: %d sending the breakpoint request", errno);
+ else
+ error.SetErrorString("error sending the breakpoint request");
return error;
+ }
// We reach here when software breakpoints have been found to be unsupported. For future
// calls to set a breakpoint, we will not attempt to set a breakpoint with a type that is
@@ -3306,7 +3350,8 @@ ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware))
{
// Try to send off a hardware breakpoint packet ($Z1)
- if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, true, addr, bp_op_size) == 0)
+ uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, true, addr, bp_op_size);
+ if (error_no == 0)
{
// The breakpoint was placed successfully
bp_site->SetEnabled(true);
@@ -3318,7 +3363,13 @@ ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware))
{
// Unable to set this hardware breakpoint
- error.SetErrorString("failed to set hardware breakpoint (hardware breakpoint resources might be exhausted or unavailable)");
+ if (error_no != UINT8_MAX)
+ error.SetErrorStringWithFormat("error: %d sending the hardware breakpoint request "
+ "(hardware breakpoint resources might be exhausted or unavailable)",
+ error_no);
+ else
+ error.SetErrorString("error sending the hardware breakpoint request (hardware breakpoint resources "
+ "might be exhausted or unavailable)");
return error;
}
@@ -3550,6 +3601,8 @@ ProcessGDBRemote::EstablishConnectionIfNeeded (const ProcessInfo &process_info)
Error
ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info)
{
+ using namespace std::placeholders; // For _1, _2, etc.
+
Error error;
if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
{
@@ -3561,7 +3614,9 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
// special terminal key sequences (^C) don't affect debugserver.
debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);
- debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
+ const std::weak_ptr<ProcessGDBRemote> this_wp = std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
+ debugserver_launch_info.SetMonitorProcessCallback(std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3, _4),
+ false);
debugserver_launch_info.SetUserID(process_info.GetUserID());
#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
@@ -3623,91 +3678,58 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
}
bool
-ProcessGDBRemote::MonitorDebugserverProcess
-(
- void *callback_baton,
- lldb::pid_t debugserver_pid,
- bool exited, // True if the process did exit
- int signo, // Zero for no signal
- int exit_status // Exit value of process if signal is zero
-)
+ProcessGDBRemote::MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t debugserver_pid,
+ bool exited, // True if the process did exit
+ int signo, // Zero for no signal
+ int exit_status // Exit value of process if signal is zero
+ )
{
- // The baton is a "ProcessGDBRemote *". Now this class might be gone
- // and might not exist anymore, so we need to carefully try to get the
- // target for this process first since we have a race condition when
- // we are done running between getting the notice that the inferior
- // process has died and the debugserver that was debugging this process.
- // In our test suite, we are also continually running process after
- // process, so we must be very careful to make sure:
- // 1 - process object hasn't been deleted already
- // 2 - that a new process object hasn't been recreated in its place
-
// "debugserver_pid" argument passed in is the process ID for
// debugserver that we are tracking...
Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ const bool handled = true;
- ProcessGDBRemote *process = (ProcessGDBRemote *)callback_baton;
-
- // Get a shared pointer to the target that has a matching process pointer.
- // This target could be gone, or the target could already have a new process
- // object inside of it
- TargetSP target_sp (Debugger::FindTargetWithProcess(process));
+ if (log)
+ log->Printf("ProcessGDBRemote::%s(process_wp, pid=%" PRIu64 ", signo=%i (0x%x), exit_status=%i)", __FUNCTION__,
+ debugserver_pid, signo, signo, exit_status);
+ std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
if (log)
- log->Printf ("ProcessGDBRemote::MonitorDebugserverProcess (baton=%p, pid=%" PRIu64 ", signo=%i (0x%x), exit_status=%i)", callback_baton, debugserver_pid, signo, signo, exit_status);
-
- if (target_sp)
- {
- // We found a process in a target that matches, but another thread
- // might be in the process of launching a new process that will
- // soon replace it, so get a shared pointer to the process so we
- // can keep it alive.
- ProcessSP process_sp (target_sp->GetProcessSP());
- // Now we have a shared pointer to the process that can't go away on us
- // so we now make sure it was the same as the one passed in, and also make
- // sure that our previous "process *" didn't get deleted and have a new
- // "process *" created in its place with the same pointer. To verify this
- // we make sure the process has our debugserver process ID. If we pass all
- // of these tests, then we are sure that this process is the one we were
- // looking for.
- if (process_sp && process == process_sp.get() && process->m_debugserver_pid == debugserver_pid)
+ log->Printf("ProcessGDBRemote::%s(process = %p)", __FUNCTION__, static_cast<void *>(process_sp.get()));
+ if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
+ return handled;
+
+ // Sleep for a half a second to make sure our inferior process has
+ // time to set its exit status before we set it incorrectly when
+ // both the debugserver and the inferior process shut down.
+ usleep(500000);
+ // If our process hasn't yet exited, debugserver might have died.
+ // If the process did exit, then we are reaping it.
+ const StateType state = process_sp->GetState();
+
+ if (state != eStateInvalid && state != eStateUnloaded && state != eStateExited && state != eStateDetached)
+ {
+ char error_str[1024];
+ if (signo)
{
- // Sleep for a half a second to make sure our inferior process has
- // time to set its exit status before we set it incorrectly when
- // both the debugserver and the inferior process shut down.
- usleep (500000);
- // If our process hasn't yet exited, debugserver might have died.
- // If the process did exit, the we are reaping it.
- const StateType state = process->GetState();
-
- if (process->m_debugserver_pid != LLDB_INVALID_PROCESS_ID &&
- state != eStateInvalid &&
- state != eStateUnloaded &&
- state != eStateExited &&
- state != eStateDetached)
- {
- char error_str[1024];
- if (signo)
- {
- const char *signal_cstr = process->GetUnixSignals()->GetSignalAsCString(signo);
- if (signal_cstr)
- ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
- else
- ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
- }
- else
- {
- ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x", exit_status);
- }
-
- process->SetExitStatus (-1, error_str);
- }
- // Debugserver has exited we need to let our ProcessGDBRemote
- // know that it no longer has a debugserver instance
- process->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ const char *signal_cstr = process_sp->GetUnixSignals()->GetSignalAsCString(signo);
+ if (signal_cstr)
+ ::snprintf(error_str, sizeof(error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
+ else
+ ::snprintf(error_str, sizeof(error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
}
+ else
+ {
+ ::snprintf(error_str, sizeof(error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x",
+ exit_status);
+ }
+
+ process_sp->SetExitStatus(-1, error_str);
}
- return true;
+ // Debugserver has exited we need to let our ProcessGDBRemote
+ // know that it no longer has a debugserver instance
+ process_sp->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ return handled;
}
void
@@ -3756,7 +3778,7 @@ ProcessGDBRemote::StartAsyncThread ()
if (log)
log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
- Mutex::Locker start_locker(m_async_thread_state_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
if (!m_async_thread.IsJoinable())
{
// Create a thread that watches our internal state and controls which
@@ -3778,7 +3800,7 @@ ProcessGDBRemote::StopAsyncThread ()
if (log)
log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
- Mutex::Locker start_locker(m_async_thread_state_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
if (m_async_thread.IsJoinable())
{
m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
@@ -3838,7 +3860,7 @@ ProcessGDBRemote::AsyncThread (void *arg)
{
if (log)
log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
- if (process->m_async_listener.WaitForEvent (NULL, event_sp))
+ if (process->m_async_listener_sp->WaitForEvent (NULL, event_sp))
{
const uint32_t event_type = event_sp->GetType();
if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
@@ -4153,6 +4175,7 @@ ProcessGDBRemote::GetExtendedInfoForThread (lldb::tid_t tid)
packet << (char) (0x7d ^ 0x20);
StringExtractorGDBRemote response;
+ response.SetResponseValidatorToJSON();
if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, false) == GDBRemoteCommunication::PacketResult::Success)
{
StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType();
@@ -4194,6 +4217,7 @@ ProcessGDBRemote::GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_addres
packet << (char) (0x7d ^ 0x20);
StringExtractorGDBRemote response;
+ response.SetResponseValidatorToJSON();
if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, false) == GDBRemoteCommunication::PacketResult::Success)
{
StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType();
@@ -4336,14 +4360,11 @@ struct GdbServerTargetInfo
};
bool
-ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp)
+ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp, uint32_t &cur_reg_num, uint32_t &reg_offset)
{
if (!feature_node)
return false;
- uint32_t cur_reg_num = 0;
- uint32_t reg_offset = 0;
-
feature_node.ForEachChildElementWithName("reg", [&target_info, &dyn_reg_info, &cur_reg_num, &reg_offset, &abi_sp](const XMLNode &reg_node) -> bool {
std::string gdb_group;
std::string gdb_type;
@@ -4520,7 +4541,7 @@ ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemot
// return: 'true' on success
// 'false' on failure
bool
-ProcessGDBRemote::GetGDBServerRegisterInfo ()
+ProcessGDBRemote::GetGDBServerRegisterInfo (ArchSpec &arch_to_use)
{
// Make sure LLDB has an XML parser it can use first
if (!XMLDocument::XMLEnabled())
@@ -4599,9 +4620,16 @@ ProcessGDBRemote::GetGDBServerRegisterInfo ()
return true; // Keep iterating through all children of the target_node
});
+ // Initialize these outside of ParseRegisters, since they should not be reset inside each include feature
+ uint32_t cur_reg_num = 0;
+ uint32_t reg_offset = 0;
+
+ // Don't use Process::GetABI, this code gets called from DidAttach, and in that context we haven't
+ // set the Target's architecture yet, so the ABI is also potentially incorrect.
+ ABISP abi_to_use_sp = ABI::FindPlugin(arch_to_use);
if (feature_node)
{
- ParseRegisters(feature_node, target_info, this->m_register_info, GetABI());
+ ParseRegisters(feature_node, target_info, this->m_register_info, abi_to_use_sp, cur_reg_num, reg_offset);
}
for (const auto &include : target_info.includes)
@@ -4619,10 +4647,10 @@ ProcessGDBRemote::GetGDBServerRegisterInfo ()
XMLNode include_feature_node = include_xml_document.GetRootElement("feature");
if (include_feature_node)
{
- ParseRegisters(include_feature_node, target_info, this->m_register_info, GetABI());
+ ParseRegisters(include_feature_node, target_info, this->m_register_info, abi_to_use_sp, cur_reg_num, reg_offset);
}
}
- this->m_register_info.Finalize(GetTarget().GetArchitecture());
+ this->m_register_info.Finalize(arch_to_use);
}
}
@@ -4784,25 +4812,14 @@ ProcessGDBRemote::GetLoadedModuleList (LoadedModuleInfoList & list)
}
lldb::ModuleSP
-ProcessGDBRemote::LoadModuleAtAddress (const FileSpec &file, lldb::addr_t base_addr, bool value_is_offset)
+ProcessGDBRemote::LoadModuleAtAddress (const FileSpec &file, lldb::addr_t link_map,
+ lldb::addr_t base_addr, bool value_is_offset)
{
- Target &target = m_process->GetTarget();
- ModuleList &modules = target.GetImages();
- ModuleSP module_sp;
-
- bool changed = false;
-
- ModuleSpec module_spec (file, target.GetArchitecture());
- if ((module_sp = modules.FindFirstModule (module_spec)))
- {
- module_sp->SetLoadAddress (target, base_addr, value_is_offset, changed);
- }
- else if ((module_sp = target.GetSharedModule (module_spec)))
- {
- module_sp->SetLoadAddress (target, base_addr, value_is_offset, changed);
- }
+ DynamicLoader *loader = GetDynamicLoader();
+ if (!loader)
+ return nullptr;
- return module_sp;
+ return loader->LoadModuleAtAddress(file, link_map, base_addr, value_is_offset);
}
size_t
@@ -4821,6 +4838,7 @@ ProcessGDBRemote::LoadModules (LoadedModuleInfoList &module_list)
{
std::string mod_name;
lldb::addr_t mod_base;
+ lldb::addr_t link_map;
bool mod_base_is_offset;
bool valid = true;
@@ -4830,15 +4848,12 @@ ProcessGDBRemote::LoadModules (LoadedModuleInfoList &module_list)
if (!valid)
continue;
- // hack (cleaner way to get file name only?) (win/unix compat?)
- size_t marker = mod_name.rfind ('/');
- if (marker == std::string::npos)
- marker = 0;
- else
- marker += 1;
+ if (!modInfo.get_link_map (link_map))
+ link_map = LLDB_INVALID_ADDRESS;
- FileSpec file (mod_name.c_str()+marker, true);
- lldb::ModuleSP module_sp = LoadModuleAtAddress (file, mod_base, mod_base_is_offset);
+ FileSpec file (mod_name.c_str(), true);
+ lldb::ModuleSP module_sp = LoadModuleAtAddress (file, link_map, mod_base,
+ mod_base_is_offset);
if (module_sp.get())
new_modules.Append (module_sp);
@@ -4846,7 +4861,30 @@ ProcessGDBRemote::LoadModules (LoadedModuleInfoList &module_list)
if (new_modules.GetSize() > 0)
{
+ ModuleList removed_modules;
Target &target = GetTarget();
+ ModuleList &loaded_modules = m_process->GetTarget().GetImages();
+
+ for (size_t i = 0; i < loaded_modules.GetSize(); ++i)
+ {
+ const lldb::ModuleSP loaded_module = loaded_modules.GetModuleAtIndex(i);
+
+ bool found = false;
+ for (size_t j = 0; j < new_modules.GetSize(); ++j)
+ {
+ if (new_modules.GetModuleAtIndex(j).get() == loaded_module.get())
+ found = true;
+ }
+
+ // The main executable will never be included in libraries-svr4, don't remove it
+ if (!found && loaded_module.get() != target.GetExecutableModulePointer())
+ {
+ removed_modules.Append (loaded_module);
+ }
+ }
+
+ loaded_modules.Remove (removed_modules);
+ m_process->GetTarget().ModulesDidUnload (removed_modules, false);
new_modules.ForEach ([&target](const lldb::ModuleSP module_sp) -> bool
{
@@ -4862,13 +4900,11 @@ ProcessGDBRemote::LoadModules (LoadedModuleInfoList &module_list)
return false;
});
- ModuleList &loaded_modules = m_process->GetTarget().GetImages();
loaded_modules.AppendIfNeeded (new_modules);
m_process->GetTarget().ModulesDidLoad (new_modules);
}
return new_modules.GetSize();
-
}
size_t
@@ -5230,11 +5266,9 @@ public:
class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword
{
public:
- CommandObjectMultiwordProcessGDBRemote (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "process plugin",
- "A set of commands for operating on a ProcessGDBRemote process.",
- "process plugin <subcommand> [<subcommand-options>]")
+ CommandObjectMultiwordProcessGDBRemote(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "process plugin", "Commands for operating on a ProcessGDBRemote process.",
+ "process plugin <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessGDBRemotePacket (interpreter)));
}
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index b48edd836a74..6d373965fc42 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -14,6 +14,7 @@
// C++ Includes
#include <atomic>
#include <map>
+#include <mutex>
#include <string>
#include <vector>
@@ -45,13 +46,13 @@ class ThreadGDBRemote;
class ProcessGDBRemote : public Process
{
public:
- ProcessGDBRemote(lldb::TargetSP target_sp, Listener &listener);
+ ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
~ProcessGDBRemote() override;
static lldb::ProcessSP
CreateInstance (lldb::TargetSP target_sp,
- Listener &listener,
+ lldb::ListenerSP listener_sp,
const FileSpec *crash_file_path);
static void
@@ -279,12 +280,12 @@ protected:
GDBRemoteCommunicationClient m_gdb_comm;
std::atomic<lldb::pid_t> m_debugserver_pid;
std::vector<StringExtractorGDBRemote> m_stop_packet_stack; // The stop packet stack replaces the last stop packet variable
- Mutex m_last_stop_packet_mutex;
+ std::recursive_mutex m_last_stop_packet_mutex;
GDBRemoteDynamicRegisterInfo m_register_info;
Broadcaster m_async_broadcaster;
- Listener m_async_listener;
+ lldb::ListenerSP m_async_listener_sp;
HostThread m_async_thread;
- Mutex m_async_thread_state_mutex;
+ std::recursive_mutex m_async_thread_state_mutex;
typedef std::vector<lldb::tid_t> tid_collection;
typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;
typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
@@ -405,11 +406,8 @@ protected:
AsyncThread (void *arg);
static bool
- MonitorDebugserverProcess (void *callback_baton,
- lldb::pid_t pid,
- bool exited,
- int signo,
- int exit_status);
+ MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t pid, bool exited, int signo,
+ int exit_status);
lldb::StateType
SetThreadStopInfo (StringExtractor& stop_packet);
@@ -461,14 +459,15 @@ protected:
// Query remote GDBServer for register information
bool
- GetGDBServerRegisterInfo ();
+ GetGDBServerRegisterInfo (ArchSpec &arch);
// Query remote GDBServer for a detailed loaded library list
Error
GetLoadedModuleList (LoadedModuleInfoList &);
lldb::ModuleSP
- LoadModuleAtAddress (const FileSpec &file, lldb::addr_t base_addr, bool value_is_offset);
+ LoadModuleAtAddress (const FileSpec &file, lldb::addr_t link_map, lldb::addr_t base_addr,
+ bool value_is_offset);
private:
//------------------------------------------------------------------
diff --git a/source/Plugins/Process/mach-core/Makefile b/source/Plugins/Process/mach-core/Makefile
deleted file mode 100644
index 6db849872267..000000000000
--- a/source/Plugins/Process/mach-core/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/Process/mach-core/Makefile -----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginProcessMachCore
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index b199ec606367..6bf198ca2f37 100644
--- a/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -18,13 +18,15 @@
// Other libraries and framework includes
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Debugger.h"
-#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
@@ -64,7 +66,7 @@ ProcessMachCore::Terminate()
lldb::ProcessSP
-ProcessMachCore::CreateInstance (lldb::TargetSP target_sp, Listener &listener, const FileSpec *crash_file)
+ProcessMachCore::CreateInstance (lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec *crash_file)
{
lldb::ProcessSP process_sp;
if (crash_file)
@@ -80,7 +82,7 @@ ProcessMachCore::CreateInstance (lldb::TargetSP target_sp, Listener &listener, c
if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header))
{
if (mach_header.filetype == llvm::MachO::MH_CORE)
- process_sp.reset(new ProcessMachCore (target_sp, listener, *crash_file));
+ process_sp.reset(new ProcessMachCore (target_sp, listener_sp, *crash_file));
}
}
@@ -121,14 +123,15 @@ ProcessMachCore::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_nam
//----------------------------------------------------------------------
// ProcessMachCore constructor
//----------------------------------------------------------------------
-ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp, Listener &listener, const FileSpec &core_file) :
- Process (target_sp, listener),
- m_core_aranges (),
- m_core_module_sp (),
- m_core_file (core_file),
- m_dyld_addr (LLDB_INVALID_ADDRESS),
- m_mach_kernel_addr (LLDB_INVALID_ADDRESS),
- m_dyld_plugin_name ()
+ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec &core_file)
+ : Process(target_sp, listener_sp),
+ m_core_aranges(),
+ m_core_range_infos(),
+ m_core_module_sp(),
+ m_core_file(core_file),
+ m_dyld_addr(LLDB_INVALID_ADDRESS),
+ m_mach_kernel_addr(LLDB_INVALID_ADDRESS),
+ m_dyld_plugin_name()
{
}
@@ -163,6 +166,7 @@ ProcessMachCore::GetPluginVersion()
bool
ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr)
{
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_PROCESS));
llvm::MachO::mach_header header;
Error error;
if (DoReadMemory (addr, &header, sizeof(header), error) != sizeof(header))
@@ -194,6 +198,8 @@ ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr)
case llvm::MachO::MH_DYLINKER:
//printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
// Address of dyld "struct mach_header" in the core file
+ if (log)
+ log->Printf ("ProcessMachCore::GetDynamicLoaderAddress found a user process dyld binary image at 0x%" PRIx64, addr);
m_dyld_addr = addr;
return true;
@@ -203,6 +209,8 @@ ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr)
// is NOT set. If it isn't, then we have a mach_kernel.
if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0)
{
+ if (log)
+ log->Printf ("ProcessMachCore::GetDynamicLoaderAddress found a mach kernel binary image at 0x%" PRIx64, addr);
// Address of the mach kernel "struct mach_header" in the core file.
m_mach_kernel_addr = addr;
return true;
@@ -219,6 +227,7 @@ ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr)
Error
ProcessMachCore::DoLoadCore ()
{
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_PROCESS));
Error error;
if (!m_core_module_sp)
{
@@ -297,11 +306,21 @@ ProcessMachCore::DoLoadCore ()
{
m_core_aranges.Append(range_entry);
}
+ // Some core files don't fill in the permissions correctly. If that is the case
+ // assume read + execute so clients don't think the memory is not readable,
+ // or executable. The memory isn't writable since this plug-in doesn't implement
+ // DoWriteMemory.
+ uint32_t permissions = section->GetPermissions();
+ if (permissions == 0)
+ permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
+ m_core_range_infos.Append(
+ VMRangeToPermissions::Entry(section_vm_addr, section->GetByteSize(), permissions));
}
}
if (!ranges_are_sorted)
{
m_core_aranges.Sort();
+ m_core_range_infos.Sort();
}
if (m_dyld_addr == LLDB_INVALID_ADDRESS || m_mach_kernel_addr == LLDB_INVALID_ADDRESS)
@@ -314,9 +333,7 @@ ProcessMachCore::DoLoadCore ()
// later if both are present.
const size_t num_core_aranges = m_core_aranges.GetSize();
- for (size_t i = 0;
- i < num_core_aranges && (m_dyld_addr == LLDB_INVALID_ADDRESS || m_mach_kernel_addr == LLDB_INVALID_ADDRESS);
- ++i)
+ for (size_t i = 0; i < num_core_aranges; ++i)
{
const VMRangeToFileOffset::Entry *entry = m_core_aranges.GetEntryAtIndex(i);
lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
@@ -330,16 +347,58 @@ ProcessMachCore::DoLoadCore ()
}
}
+
+ if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
+ {
+ // In the case of multiple kernel images found in the core file via exhaustive
+ // search, we may not pick the correct one. See if the DynamicLoaderDarwinKernel's
+ // search heuristics might identify the correct one.
+ // Most of the time, I expect the address from SearchForDarwinKernel() will be the
+ // same as the address we found via exhaustive search.
+
+ if (GetTarget().GetArchitecture().IsValid() == false && m_core_module_sp.get())
+ {
+ GetTarget().SetArchitecture (m_core_module_sp->GetArchitecture());
+ }
+
+ // SearchForDarwinKernel will end up calling back into this this class in the GetImageInfoAddress
+ // method which will give it the m_mach_kernel_addr/m_dyld_addr it already has. Save that aside
+ // and set m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily so
+ // DynamicLoaderDarwinKernel does a real search for the kernel using its own heuristics.
+
+ addr_t saved_mach_kernel_addr = m_mach_kernel_addr;
+ addr_t saved_user_dyld_addr = m_dyld_addr;
+ m_mach_kernel_addr = LLDB_INVALID_ADDRESS;
+ m_dyld_addr = LLDB_INVALID_ADDRESS;
+
+ addr_t better_kernel_address = DynamicLoaderDarwinKernel::SearchForDarwinKernel (this);
+
+ m_mach_kernel_addr = saved_mach_kernel_addr;
+ m_dyld_addr = saved_user_dyld_addr;
+
+ if (better_kernel_address != LLDB_INVALID_ADDRESS)
+ {
+ if (log)
+ log->Printf ("ProcessMachCore::DoLoadCore: Using the kernel address from DynamicLoaderDarwinKernel");
+ m_mach_kernel_addr = better_kernel_address;
+ }
+ }
+
+
// If we found both a user-process dyld and a kernel binary, we need to decide
// which to prefer.
if (GetCorefilePreference() == eKernelCorefile)
{
if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
{
+ if (log)
+ log->Printf ("ProcessMachCore::DoLoadCore: Using kernel corefile image at 0x%" PRIx64, m_mach_kernel_addr);
m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
}
else if (m_dyld_addr != LLDB_INVALID_ADDRESS)
{
+ if (log)
+ log->Printf ("ProcessMachCore::DoLoadCore: Using user process dyld image at 0x%" PRIx64, m_dyld_addr);
m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
}
}
@@ -347,10 +406,14 @@ ProcessMachCore::DoLoadCore ()
{
if (m_dyld_addr != LLDB_INVALID_ADDRESS)
{
+ if (log)
+ log->Printf ("ProcessMachCore::DoLoadCore: Using user process dyld image at 0x%" PRIx64, m_dyld_addr);
m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
}
else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
{
+ if (log)
+ log->Printf ("ProcessMachCore::DoLoadCore: Using kernel corefile image at 0x%" PRIx64, m_mach_kernel_addr);
m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
}
}
@@ -450,25 +513,95 @@ size_t
ProcessMachCore::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
{
ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+ size_t bytes_read = 0;
if (core_objfile)
{
- const VMRangeToFileOffset::Entry *core_memory_entry = m_core_aranges.FindEntryThatContains (addr);
- if (core_memory_entry)
+ //----------------------------------------------------------------------
+ // Segments are not always contiguous in mach-o core files. We have core
+ // files that have segments like:
+ // Address Size File off File size
+ // ---------- ---------- ---------- ----------
+ // LC_SEGMENT 0x000f6000 0x00001000 0x1d509ee8 0x00001000 --- --- 0 0x00000000 __TEXT
+ // LC_SEGMENT 0x0f600000 0x00100000 0x1d50aee8 0x00100000 --- --- 0 0x00000000 __TEXT
+ // LC_SEGMENT 0x000f7000 0x00001000 0x1d60aee8 0x00001000 --- --- 0 0x00000000 __TEXT
+ //
+ // Any if the user executes the following command:
+ //
+ // (lldb) mem read 0xf6ff0
+ //
+ // We would attempt to read 32 bytes from 0xf6ff0 but would only
+ // get 16 unless we loop through consecutive memory ranges that are
+ // contiguous in the address space, but not in the file data.
+ //----------------------------------------------------------------------
+ while (bytes_read < size)
{
- const addr_t offset = addr - core_memory_entry->GetRangeBase();
- const addr_t bytes_left = core_memory_entry->GetRangeEnd() - addr;
- size_t bytes_to_read = size;
- if (bytes_to_read > bytes_left)
- bytes_to_read = bytes_left;
- return core_objfile->CopyData (core_memory_entry->data.GetRangeBase() + offset, bytes_to_read, buf);
+ const addr_t curr_addr = addr + bytes_read;
+ const VMRangeToFileOffset::Entry *core_memory_entry = m_core_aranges.FindEntryThatContains(curr_addr);
+
+ if (core_memory_entry)
+ {
+ const addr_t offset = curr_addr - core_memory_entry->GetRangeBase();
+ const addr_t bytes_left = core_memory_entry->GetRangeEnd() - curr_addr;
+ const size_t bytes_to_read = std::min(size - bytes_read, (size_t)bytes_left);
+ const size_t curr_bytes_read = core_objfile->CopyData(core_memory_entry->data.GetRangeBase() + offset,
+ bytes_to_read, (char *)buf + bytes_read);
+ if (curr_bytes_read == 0)
+ break;
+ bytes_read += curr_bytes_read;
+ }
+ else
+ {
+ // Only set the error if we didn't read any bytes
+ if (bytes_read == 0)
+ error.SetErrorStringWithFormat("core file does not contain 0x%" PRIx64, curr_addr);
+ break;
+ }
}
- else
+ }
+
+ return bytes_read;
+}
+
+Error
+ProcessMachCore::GetMemoryRegionInfo(addr_t load_addr, MemoryRegionInfo &region_info)
+{
+ region_info.Clear();
+ const VMRangeToPermissions::Entry *permission_entry = m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
+ if (permission_entry)
+ {
+ if (permission_entry->Contains(load_addr))
{
- error.SetErrorStringWithFormat ("core file does not contain 0x%" PRIx64, addr);
+ region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
+ region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
+ const Flags permissions(permission_entry->data);
+ region_info.SetReadable(permissions.Test(ePermissionsReadable) ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetWritable(permissions.Test(ePermissionsWritable) ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetExecutable(permissions.Test(ePermissionsExecutable) ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eYes);
}
+ else if (load_addr < permission_entry->GetRangeBase())
+ {
+ region_info.GetRange().SetRangeBase(load_addr);
+ region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
+ }
+ return Error();
}
- return 0;
+
+ region_info.GetRange().SetRangeBase(load_addr);
+ region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
+ return Error();
}
void
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.h b/source/Plugins/Process/mach-core/ProcessMachCore.h
index 2de0b772370c..21a0083b2d12 100644
--- a/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ b/source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -30,14 +30,14 @@ public:
// Constructors and Destructors
//------------------------------------------------------------------
ProcessMachCore(lldb::TargetSP target_sp,
- lldb_private::Listener &listener,
+ lldb::ListenerSP listener,
const lldb_private::FileSpec &core_file);
~ProcessMachCore() override;
static lldb::ProcessSP
CreateInstance (lldb::TargetSP target_sp,
- lldb_private::Listener &listener,
+ lldb::ListenerSP listener,
const lldb_private::FileSpec *crash_file_path);
static void
@@ -103,7 +103,10 @@ public:
size_t
DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
-
+
+ lldb_private::Error
+ GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &region_info) override;
+
lldb::addr_t
GetImageInfoAddress () override;
@@ -131,7 +134,7 @@ private:
///
/// If a core file contains both a kernel binary and a user-process
/// dynamic loader, lldb needs to pick one over the other. This could
- /// be a kernel corefile that happens to have a coyp of dyld in its
+ /// be a kernel corefile that happens to have a copy of dyld in its
/// memory. Or it could be a user process coredump of lldb while doing
/// kernel debugging - so a copy of the kernel is in its heap. This
/// should become a setting so it can be over-ridden when necessary.
@@ -150,8 +153,10 @@ private:
//------------------------------------------------------------------
typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange> VMRangeToFileOffset;
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> VMRangeToPermissions;
VMRangeToFileOffset m_core_aranges;
+ VMRangeToPermissions m_core_range_infos;
lldb::ModuleSP m_core_module_sp;
lldb_private::FileSpec m_core_file;
lldb::addr_t m_dyld_addr;
diff --git a/source/Plugins/ScriptInterpreter/None/Makefile b/source/Plugins/ScriptInterpreter/None/Makefile
deleted file mode 100644
index 1e2523198520..000000000000
--- a/source/Plugins/ScriptInterpreter/None/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ScriptInterpreter/None/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginScriptInterpreterNone
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ScriptInterpreter/Python/Makefile b/source/Plugins/ScriptInterpreter/Python/Makefile
deleted file mode 100644
index cf605014d458..000000000000
--- a/source/Plugins/ScriptInterpreter/Python/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/ScriptInterpreter/Python/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginScriptInterpreterPython
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 23bacc932c03..1fdf4c70a5dc 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -19,10 +19,15 @@
#include "lldb/Core/Stream.h"
#include "lldb/Host/File.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "llvm/Support/ConvertUTF.h"
+
#include <stdio.h>
+#include "llvm/ADT/StringSwitch.h"
+
using namespace lldb_private;
using namespace lldb;
@@ -81,6 +86,8 @@ PythonObject::GetObjectType() const
if (PythonBytes::Check(m_py_obj))
return PyObjectType::Bytes;
#endif
+ if (PythonByteArray::Check(m_py_obj))
+ return PyObjectType::ByteArray;
if (PythonInteger::Check(m_py_obj))
return PyObjectType::Integer;
if (PythonFile::Check(m_py_obj))
@@ -216,6 +223,8 @@ PythonObject::CreateStructuredObject() const
return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
case PyObjectType::Bytes:
return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
+ case PyObjectType::ByteArray:
+ return PythonByteArray(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
case PyObjectType::None:
return StructuredData::ObjectSP();
default:
@@ -321,6 +330,87 @@ PythonBytes::CreateStructuredString() const
return result;
}
+PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes) : PythonByteArray(bytes.data(), bytes.size())
+{
+}
+
+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);
+}
+
+PythonByteArray::PythonByteArray(const PythonBytes &object) : PythonObject(object)
+{
+}
+
+PythonByteArray::~PythonByteArray()
+{
+}
+
+bool
+PythonByteArray::Check(PyObject *py_obj)
+{
+ if (!py_obj)
+ return false;
+ if (PyByteArray_Check(py_obj))
+ return true;
+ return false;
+}
+
+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>();
+
+ char *c = PyByteArray_AsString(m_py_obj);
+ size_t size = GetSize();
+ return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
+}
+
+size_t
+PythonByteArray::GetSize() const
+{
+ if (!IsValid())
+ return 0;
+
+ return PyByteArray_Size(m_py_obj);
+}
+
+StructuredData::StringSP
+PythonByteArray::CreateStructuredString() const
+{
+ StructuredData::StringSP result(new StructuredData::String);
+ llvm::ArrayRef<uint8_t> bytes = GetBytes();
+ const char *str = reinterpret_cast<const char *>(bytes.data());
+ result->SetValue(std::string(str, bytes.size()));
+ return result;
+}
+
//----------------------------------------------------------------------
// PythonString
//----------------------------------------------------------------------
@@ -1019,13 +1109,37 @@ PythonCallable::Reset(PyRefType type, PyObject *py_obj)
PythonCallable::ArgInfo
PythonCallable::GetNumArguments() const
{
- ArgInfo result = { 0, false, false };
+ ArgInfo result = { 0, false, false, false };
if (!IsValid())
return result;
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;
+ }
+ else
+ {
+ // see if this is a callable object with an __call__ method
+ if (!PyFunction_Check(py_func_obj))
+ {
+ PythonObject __call__ = GetAttributeValue("__call__");
+ if (__call__.IsValid())
+ {
+ auto __callable__ = __call__.AsType<PythonCallable>();
+ if (__callable__.IsValid())
+ {
+ py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
+ PythonObject im_self = GetAttributeValue("im_self");
+ if (im_self.IsValid() && !im_self.IsNone())
+ result.is_bound_method = true;
+ }
+ }
+ }
+ }
if (!py_func_obj)
return result;
@@ -1075,9 +1189,7 @@ PythonFile::PythonFile(File &file, const char *mode)
PythonFile::PythonFile(const char *path, const char *mode)
{
- FILE *fp = nullptr;
- fp = fopen(path, mode);
- lldb_private::File file(fp, true);
+ lldb_private::File file(path, GetOptionsFromMode(mode));
Reset(file, mode);
}
@@ -1156,6 +1268,22 @@ PythonFile::Reset(File &file, const char *mode)
#endif
}
+uint32_t
+PythonFile::GetOptionsFromMode(llvm::StringRef mode)
+{
+ if (mode.empty())
+ return 0;
+
+ return llvm::StringSwitch<uint32_t>(mode.str().c_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);
+}
+
bool
PythonFile::GetUnderlyingFile(File &file) const
{
@@ -1166,6 +1294,8 @@ PythonFile::GetUnderlyingFile(File &file) const
// 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();
}
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index 06264b66c283..78245a98d0b8 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -75,6 +75,7 @@ enum class PyObjectType
List,
String,
Bytes,
+ ByteArray,
Module,
Callable,
Tuple,
@@ -293,6 +294,39 @@ public:
CreateStructuredString() const;
};
+class PythonByteArray : public PythonObject
+{
+public:
+ PythonByteArray();
+ 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;
+
+ void
+ SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
+
+ StructuredData::StringSP
+ CreateStructuredString() const;
+};
+
class PythonString : public PythonObject
{
public:
@@ -468,6 +502,7 @@ class PythonCallable : public PythonObject
public:
struct ArgInfo {
size_t count;
+ bool is_bound_method : 1;
bool has_varargs : 1;
bool has_kwargs : 1;
};
@@ -525,6 +560,8 @@ class PythonFile : public PythonObject
void Reset(PyRefType type, PyObject *py_obj) override;
void Reset(File &file, const char *mode);
+ static uint32_t GetOptionsFromMode(llvm::StringRef mode);
+
bool GetUnderlyingFile(File &file) const;
};
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 19ad86db240a..788167370593 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -146,7 +146,7 @@ private:
size_t size = 0;
static wchar_t *g_python_home = Py_DecodeLocale(LLDB_PYTHON_HOME, &size);
#else
- static char *g_python_home = LLDB_PYTHON_HOME;
+ static char g_python_home[] = LLDB_PYTHON_HOME;
#endif
Py_SetPythonHome(g_python_home);
#endif
@@ -274,7 +274,7 @@ ScriptInterpreterPython::ScriptInterpreterPython(CommandInterpreter &interpreter
m_lock_count(0),
m_command_thread_state(nullptr)
{
- assert(g_initialized && "ScriptInterpreterPython created but InitializePrivate has not been called!");
+ InitializePrivate();
m_dictionary_name.append("_dict");
StreamString run_string;
@@ -330,8 +330,6 @@ ScriptInterpreterPython::Initialize()
std::call_once(g_once_flag, []()
{
- InitializePrivate();
-
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(),
lldb::eScriptLanguagePython,
@@ -547,6 +545,27 @@ ScriptInterpreterPython::LeaveSession ()
}
bool
+ScriptInterpreterPython::SetStdHandle(File &file, const char *py_name, PythonFile &save_file, const char *mode)
+{
+ if (file.IsValid())
+ {
+ // Flush the file before giving it to python to avoid interleaved output.
+ file.Flush();
+
+ PythonDictionary &sys_module_dict = GetSysModuleDictionary();
+
+ save_file = sys_module_dict.GetItemForKey(PythonString(py_name)).AsType<PythonFile>();
+
+ PythonFile new_file(file, mode);
+ sys_module_dict.SetItemForKey(PythonString(py_name), new_file);
+ return true;
+ }
+ else
+ save_file.Reset();
+ return false;
+}
+
+bool
ScriptInterpreterPython::EnterSession (uint16_t on_entry_flags,
FILE *in,
FILE *out,
@@ -604,54 +623,31 @@ ScriptInterpreterPython::EnterSession (uint16_t on_entry_flags,
if (!in_file.IsValid() || !out_file.IsValid() || !err_file.IsValid())
m_interpreter.GetDebugger().AdoptTopIOHandlerFilesIfInvalid (in_sp, out_sp, err_sp);
- m_saved_stdin.Reset();
- if ((on_entry_flags & Locker::NoSTDIN) == 0)
+ if (on_entry_flags & Locker::NoSTDIN)
+ {
+ m_saved_stdin.Reset();
+ }
+ else
{
- // STDIN is enabled
- if (!in_file.IsValid() && in_sp)
- in_file = in_sp->GetFile();
- if (in_file.IsValid())
+ if (!SetStdHandle(in_file, "stdin", m_saved_stdin, "r"))
{
- // Flush the file before giving it to python to avoid interleaved output.
- in_file.Flush();
-
- m_saved_stdin = sys_module_dict.GetItemForKey(PythonString("stdin")).AsType<PythonFile>();
- // This call can deadlock your process if the file is locked
- PythonFile new_file(in_file, "r");
- sys_module_dict.SetItemForKey (PythonString("stdin"), new_file);
+ if (in_sp)
+ SetStdHandle(in_sp->GetFile(), "stdin", m_saved_stdin, "r");
}
}
- if (!out_file.IsValid() && out_sp)
- out_file = out_sp->GetFile();
- if (out_file.IsValid())
+ if (!SetStdHandle(out_file, "stdout", m_saved_stdout, "w"))
{
- // Flush the file before giving it to python to avoid interleaved output.
- out_file.Flush();
-
- m_saved_stdout = sys_module_dict.GetItemForKey(PythonString("stdout")).AsType<PythonFile>();
-
- PythonFile new_file(out_file, "w");
- sys_module_dict.SetItemForKey (PythonString("stdout"), new_file);
+ if (out_sp)
+ SetStdHandle(out_sp->GetFile(), "stdout", m_saved_stdout, "w");
}
- else
- m_saved_stdout.Reset();
- if (!err_file.IsValid() && err_sp)
- err_file = err_sp->GetFile();
- if (err_file.IsValid())
+ if (!SetStdHandle(err_file, "stderr", m_saved_stderr, "w"))
{
- // Flush the file before giving it to python to avoid interleaved output.
- err_file.Flush();
-
- m_saved_stderr = sys_module_dict.GetItemForKey(PythonString("stderr")).AsType<PythonFile>();
-
- PythonFile new_file(err_file, "w");
- sys_module_dict.SetItemForKey (PythonString("stderr"), new_file);
+ if (err_sp)
+ SetStdHandle(err_sp->GetFile(), "stderr", m_saved_stderr, "w");
}
- else
- m_saved_stderr.Reset();
}
if (PyErr_Occurred())
@@ -1019,7 +1015,7 @@ ScriptInterpreterPython::Interrupt()
if (IsExecutingPython())
{
- PyThreadState *state = PyThreadState_Get();
+ PyThreadState *state = PyThreadState_GET();
if (!state)
state = GetThreadState();
if (state)
@@ -1555,10 +1551,12 @@ ScriptInterpreterPython::OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugi
PyErr_Print();
PyErr_Clear();
}
- assert(PythonDictionary::Check(py_return.get()) && "get_register_info returned unknown object type!");
-
- PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
- return result_dict.CreateStructuredDictionary();
+ if (py_return.get())
+ {
+ PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
+ return result_dict.CreateStructuredDictionary();
+ }
+ return StructuredData::DictionarySP();
}
StructuredData::ArraySP
@@ -1611,10 +1609,12 @@ ScriptInterpreterPython::OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin
PyErr_Clear();
}
- assert(PythonList::Check(py_return.get()) && "get_thread_info returned unknown object type!");
-
- PythonList result_list(PyRefType::Borrowed, py_return.get());
- return result_list.CreateStructuredArray();
+ if (py_return.get())
+ {
+ PythonList result_list(PyRefType::Borrowed, py_return.get());
+ return result_list.CreateStructuredArray();
+ }
+ return StructuredData::ArraySP();
}
// GetPythonValueFormatString provides a system independent type safe way to
@@ -1692,10 +1692,12 @@ ScriptInterpreterPython::OSPlugin_RegisterContextData(StructuredData::ObjectSP o
PyErr_Clear();
}
- assert(PythonBytes::Check(py_return.get()) && "get_register_data returned unknown object type!");
-
- PythonBytes result(PyRefType::Borrowed, py_return.get());
- return result.CreateStructuredString();
+ if (py_return.get())
+ {
+ PythonBytes result(PyRefType::Borrowed, py_return.get());
+ return result.CreateStructuredString();
+ }
+ return StructuredData::StringSP();
}
StructuredData::DictionarySP
@@ -1750,10 +1752,12 @@ ScriptInterpreterPython::OSPlugin_CreateThread(StructuredData::ObjectSP os_plugi
PyErr_Clear();
}
- assert(PythonDictionary::Check(py_return.get()) && "create_thread returned unknown object type!");
-
- PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
- return result_dict.CreateStructuredDictionary();
+ if (py_return.get())
+ {
+ PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
+ return result_dict.CreateStructuredDictionary();
+ }
+ return StructuredData::DictionarySP();
}
StructuredData::ObjectSP
@@ -2353,6 +2357,72 @@ ScriptInterpreterPython::GetSyntheticValue(const StructuredData::ObjectSP &imple
return ret_val;
}
+ConstString
+ScriptInterpreterPython::GetSyntheticTypeName (const StructuredData::ObjectSP &implementor_sp)
+{
+ Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+
+ static char callee_name[] = "get_type_name";
+
+ ConstString ret_val;
+ bool got_string = false;
+ std::string buffer;
+
+ if (!implementor_sp)
+ return ret_val;
+
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return ret_val;
+ PythonObject implementor(PyRefType::Borrowed, (PyObject *)generic->GetValue());
+ if (!implementor.IsAllocated())
+ return ret_val;
+
+ PythonObject pmeth(PyRefType::Owned, PyObject_GetAttrString(implementor.get(), callee_name));
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ if (!pmeth.IsAllocated())
+ return ret_val;
+
+ if (PyCallable_Check(pmeth.get()) == 0)
+ {
+ if (PyErr_Occurred())
+ PyErr_Clear();
+ return ret_val;
+ }
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ // right now we know this function exists and is callable..
+ PythonObject py_return(PyRefType::Owned, PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return.IsAllocated() && PythonString::Check(py_return.get()))
+ {
+ PythonString py_string(PyRefType::Borrowed, py_return.get());
+ llvm::StringRef return_data(py_string.GetString());
+ if (!return_data.empty())
+ {
+ buffer.assign(return_data.data(), return_data.size());
+ got_string = true;
+ }
+ }
+
+ if (got_string)
+ ret_val.SetCStringWithLength(buffer.c_str(), buffer.size());
+
+ return ret_val;
+}
+
bool
ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
Process* process,
@@ -2550,7 +2620,7 @@ ScriptInterpreterPython::LoadScriptingModule(const char *pathname, bool can_relo
StreamString command_stream;
- // Before executing Pyton code, lock the GIL.
+ // Before executing Python code, lock the GIL.
Locker py_lock (this,
Locker::AcquireLock | (init_session ? Locker::InitSession : 0) | Locker::NoSTDIN,
Locker::FreeAcquiredLock | (init_session ? Locker::TearDownSession : 0));
@@ -2571,9 +2641,10 @@ ScriptInterpreterPython::LoadScriptingModule(const char *pathname, bool can_relo
target_file.GetFileType() == FileSpec::eFileTypeRegular ||
target_file.GetFileType() == FileSpec::eFileTypeSymbolicLink)
{
- std::string directory(target_file.GetDirectory().GetCString());
- replace_all(directory,"'","\\'");
-
+ std::string directory = target_file.GetDirectory().GetCString();
+ replace_all(directory, "\\", "\\\\");
+ replace_all(directory, "'", "\\'");
+
// now make sure that Python has "directory" in the search path
StreamString command_stream;
command_stream.Printf("if not (sys.path.__contains__('%s')):\n sys.path.insert(1,'%s');\n\n",
@@ -2585,7 +2656,7 @@ ScriptInterpreterPython::LoadScriptingModule(const char *pathname, bool can_relo
error.SetErrorString("Python sys.path handling failed");
return false;
}
-
+
// strip .py or .pyc extension
ConstString extension = target_file.GetFileNameExtension();
if (extension)
@@ -2636,8 +2707,8 @@ ScriptInterpreterPython::LoadScriptingModule(const char *pathname, bool can_relo
command_stream.Printf("reload_module(%s)",basename.c_str());
}
else
- command_stream.Printf("import %s",basename.c_str());
-
+ command_stream.Printf("import %s", basename.c_str());
+
error = ExecuteMultipleLines(command_stream.GetData(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false));
if (error.Fail())
return false;
@@ -3098,7 +3169,9 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callb
void
ScriptInterpreterPython::InitializePrivate ()
{
- assert(!g_initialized && "ScriptInterpreterPython::InitializePrivate() called more than once!");
+ if (g_initialized)
+ return;
+
g_initialized = true;
Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
index 4c6eb3949898..263bb527d833 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
@@ -228,6 +228,8 @@ public:
lldb::ValueObjectSP GetSyntheticValue(const StructuredData::ObjectSP &implementor) override;
+ ConstString GetSyntheticTypeName (const StructuredData::ObjectSP &implementor) override;
+
bool
RunScriptBasedCommand(const char* impl_function,
const char* args,
@@ -581,6 +583,9 @@ protected:
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;
diff --git a/source/Plugins/SymbolFile/CMakeLists.txt b/source/Plugins/SymbolFile/CMakeLists.txt
index add6697389f9..98510704ce73 100644
--- a/source/Plugins/SymbolFile/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/CMakeLists.txt
@@ -1,2 +1,3 @@
add_subdirectory(DWARF)
add_subdirectory(Symtab)
+add_subdirectory(PDB)
diff --git a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
index b4658115dfeb..ac69243b65c0 100644
--- a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -3,6 +3,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF
DWARFAbbreviationDeclaration.cpp
DWARFASTParserClang.cpp
DWARFASTParserGo.cpp
+ DWARFASTParserJava.cpp
DWARFAttribute.cpp
DWARFCompileUnit.cpp
DWARFDataExtractor.cpp
diff --git a/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/source/Plugins/SymbolFile/DWARF/DIERef.cpp
index c0754a1fdd54..5fe0cc4d416e 100644
--- a/source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -10,26 +10,49 @@
#include "DIERef.h"
#include "DWARFCompileUnit.h"
#include "DWARFFormValue.h"
+#include "DWARFDebugInfo.h"
+#include "SymbolFileDWARF.h"
+#include "SymbolFileDWARFDebugMap.h"
DIERef::DIERef() :
cu_offset(DW_INVALID_OFFSET),
die_offset(DW_INVALID_OFFSET)
{}
-DIERef::DIERef(dw_offset_t d) :
- cu_offset(DW_INVALID_OFFSET),
- die_offset(d)
-{}
-
DIERef::DIERef(dw_offset_t c, dw_offset_t d) :
cu_offset(c),
die_offset(d)
{}
-DIERef::DIERef(lldb::user_id_t uid) :
- cu_offset(uid>>32),
+DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf) :
+ cu_offset(DW_INVALID_OFFSET),
die_offset(uid&0xffffffff)
-{}
+{
+ SymbolFileDWARFDebugMap *debug_map = dwarf->GetDebugMapSymfile();
+ if (debug_map)
+ {
+ const uint32_t oso_idx = debug_map->GetOSOIndexFromUserID(uid);
+ SymbolFileDWARF *actual_dwarf = debug_map->GetSymbolFileByOSOIndex(oso_idx);
+ if (actual_dwarf)
+ {
+ DWARFDebugInfo *debug_info = actual_dwarf->DebugInfo();
+ if (debug_info)
+ {
+ DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitContainingDIEOffset(die_offset);
+ if (dwarf_cu)
+ {
+ cu_offset = dwarf_cu->GetOffset();
+ return;
+ }
+ }
+ }
+ die_offset = DW_INVALID_OFFSET;
+ }
+ else
+ {
+ cu_offset = uid>>32;
+ }
+}
DIERef::DIERef(const DWARFFormValue& form_value) :
cu_offset(DW_INVALID_OFFSET),
@@ -50,7 +73,19 @@ DIERef::DIERef(const DWARFFormValue& form_value) :
}
lldb::user_id_t
-DIERef::GetUID() const
+DIERef::GetUID(SymbolFileDWARF *dwarf) const
{
- return ((lldb::user_id_t)cu_offset) << 32 | die_offset;
+ //----------------------------------------------------------------------
+ // Each SymbolFileDWARF will set its ID to what is expected.
+ //
+ // SymbolFileDWARF, when used for DWARF with .o files on MacOSX, has the
+ // ID set to the compile unit index.
+ //
+ // SymbolFileDWARFDwo sets the ID to the compile unit offset.
+ //----------------------------------------------------------------------
+ if (dwarf)
+ return dwarf->GetID() | die_offset;
+ else
+ return LLDB_INVALID_UID;
}
+
diff --git a/source/Plugins/SymbolFile/DWARF/DIERef.h b/source/Plugins/SymbolFile/DWARF/DIERef.h
index 3df07d511749..ad4ad45623a3 100644
--- a/source/Plugins/SymbolFile/DWARF/DIERef.h
+++ b/source/Plugins/SymbolFile/DWARF/DIERef.h
@@ -14,24 +14,34 @@
#include "lldb/lldb-defines.h"
class DWARFFormValue;
+class SymbolFileDWARF;
struct DIERef
{
DIERef();
- explicit
- DIERef(dw_offset_t d);
-
DIERef(dw_offset_t c, dw_offset_t d);
+ //----------------------------------------------------------------------
+ // In order to properly decode a lldb::user_id_t back into a DIERef we
+ // need the DWARF file since it knows if DWARF in .o files is being used
+ // (MacOSX) or if DWO files are being used. The encoding of the user ID
+ // differs between the two types of DWARF.
+ //----------------------------------------------------------------------
explicit
- DIERef(lldb::user_id_t uid);
+ DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf);
explicit
DIERef(const DWARFFormValue& form_value);
+ //----------------------------------------------------------------------
+ // In order to properly encode a DIERef unto a lldb::user_id_t we need
+ // the DWARF file since it knows if DWARF in .o files is being used
+ // (MacOSX) or if DWO files are being used. The encoding of the user ID
+ // differs between the two types of DWARF.
+ //----------------------------------------------------------------------
lldb::user_id_t
- GetUID() const;
+ GetUID(SymbolFileDWARF *dwarf) const;
bool
operator< (const DIERef &ref) const
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index ab20844bfcfd..2fb360440f63 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -33,18 +33,6 @@ public:
const DWARFDIE &die) = 0;
virtual bool
- CanCompleteType (const lldb_private::CompilerType &compiler_type)
- {
- return false;
- }
-
- virtual bool
- CompleteType (const lldb_private::CompilerType &compiler_type)
- {
- return false;
- }
-
- virtual bool
CompleteTypeFromDWARF (const DWARFDIE &die,
lldb_private::Type *type,
lldb_private::CompilerType &compiler_type) = 0;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 74b54d614aa2..23381df3297a 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include <stdlib.h>
+
#include "DWARFASTParserClang.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugInfo.h"
@@ -18,14 +20,16 @@
#include "SymbolFileDWARFDebugMap.h"
#include "UniqueDWARFASTType.h"
-#include "lldb/Interpreter/Args.h"
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Value.h"
#include "lldb/Host/Host.h"
+#include "lldb/Interpreter/Args.h"
#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -33,7 +37,7 @@
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Target/Language.h"
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
@@ -97,9 +101,9 @@ struct BitfieldInfo
uint64_t bit_size;
uint64_t bit_offset;
- BitfieldInfo () :
- bit_size (LLDB_INVALID_ADDRESS),
- bit_offset (LLDB_INVALID_ADDRESS)
+ BitfieldInfo() :
+ bit_size(LLDB_INVALID_ADDRESS),
+ bit_offset(LLDB_INVALID_ADDRESS)
{
}
@@ -110,10 +114,28 @@ struct BitfieldInfo
bit_offset = LLDB_INVALID_ADDRESS;
}
- bool IsValid ()
+ bool
+ IsValid() const
{
return (bit_size != LLDB_INVALID_ADDRESS) &&
- (bit_offset != LLDB_INVALID_ADDRESS);
+ (bit_offset != LLDB_INVALID_ADDRESS);
+ }
+
+ bool
+ NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const
+ {
+ if (IsValid())
+ {
+ // This bitfield info is valid, so any subsequent bitfields
+ // must not overlap and must be at a higher bit offset than
+ // any previous bitfield + size.
+ return (bit_size + bit_offset) <= next_bit_offset;
+ }
+ else
+ {
+ // If the this BitfieldInfo is not valid, then any offset isOK
+ return true;
+ }
}
};
@@ -252,11 +274,11 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
switch (tag)
{
+ case DW_TAG_typedef:
case DW_TAG_base_type:
case DW_TAG_pointer_type:
case DW_TAG_reference_type:
case DW_TAG_rvalue_reference_type:
- case DW_TAG_typedef:
case DW_TAG_const_type:
case DW_TAG_restrict_type:
case DW_TAG_volatile_type:
@@ -267,7 +289,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
const size_t num_attributes = die.GetAttributes (attributes);
uint32_t encoding = 0;
- lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
+ DWARFFormValue encoding_uid;
if (num_attributes > 0)
{
@@ -297,7 +319,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
case DW_AT_encoding: encoding = form_value.Unsigned(); break;
- case DW_AT_type: encoding_uid = DIERef(form_value).GetUID(); break;
+ case DW_AT_type: encoding_uid = form_value; break;
default:
case DW_AT_sibling:
break;
@@ -306,7 +328,43 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
}
}
- DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
+ if (tag == DW_TAG_typedef && encoding_uid.IsValid())
+ {
+ // Try to parse a typedef from the DWO file first as modules
+ // can contain typedef'ed structures that have no names like:
+ //
+ // typedef struct { int a; } Foo;
+ //
+ // In this case we will have a structure with no name and a
+ // typedef named "Foo" that points to this unnamed structure.
+ // The name in the typedef is the only identifier for the struct,
+ // so always try to get typedefs from DWO files if possible.
+ //
+ // The type_sp returned will be empty if the typedef doesn't exist
+ // in a DWO file, so it is cheap to call this function just to check.
+ //
+ // If we don't do this we end up creating a TypeSP that says this
+ // is a typedef to type 0x123 (the DW_AT_type value would be 0x123
+ // in the DW_TAG_typedef), and this is the unnamed structure type.
+ // We will have a hard time tracking down an unnammed structure
+ // type in the module DWO file, so we make sure we don't get into
+ // this situation by always resolving typedefs from the DWO file.
+ const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
+
+ // First make sure that the die that this is typedef'ed to _is_
+ // just a declaration (DW_AT_declaration == 1), not a full definition
+ // since template types can't be represented in modules since only
+ // concrete instances of templates are ever emitted and modules
+ // won't contain those
+ if (encoding_die && encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1)
+ {
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+ }
+ }
+
+ DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid.Reference());
switch (tag)
{
@@ -322,6 +380,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
break;
}
// Fall through to base type below in case we can handle the type there...
+ LLVM_FALLTHROUGH;
case DW_TAG_base_type:
resolve_state = Type::eResolveStateFull;
@@ -341,6 +400,44 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
{
+ if (tag == DW_TAG_pointer_type)
+ {
+ DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);
+
+ if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0))
+ {
+ // Blocks have a __FuncPtr inside them which is a pointer to a function of the proper type.
+
+ for (DWARFDIE child_die = target_die.GetFirstChild();
+ child_die.IsValid();
+ child_die = child_die.GetSibling())
+ {
+ if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""), "__FuncPtr"))
+ {
+ DWARFDIE function_pointer_type = child_die.GetReferencedDIE(DW_AT_type);
+
+ if (function_pointer_type)
+ {
+ DWARFDIE function_type = function_pointer_type.GetReferencedDIE(DW_AT_type);
+
+ bool function_type_is_new_pointer;
+ TypeSP lldb_function_type_sp = ParseTypeFromDWARF(sc, function_type, log, &function_type_is_new_pointer);
+
+ if (lldb_function_type_sp)
+ {
+ clang_type = m_ast.CreateBlockPointerType(lldb_function_type_sp->GetForwardCompilerType());
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid.Clear();
+ resolve_state = Type::eResolveStateFull;
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
if (translation_unit_is_objc)
@@ -361,7 +458,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
die.GetName());
clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
+ encoding_uid.Clear();
resolve_state = Type::eResolveStateFull;
}
@@ -375,7 +472,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
die.GetName());
clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
+ encoding_uid.Clear();
resolve_state = Type::eResolveStateFull;
}
else if (type_name_const_str == g_objc_type_name_selector)
@@ -388,15 +485,15 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
die.GetName());
clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
+ encoding_uid.Clear();
resolve_state = Type::eResolveStateFull;
}
}
- else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid != LLDB_INVALID_UID)
+ else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid.IsValid())
{
// Clang sometimes erroneously emits id as objc_object*. In that case we fix up the type to "id".
- const DWARFDIE encoding_die = die.GetDIE(encoding_uid);
+ const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type)
{
@@ -412,7 +509,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
die.GetName());
clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
+ encoding_uid.Clear();
resolve_state = Type::eResolveStateFull;
}
}
@@ -426,7 +523,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
type_name_const_str,
byte_size,
NULL,
- encoding_uid,
+ DIERef(encoding_uid).GetUID(dwarf),
encoding_data_type,
&decl,
clang_type,
@@ -532,43 +629,32 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
// and clang isn't good and sharing the stack space for variables in different blocks.
std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(new UniqueDWARFASTType());
+ ConstString unique_typename(type_name_const_str);
+ Declaration unique_decl(decl);
+
if (type_name_const_str)
{
LanguageType die_language = die.GetLanguage();
- bool handled = false;
if (Language::LanguageIsCPlusPlus(die_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))
- {
- handled = true;
- ConstString const_qualified_name(qualified_name);
- if (dwarf->GetUniqueDWARFASTTypeMap().Find(const_qualified_name, die, Declaration(),
- byte_size_valid ? byte_size : -1,
- *unique_ast_entry_ap))
- {
- type_sp = unique_ast_entry_ap->m_type_sp;
- if (type_sp)
- {
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
- }
+ unique_typename = ConstString(qualified_name);
+ unique_decl.Clear();
}
- if (!handled)
+ if (dwarf->GetUniqueDWARFASTTypeMap().Find(unique_typename, die, unique_decl,
+ byte_size_valid ? byte_size : -1,
+ *unique_ast_entry_ap))
{
- if (dwarf->GetUniqueDWARFASTTypeMap().Find(type_name_const_str, die, decl,
- byte_size_valid ? byte_size : -1,
- *unique_ast_entry_ap))
+ type_sp = unique_ast_entry_ap->m_type_sp;
+ if (type_sp)
{
- type_sp = unique_ast_entry_ap->m_type_sp;
- if (type_sp)
- {
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
}
}
}
@@ -716,7 +802,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
// a complete type for this die
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
- dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID())));
+ dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf)));
if (defn_decl_ctx)
LinkDeclContextToDIE(defn_decl_ctx, die);
return type_sp;
@@ -799,9 +885,9 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
// and over in the ASTContext for our module
unique_ast_entry_ap->m_type_sp = type_sp;
unique_ast_entry_ap->m_die = die;
- unique_ast_entry_ap->m_declaration = decl;
+ unique_ast_entry_ap->m_declaration = unique_decl;
unique_ast_entry_ap->m_byte_size = byte_size;
- dwarf->GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
+ dwarf->GetUniqueDWARFASTTypeMap().Insert (unique_typename,
*unique_ast_entry_ap);
if (is_forward_declaration && die.HasChildren())
@@ -842,15 +928,25 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
if (die.HasChildren() == false)
{
// No children for this struct/union/class, lets finish it
- ClangASTContext::StartTagDeclarationDefinition (clang_type);
- ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
+ 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(),
+ type_name_cstr);
+ }
if (tag == DW_TAG_structure_type) // this only applies in C
{
clang::RecordDecl *record_decl = ClangASTContext::GetAsRecordDecl(clang_type);
if (record_decl)
- m_record_decl_to_layout_map.insert(std::make_pair(record_decl, LayoutInfo()));
+ {
+ GetClangASTImporter().InsertRecordDecl(record_decl, ClangASTImporter::LayoutInfo());
+ }
}
}
else if (clang_type_was_created)
@@ -872,12 +968,14 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
// will automatically call the SymbolFile virtual function
// "SymbolFileDWARF::CompleteType(Type *)"
// When the definition needs to be defined.
- assert(!dwarf->GetForwardDeclClangTypeToDie().count(ClangASTContext::RemoveFastQualifiers(clang_type).GetOpaqueQualType()) &&
+ assert(!dwarf->GetForwardDeclClangTypeToDie().count(
+ ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()) &&
"Type already in the forward declaration map!");
- assert(((SymbolFileDWARF*)m_ast.GetSymbolFile())->UserIDMatches(die.GetDIERef().GetUID()) &&
- "Adding incorrect type to 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()[ClangASTContext::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] = die.GetDIERef();
+ dwarf->GetForwardDeclClangTypeToDie()[ClangUtil::RemoveFastQualifiers(clang_type)
+ .GetOpaqueQualType()] = die.GetDIERef();
m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), true);
}
}
@@ -970,8 +1068,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
// 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->DebugInfo()->GetDIE(DIERef(type_sp->GetID())));
+ clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf)));
if (defn_decl_ctx)
LinkDeclContextToDIE(defn_decl_ctx, die);
return type_sp;
@@ -986,15 +1083,24 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
{
if (encoding_form.IsValid())
{
- Type *enumerator_type = dwarf->ResolveTypeUID(DIERef(encoding_form).GetUID());
+ Type *enumerator_type = dwarf->ResolveTypeUID(DIERef(encoding_form));
if (enumerator_type)
enumerator_clang_type = enumerator_type->GetFullCompilerType ();
}
if (!enumerator_clang_type)
- enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
- DW_ATE_signed,
- byte_size * 8);
+ {
+ if (byte_size > 0)
+ {
+ enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(NULL,
+ DW_ATE_signed,
+ byte_size * 8);
+ }
+ else
+ {
+ enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
+ }
+ }
clang_type = m_ast.CreateEnumerationType (type_name_cstr,
GetClangDeclContextContainingDIE (die, nullptr),
@@ -1013,21 +1119,29 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
type_name_const_str,
byte_size,
NULL,
- DIERef(encoding_form).GetUID(),
+ DIERef(encoding_form).GetUID(dwarf),
Type::eEncodingIsUID,
&decl,
clang_type,
Type::eResolveStateForward));
- ClangASTContext::StartTagDeclarationDefinition (clang_type);
- if (die.HasChildren())
+ if (ClangASTContext::StartTagDeclarationDefinition (clang_type))
{
- SymbolContext cu_sc(die.GetLLDBCompileUnit());
- bool is_signed = false;
- enumerator_clang_type.IsIntegerType(is_signed);
- ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), die);
+ if (die.HasChildren())
+ {
+ SymbolContext cu_sc(die.GetLLDBCompileUnit());
+ bool is_signed = false;
+ enumerator_clang_type.IsIntegerType(is_signed);
+ ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), die);
+ }
+ 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(),
+ type_name_cstr);
}
- ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
}
}
break;
@@ -1046,6 +1160,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
bool is_virtual = false;
bool is_explicit = false;
bool is_artificial = false;
+ bool has_template_params = false;
DWARFFormValue specification_die_form;
DWARFFormValue abstract_origin_die_form;
dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
@@ -1153,7 +1268,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
Type *func_type = NULL;
if (type_die_form.IsValid())
- func_type = dwarf->ResolveTypeUID(DIERef(type_die_form).GetUID());
+ func_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
if (func_type)
return_clang_type = func_type->GetForwardCompilerType ();
@@ -1170,11 +1285,13 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (die, &decl_ctx_die);
const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
- const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
+ bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
// Start off static. This will be set to false in ParseChildParameters(...)
// if we find a "this" parameters as the first parameter
if (is_cxx_method)
+ {
is_static = true;
+ }
if (die.HasChildren())
{
@@ -1185,11 +1302,26 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
skip_artificial,
is_static,
is_variadic,
+ has_template_params,
function_param_types,
function_param_decls,
type_quals);
}
+ bool ignore_containing_context = false;
+ // Check for templatized class member functions. If we had any DW_TAG_template_type_parameter
+ // or DW_TAG_template_value_parameter the DW_TAG_subprogram DIE, then we can't let this become
+ // a method in a class. Why? Because templatized functions are only emitted if one of the
+ // templatized methods is used in the current compile unit and we will end up with classes
+ // that may or may not include these member functions and this means one class won't match another
+ // class definition and it affects our ability to use a class in the clang expression parser. So
+ // for the greater good, we currently must not allow any template member functions in a class definition.
+ if (is_cxx_method && has_template_params)
+ {
+ ignore_containing_context = true;
+ is_cxx_method = false;
+ }
+
// clang_type will get the function prototype clang type after this call
clang_type = m_ast.CreateFunctionType (return_clang_type,
function_param_types.data(),
@@ -1197,7 +1329,6 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
is_variadic,
type_quals);
- bool ignore_containing_context = false;
if (type_name_cstr)
{
@@ -1233,7 +1364,8 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
type_name_cstr,
clang_type,
accessibility,
- is_artificial);
+ is_artificial,
+ is_variadic);
type_handled = objc_method_decl != NULL;
if (type_handled)
{
@@ -1272,12 +1404,12 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
if (debug_map_symfile)
{
class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID()));
- class_type_die = class_symfile->DebugInfo()->GetDIE (DIERef(class_type->GetID()));
+ class_type_die = class_symfile->DebugInfo()->GetDIE (DIERef(class_type->GetID(), dwarf));
}
else
{
class_symfile = dwarf;
- class_type_die = dwarf->DebugInfo()->GetDIE (DIERef(class_type->GetID()));
+ class_type_die = dwarf->DebugInfo()->GetDIE (DIERef(class_type->GetID(), dwarf));
}
if (class_type_die)
{
@@ -1378,7 +1510,8 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
clang::CXXMethodDecl *method_decl = *method_iter;
if (method_decl->getNameInfo().getAsString() == std::string(type_name_cstr))
{
- if (method_decl->getType() == ClangASTContext::GetQualType(clang_type))
+ if (method_decl->getType() ==
+ ClangUtil::GetQualType(clang_type))
{
add_method = false;
LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(method_decl), die);
@@ -1483,44 +1616,72 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
if (!type_handled)
{
- // We just have a function that isn't part of a class
- clang::FunctionDecl *function_decl = m_ast.CreateFunctionDeclaration (ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx,
- type_name_cstr,
- clang_type,
- storage,
- is_inline);
-
- // if (template_param_infos.GetSize() > 0)
- // {
- // clang::FunctionTemplateDecl *func_template_decl = CreateFunctionTemplateDecl (containing_decl_ctx,
- // function_decl,
- // type_name_cstr,
- // template_param_infos);
- //
- // CreateFunctionTemplateSpecializationInfo (function_decl,
- // func_template_decl,
- // template_param_infos);
- // }
- // Add the decl to our DIE to decl context map
- assert (function_decl);
- LinkDeclContextToDIE(function_decl, die);
- if (!function_param_decls.empty())
- m_ast.SetFunctionParameters (function_decl,
- &function_param_decls.front(),
- function_param_decls.size());
+ clang::FunctionDecl *function_decl = nullptr;
+
+ if (abstract_origin_die_form.IsValid())
+ {
+ DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE (DIERef(abstract_origin_die_form));
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
+ SymbolContext sc;
+
+ if (dwarf->ResolveType (abs_die))
+ {
+ function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(GetCachedClangDeclContextForDIE(abs_die));
+
+ if (function_decl)
+ {
+ LinkDeclContextToDIE(function_decl, die);
+ }
+ }
+ }
- if (!object_pointer_name.empty())
+ if (!function_decl)
{
- 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));
+ // We just have a function that isn't part of a class
+ function_decl = m_ast.CreateFunctionDeclaration (ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx,
+ type_name_cstr,
+ clang_type,
+ storage,
+ is_inline);
+
+ // if (template_param_infos.GetSize() > 0)
+ // {
+ // clang::FunctionTemplateDecl *func_template_decl = CreateFunctionTemplateDecl (containing_decl_ctx,
+ // function_decl,
+ // type_name_cstr,
+ // template_param_infos);
+ //
+ // CreateFunctionTemplateSpecializationInfo (function_decl,
+ // func_template_decl,
+ // template_param_infos);
+ // }
+ // Add the decl to our DIE to decl context map
+
+ lldbassert (function_decl);
+
+ if (function_decl)
+ {
+ LinkDeclContextToDIE(function_decl, die);
+
+ if (!function_param_decls.empty())
+ m_ast.SetFunctionParameters (function_decl,
+ &function_param_decls.front(),
+ function_param_decls.size());
+
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+
+ 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));
+ }
+ m_ast.SetMetadata (function_decl, metadata);
+ }
}
- m_ast.SetMetadata (function_decl, metadata);
}
}
type_sp.reset( new Type (die.GetID(),
@@ -1591,7 +1752,8 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
- Type *element_type = dwarf->ResolveTypeUID(DIERef(type_die_form).GetUID());
+ DIERef type_die_ref(type_die_form);
+ Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
if (element_type)
{
@@ -1600,6 +1762,39 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
if (byte_stride == 0 && bit_stride == 0)
byte_stride = element_type->GetByteSize();
CompilerType array_element_type = element_type->GetForwardCompilerType ();
+
+ if (ClangASTContext::IsCXXClassType(array_element_type) && array_element_type.GetCompleteType() == false)
+ {
+ ModuleSP module_sp = die.GetModule();
+ if (module_sp)
+ {
+ if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)
+ module_sp->ReportError ("DWARF DW_TAG_array_type DIE at 0x%8.8x has a class/union/struct element type DIE 0x%8.8x that is a forward declaration, not a complete definition.\nTry compiling the source file with -fno-limit-debug-info or disable -gmodule",
+ die.GetOffset(),
+ type_die_ref.die_offset);
+ else
+ module_sp->ReportError ("DWARF DW_TAG_array_type DIE at 0x%8.8x has a class/union/struct element type DIE 0x%8.8x that is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s",
+ die.GetOffset(),
+ type_die_ref.die_offset,
+ die.GetLLDBCompileUnit() ? die.GetLLDBCompileUnit()->GetPath().c_str() : "the source file");
+ }
+
+ // We have no choice other than to pretend that the element class type
+ // is complete. If we don't do this, clang will crash when trying
+ // to layout the class. Since we provide layout assistance, all
+ // ivars in this class and other classes will be fine, this is
+ // the best we can do short of crashing.
+ if (ClangASTContext::StartTagDeclarationDefinition(array_element_type))
+ {
+ ClangASTContext::CompleteTagDeclarationDefinition(array_element_type);
+ }
+ else
+ {
+ module_sp->ReportError ("DWARF DIE at 0x%8.8x was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message",
+ type_die_ref.die_offset);
+ }
+ }
+
uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
if (element_orders.size() > 0)
{
@@ -1628,7 +1823,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
empty_name,
array_element_bit_stride / 8,
NULL,
- DIERef(type_die_form).GetUID(),
+ DIERef(type_die_form).GetUID(dwarf),
Type::eEncodingIsUID,
&decl,
clang_type,
@@ -1663,8 +1858,8 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
}
}
- Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form).GetUID());
- Type *class_type = dwarf->ResolveTypeUID(DIERef(containing_type_die_form).GetUID());
+ Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
+ Type *class_type = dwarf->ResolveTypeUID(DIERef(containing_type_die_form));
CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType ();
CompilerType class_clang_type = class_type->GetLayoutCompilerType ();
@@ -1812,8 +2007,7 @@ DWARFASTParserClang::ParseTemplateDIE (const DWARFDIE &die,
{
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes (attributes);
- const char *name = NULL;
- Type *lldb_type = NULL;
+ const char *name = nullptr;
CompilerType clang_type;
uint64_t uval64 = 0;
bool uval64_valid = false;
@@ -1834,7 +2028,7 @@ DWARFASTParserClang::ParseTemplateDIE (const DWARFDIE &die,
case DW_AT_type:
if (attributes.ExtractFormValueAtIndex(i, form_value))
{
- lldb_type = die.ResolveTypeUID(DIERef(form_value).GetUID());
+ Type *lldb_type = die.ResolveTypeUID(DIERef(form_value));
if (lldb_type)
clang_type = lldb_type->GetForwardCompilerType ();
}
@@ -1864,19 +2058,19 @@ DWARFASTParserClang::ParseTemplateDIE (const DWARFDIE &die,
else
template_param_infos.names.push_back(NULL);
- if (tag == DW_TAG_template_value_parameter &&
- lldb_type != NULL &&
- clang_type.IsIntegerType (is_signed) &&
- uval64_valid)
+ // Get the signed value for any integer or enumeration if available
+ clang_type.IsIntegerOrEnumerationType (is_signed);
+
+ if (tag == DW_TAG_template_value_parameter && uval64_valid)
{
- llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
- template_param_infos.args.push_back (clang::TemplateArgument (*ast,
- llvm::APSInt(apint),
- ClangASTContext::GetQualType(clang_type)));
+ llvm::APInt apint (clang_type.GetBitSize(nullptr), uval64, is_signed);
+ template_param_infos.args.push_back(
+ clang::TemplateArgument(*ast, llvm::APSInt(apint, !is_signed), ClangUtil::GetQualType(clang_type)));
}
else
{
- template_param_infos.args.push_back (clang::TemplateArgument (ClangASTContext::GetQualType(clang_type)));
+ template_param_infos.args.push_back(
+ clang::TemplateArgument(ClangUtil::GetQualType(clang_type)));
}
}
else
@@ -1926,37 +2120,12 @@ DWARFASTParserClang::ParseTemplateParameterInfos (const DWARFDIE &parent_die,
}
bool
-DWARFASTParserClang::CanCompleteType (const lldb_private::CompilerType &compiler_type)
+DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type)
{
- if (m_clang_ast_importer_ap)
- return ClangASTContext::CanImport(compiler_type, GetClangASTImporter());
- else
- return false;
-}
+ SymbolFileDWARF *dwarf = die.GetDWARF();
-bool
-DWARFASTParserClang::CompleteType (const lldb_private::CompilerType &compiler_type)
-{
- if (CanCompleteType(compiler_type))
- {
- if (ClangASTContext::Import(compiler_type, GetClangASTImporter()))
- {
- ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
- return true;
- }
- else
- {
- ClangASTContext::SetHasExternalStorage (compiler_type.GetOpaqueQualType(), false);
- }
- }
- return false;
-}
+ std::lock_guard<std::recursive_mutex> guard(dwarf->GetObjectFile()->GetModule()->GetMutex());
-bool
-DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
- lldb_private::Type *type,
- CompilerType &clang_type)
-{
// Disable external storage for this type so we don't get anymore
// clang::ExternalASTSource queries for this type.
m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), false);
@@ -1964,9 +2133,45 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
if (!die)
return false;
- const dw_tag_t tag = die.Tag();
+#if defined LLDB_CONFIGURATION_DEBUG
+ //----------------------------------------------------------------------
+ // For debugging purposes, the LLDB_DWARF_DONT_COMPLETE_TYPENAMES
+ // environment variable can be set with one or more typenames separated
+ // by ';' characters. This will cause this function to not complete any
+ // types whose names match.
+ //
+ // Examples of setting this environment variable:
+ //
+ // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo
+ // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo;Bar;Baz
+ //----------------------------------------------------------------------
+ const char *dont_complete_typenames_cstr = getenv("LLDB_DWARF_DONT_COMPLETE_TYPENAMES");
+ if (dont_complete_typenames_cstr && dont_complete_typenames_cstr[0])
+ {
+ const char *die_name = die.GetName();
+ if (die_name && die_name[0])
+ {
+ const char *match = strstr(dont_complete_typenames_cstr, die_name);
+ if (match)
+ {
+ size_t die_name_length = strlen(die_name);
+ while (match)
+ {
+ const char separator_char = ';';
+ const char next_char = match[die_name_length];
+ if (next_char == '\0' || next_char == separator_char)
+ {
+ if (match == dont_complete_typenames_cstr || match[-1] == separator_char)
+ return false;
+ }
+ match = strstr(match+1, die_name);
+ }
+ }
+ }
+ }
+#endif
- SymbolFileDWARF *dwarf = die.GetDWARF();
+ const dw_tag_t tag = die.Tag();
Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
if (log)
@@ -1983,7 +2188,7 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
case DW_TAG_union_type:
case DW_TAG_class_type:
{
- LayoutInfo layout_info;
+ ClangASTImporter::LayoutInfo layout_info;
{
if (die.HasChildren())
@@ -2080,7 +2285,7 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
if (class_language != eLanguageTypeObjC)
{
if (is_a_class && tag_decl_kind != clang::TTK_Class)
- m_ast.SetTagTypeKind (ClangASTContext::GetQualType(clang_type), clang::TTK_Class);
+ m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type), clang::TTK_Class);
}
// Since DW_TAG_structure_type gets used for both classes
@@ -2130,8 +2335,10 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
// below. Since we provide layout assistance, all ivars in this
// class and other classes will be fine, this is the best we can do
// short of crashing.
- ClangASTContext::StartTagDeclarationDefinition (base_class_type);
- ClangASTContext::CompleteTagDeclarationDefinition (base_class_type);
+ if (ClangASTContext::StartTagDeclarationDefinition (base_class_type))
+ {
+ ClangASTContext::CompleteTagDeclarationDefinition (base_class_type);
+ }
}
}
}
@@ -2219,7 +2426,7 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
}
}
- m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
+ GetClangASTImporter().InsertRecordDecl(record_decl, layout_info);
}
}
}
@@ -2227,15 +2434,17 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
return (bool)clang_type;
case DW_TAG_enumeration_type:
- ClangASTContext::StartTagDeclarationDefinition (clang_type);
- if (die.HasChildren())
+ if (ClangASTContext::StartTagDeclarationDefinition (clang_type))
{
- SymbolContext sc(die.GetLLDBCompileUnit());
- bool is_signed = false;
- clang_type.IsIntegerType(is_signed);
- ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), die);
+ if (die.HasChildren())
+ {
+ SymbolContext sc(die.GetLLDBCompileUnit());
+ bool is_signed = false;
+ clang_type.IsIntegerType(is_signed);
+ ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), die);
+ }
+ ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
}
- ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
return (bool)clang_type;
default:
@@ -2484,6 +2693,7 @@ DWARFASTParserClang::ParseFunctionFromDWARF (const SymbolContext& sc,
// never mangled.
bool is_static = false;
bool is_variadic = false;
+ bool has_template_params = false;
unsigned type_quals = 0;
std::vector<CompilerType> param_types;
std::vector<clang::ParmVarDecl*> param_decls;
@@ -2500,6 +2710,7 @@ DWARFASTParserClang::ParseFunctionFromDWARF (const SymbolContext& sc,
true,
is_static,
is_variadic,
+ has_template_params,
param_types,
param_decls,
type_quals);
@@ -2557,23 +2768,22 @@ DWARFASTParserClang::ParseFunctionFromDWARF (const SymbolContext& sc,
return NULL;
}
-
bool
-DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
- const DWARFDIE &parent_die,
- CompilerType &class_clang_type,
- const LanguageType class_language,
- std::vector<clang::CXXBaseSpecifier *>& base_classes,
- std::vector<int>& member_accessibilities,
- DWARFDIECollection& member_function_dies,
- DelayedPropertyList& delayed_properties,
- AccessType& default_accessibility,
- bool &is_a_class,
- LayoutInfo &layout_info)
+DWARFASTParserClang::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &parent_die,
+ CompilerType &class_clang_type, const LanguageType class_language,
+ std::vector<clang::CXXBaseSpecifier *> &base_classes,
+ std::vector<int> &member_accessibilities,
+ DWARFDIECollection &member_function_dies,
+ DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
+ bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info)
{
if (!parent_die)
return 0;
+ // Get the parent byte size so we can verify any members will fit
+ const uint64_t parent_byte_size = parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX) * 8;
+ const uint64_t parent_bit_size = parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8;
+
uint32_t member_idx = 0;
BitfieldInfo last_field_info;
@@ -2607,9 +2817,10 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
bool is_artificial = false;
DWARFFormValue encoding_form;
AccessType accessibility = eAccessNone;
- uint32_t member_byte_offset = UINT32_MAX;
+ uint32_t member_byte_offset = (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
size_t byte_size = 0;
- size_t bit_offset = 0;
+ int64_t bit_offset = 0;
+ uint64_t data_bit_offset = UINT64_MAX;
size_t bit_size = 0;
bool is_external = false; // On DW_TAG_members, this means the member is static
uint32_t i;
@@ -2626,9 +2837,10 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
case DW_AT_name: name = form_value.AsCString(); break;
case DW_AT_type: encoding_form = form_value; break;
- case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
+ case DW_AT_bit_offset: bit_offset = form_value.Signed(); break;
case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
+ case DW_AT_data_bit_offset: data_bit_offset = form_value.Unsigned(); break;
case DW_AT_data_member_location:
if (form_value.BlockData())
{
@@ -2637,10 +2849,10 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
const DWARFDataExtractor& debug_info_data = die.GetDWARF()->get_debug_info_data();
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
- NULL, // ClangExpressionVariableList *
- NULL, // ClangExpressionDeclMap *
- NULL, // RegisterContext *
+ if (DWARFExpression::Evaluate(nullptr, // ExecutionContext *
+ nullptr, // ClangExpressionVariableList *
+ nullptr, // ClangExpressionDeclMap *
+ nullptr, // RegisterContext *
module_sp,
debug_info_data,
die.GetCU(),
@@ -2648,8 +2860,9 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
block_length,
eRegisterKindDWARF,
&initialValue,
+ nullptr,
memberOffset,
- NULL))
+ nullptr))
{
member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
@@ -2739,7 +2952,7 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
// type in an expression when clang becomes unhappy with its
// recycled debug info.
- if (bit_offset > 128)
+ if (byte_size == 0 && bit_offset < 0)
{
bit_size = 0;
bit_offset = 0;
@@ -2764,7 +2977,7 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
// Handle static members
if (is_external && member_byte_offset == UINT32_MAX)
{
- Type *var_type = die.ResolveTypeUID(DIERef(encoding_form).GetUID());
+ Type *var_type = die.ResolveTypeUID(DIERef(encoding_form));
if (var_type)
{
@@ -2780,7 +2993,7 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
if (is_artificial == false)
{
- Type *member_type = die.ResolveTypeUID(DIERef(encoding_form).GetUID());
+ Type *member_type = die.ResolveTypeUID(DIERef(encoding_form));
clang::FieldDecl *field_decl = NULL;
if (tag == DW_TAG_member)
@@ -2815,17 +3028,38 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
// AT_bit_size indicates the size of the field in bits.
/////////////////////////////////////////////////////////////
- if (byte_size == 0)
- byte_size = member_type->GetByteSize();
-
- if (die.GetDWARF()->GetObjectFile()->GetByteOrder() == eByteOrderLittle)
+ if (data_bit_offset != UINT64_MAX)
{
- this_field_info.bit_offset += byte_size * 8;
- this_field_info.bit_offset -= (bit_offset + bit_size);
+ this_field_info.bit_offset = data_bit_offset;
}
else
{
- this_field_info.bit_offset += bit_offset;
+ if (byte_size == 0)
+ byte_size = member_type->GetByteSize();
+
+ ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+ if (objfile->GetByteOrder() == eByteOrderLittle)
+ {
+ this_field_info.bit_offset += byte_size * 8;
+ this_field_info.bit_offset -= (bit_offset + bit_size);
+ }
+ else
+ {
+ this_field_info.bit_offset += bit_offset;
+ }
+ }
+
+ if ((this_field_info.bit_offset >= parent_bit_size) || !last_field_info.NextBitfieldOffsetIsValid(this_field_info.bit_offset))
+ {
+ ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+ objfile->GetModule()->ReportWarning("0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid bit offset (0x%8.8" PRIx64 ") member will be ignored. Please file a bug against the compiler and include the preprocessed output for %s\n",
+ die.GetID(),
+ DW_TAG_value_to_name(tag),
+ name,
+ this_field_info.bit_offset,
+ sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
+ this_field_info.Clear();
+ continue;
}
// Update the field bit offset we will report for layout
@@ -2962,8 +3196,18 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
// to layout the class. Since we provide layout assistance, all
// ivars in this class and other classes will be fine, this is
// the best we can do short of crashing.
- ClangASTContext::StartTagDeclarationDefinition(member_clang_type);
- ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type);
+ if (ClangASTContext::StartTagDeclarationDefinition(member_clang_type))
+ {
+ ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type);
+ }
+ else
+ {
+ module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type claims to be a C++ class but we were not able to start its definition.\nPlease file a bug and attach the file at the start of this error message",
+ parent_die.GetOffset(),
+ parent_die.GetName(),
+ die.GetOffset(),
+ name);
+ }
}
field_decl = ClangASTContext::AddFieldToRecordType (class_clang_type,
@@ -3063,10 +3307,10 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
const DWARFDataExtractor& debug_info_data = die.GetDWARF()->get_debug_info_data();
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate (NULL,
- NULL,
- NULL,
- NULL,
+ if (DWARFExpression::Evaluate (nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
module_sp,
debug_info_data,
die.GetCU(),
@@ -3074,8 +3318,9 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
block_length,
eRegisterKindDWARF,
&initialValue,
+ nullptr,
memberOffset,
- NULL))
+ nullptr))
{
member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
@@ -3106,7 +3351,7 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
}
}
- Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form).GetUID());
+ Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form));
if (base_class_type == NULL)
{
module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to resolve the base class at 0x%8.8" PRIx64 " from enclosing type 0x%8.8x. \nPlease file a bug and attach the file at the start of this error message",
@@ -3166,6 +3411,7 @@ DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc,
bool skip_artificial,
bool &is_static,
bool &is_variadic,
+ bool &has_template_params,
std::vector<CompilerType>& function_param_types,
std::vector<clang::ParmVarDecl*>& function_param_decls,
unsigned &type_quals)
@@ -3251,7 +3497,7 @@ DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc,
// being in the formal parameter DIE...
if (name == NULL || ::strcmp(name, "this")==0)
{
- Type *this_type = die.ResolveTypeUID (DIERef(param_type_die_form).GetUID());
+ Type *this_type = die.ResolveTypeUID (DIERef(param_type_die_form));
if (this_type)
{
uint32_t encoding_mask = this_type->GetEncodingMask();
@@ -3294,7 +3540,7 @@ DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc,
if (!skip)
{
- Type *type = die.ResolveTypeUID(DIERef(param_type_die_form).GetUID());
+ Type *type = die.ResolveTypeUID(DIERef(param_type_die_form));
if (type)
{
function_param_types.push_back (type->GetForwardCompilerType ());
@@ -3324,6 +3570,7 @@ DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc,
// in SymbolFileDWARF::ParseType() so this was removed. If we ever need
// the template params back, we can add them back.
// ParseTemplateDIE (dwarf_cu, die, template_param_infos);
+ has_template_params = true;
break;
default:
@@ -3440,7 +3687,7 @@ DWARFASTParserClang::GetTypeForDIE (const DWARFDIE &die)
DWARFFormValue form_value;
if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value))
- return dwarf->ResolveTypeUID(DIERef(form_value).GetUID());
+ return dwarf->ResolveTypeUID(dwarf->GetDIE (DIERef(form_value)), true);
}
}
}
@@ -3477,6 +3724,14 @@ DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die)
m_decl_to_die[decl].insert(die.GetDIE());
return decl;
}
+
+ if (DWARFDIE abstract_origin_die = die.GetReferencedDIE(DW_AT_abstract_origin))
+ {
+ clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die);
+ m_die_to_decl[die.GetDIE()] = decl;
+ m_decl_to_die[decl].insert(die.GetDIE());
+ return decl;
+ }
clang::Decl *decl = nullptr;
switch (die.Tag())
@@ -3487,22 +3742,23 @@ DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die)
{
SymbolFileDWARF *dwarf = die.GetDWARF();
Type *type = GetTypeForDIE(die);
- const char *name = die.GetName();
- clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
- decl = m_ast.CreateVariableDeclaration(
- decl_context,
- name,
- ClangASTContext::GetQualType(type->GetForwardCompilerType()));
+ if (dwarf && type)
+ {
+ const char *name = die.GetName();
+ clang::DeclContext *decl_context =
+ ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
+ decl = m_ast.CreateVariableDeclaration(decl_context, name,
+ ClangUtil::GetQualType(type->GetForwardCompilerType()));
+ }
break;
}
case DW_TAG_imported_declaration:
{
SymbolFileDWARF *dwarf = die.GetDWARF();
- lldb::user_id_t imported_uid = die.GetAttributeValueAsReference(DW_AT_import, DW_INVALID_OFFSET);
-
- if (dwarf->UserIDMatches(imported_uid))
+ DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
+ if (imported_uid)
{
- CompilerDecl imported_decl = dwarf->GetDeclForUID(imported_uid);
+ CompilerDecl imported_decl = imported_uid.GetDecl();
if (imported_decl)
{
clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
@@ -3515,15 +3771,15 @@ DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die)
case DW_TAG_imported_module:
{
SymbolFileDWARF *dwarf = die.GetDWARF();
- lldb::user_id_t imported_uid = die.GetAttributeValueAsReference(DW_AT_import, DW_INVALID_OFFSET);
+ DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
- if (dwarf->UserIDMatches(imported_uid))
+ if (imported_uid)
{
- CompilerDeclContext imported_decl = dwarf->GetDeclContextForUID(imported_uid);
- if (imported_decl)
+ CompilerDeclContext imported_decl_ctx = imported_uid.GetDeclContext();
+ if (imported_decl_ctx)
{
clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
- if (clang::NamespaceDecl *ns_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(imported_decl))
+ if (clang::NamespaceDecl *ns_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(imported_decl_ctx))
decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
}
}
@@ -4001,34 +4257,3 @@ DWARFASTParserClang::CopyUniqueClassMethodTypes (const DWARFDIE &src_class_die,
return (failures.Size() != 0);
}
-
-bool
-DWARFASTParserClang::LayoutRecordType(const clang::RecordDecl *record_decl,
- uint64_t &bit_size,
- uint64_t &alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
-{
- RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl);
- bool success = false;
- base_offsets.clear();
- vbase_offsets.clear();
- if (pos != m_record_decl_to_layout_map.end())
- {
- bit_size = pos->second.bit_size;
- alignment = pos->second.alignment;
- field_offsets.swap(pos->second.field_offsets);
- base_offsets.swap (pos->second.base_offsets);
- vbase_offsets.swap (pos->second.vbase_offsets);
- m_record_decl_to_layout_map.erase(pos);
- success = true;
- }
- else
- {
- bit_size = 0;
- alignment = 0;
- field_offsets.clear();
- }
- return success;
-}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 3814758fdd2c..0826423b0359 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -19,11 +19,12 @@
#include "clang/AST/CharUnits.h"
// Project includes
+#include "DWARFASTParser.h"
+#include "DWARFDefines.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/ClangASTContext.h"
-#include "DWARFDefines.h"
-#include "DWARFASTParser.h"
+#include "lldb/Symbol/ClangASTImporter.h"
class DWARFDebugInfoEntry;
class DWARFDIECollection;
@@ -35,6 +36,7 @@ public:
~DWARFASTParserClang() override;
+ // DWARFASTParser interface.
lldb::TypeSP
ParseTypeFromDWARF (const lldb_private::SymbolContext& sc,
const DWARFDIE &die,
@@ -47,12 +49,6 @@ public:
const DWARFDIE &die) override;
bool
- CanCompleteType (const lldb_private::CompilerType &compiler_type) override;
-
- bool
- CompleteType (const lldb_private::CompilerType &compiler_type) override;
-
- bool
CompleteTypeFromDWARF (const DWARFDIE &die,
lldb_private::Type *type,
lldb_private::CompilerType &compiler_type) override;
@@ -69,43 +65,19 @@ public:
lldb_private::CompilerDeclContext
GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) override;
- bool
- LayoutRecordType(const clang::RecordDecl *record_decl,
- uint64_t &bit_size,
- uint64_t &alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets);
+ lldb_private::ClangASTImporter &
+ GetClangASTImporter();
protected:
class DelayedAddObjCClassProperty;
typedef std::vector <DelayedAddObjCClassProperty> DelayedPropertyList;
- struct LayoutInfo
- {
- LayoutInfo () :
- bit_size(0),
- alignment(0),
- field_offsets(),
- base_offsets(),
- vbase_offsets()
- {
- }
- uint64_t bit_size;
- uint64_t alignment;
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets;
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets;
- };
-
clang::BlockDecl *
ResolveBlockDIE (const DWARFDIE &die);
clang::NamespaceDecl *
ResolveNamespaceDIE (const DWARFDIE &die);
- typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo> RecordDeclToLayoutMap;
-
bool
ParseTemplateDIE (const DWARFDIE &die,
lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
@@ -114,17 +86,12 @@ protected:
lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
bool
- ParseChildMembers (const lldb_private::SymbolContext& sc,
- const DWARFDIE &die,
- lldb_private::CompilerType &class_compiler_type,
- const lldb::LanguageType class_language,
- std::vector<clang::CXXBaseSpecifier *>& base_classes,
- std::vector<int>& member_accessibilities,
- DWARFDIECollection& member_function_dies,
- DelayedPropertyList& delayed_properties,
- lldb::AccessType &default_accessibility,
- bool &is_a_class,
- LayoutInfo &layout_info);
+ ParseChildMembers(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+ lldb_private::CompilerType &class_compiler_type, const lldb::LanguageType class_language,
+ std::vector<clang::CXXBaseSpecifier *> &base_classes, std::vector<int> &member_accessibilities,
+ DWARFDIECollection &member_function_dies, DelayedPropertyList &delayed_properties,
+ lldb::AccessType &default_accessibility, bool &is_a_class,
+ lldb_private::ClangASTImporter::LayoutInfo &layout_info);
size_t
ParseChildParameters (const lldb_private::SymbolContext& sc,
@@ -133,6 +100,7 @@ protected:
bool skip_artificial,
bool &is_static,
bool &is_variadic,
+ bool &has_template_params,
std::vector<lldb_private::CompilerType>& function_args,
std::vector<clang::ParmVarDecl*>& function_param_decls,
unsigned &type_quals);
@@ -181,9 +149,6 @@ protected:
void
LinkDeclToDIE (clang::Decl *decl, const DWARFDIE &die);
- lldb_private::ClangASTImporter &
- GetClangASTImporter();
-
lldb::TypeSP
ParseTypeFromDWO (const DWARFDIE &die, lldb_private::Log *log);
@@ -206,7 +171,6 @@ protected:
DeclToDIEMap m_decl_to_die;
DIEToDeclContextMap m_die_to_decl_ctx;
DeclContextToDIEMap m_decl_ctx_to_die;
- RecordDeclToLayoutMap m_record_decl_to_layout_map;
std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap;
};
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
index bde2694461e2..346e2d63b908 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
@@ -144,7 +144,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
}
}
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", dwarf->MakeUserID(die.GetOffset()),
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", die.GetID(),
DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
switch (tag)
@@ -183,7 +183,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
break;
}
- type_sp.reset(new Type(dwarf->MakeUserID(die.GetOffset()), dwarf, type_name_const_str, byte_size,
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, byte_size,
NULL, encoding_uid, encoding_data_type, &decl, compiler_type, resolve_state));
dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
@@ -254,7 +254,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
}
}
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", dwarf->MakeUserID(die.GetOffset()),
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
DW_TAG_value_to_name(tag), type_name_cstr);
bool compiler_type_was_created = false;
@@ -265,7 +265,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
compiler_type = m_ast.CreateStructType(go_kind, type_name_const_str, byte_size);
}
- type_sp.reset(new Type(dwarf->MakeUserID(die.GetOffset()), dwarf, type_name_const_str, byte_size,
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, byte_size,
NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
Type::eResolveStateForward));
@@ -347,7 +347,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
}
}
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", dwarf->MakeUserID(die.GetOffset()),
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
DW_TAG_value_to_name(tag), type_name_cstr);
std::vector<CompilerType> function_param_types;
@@ -363,7 +363,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
compiler_type = m_ast.CreateFunctionType(type_name_const_str, function_param_types.data(),
function_param_types.size(), is_variadic);
- type_sp.reset(new Type(dwarf->MakeUserID(die.GetOffset()), dwarf, type_name_const_str, 0, NULL,
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL,
LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
Type::eResolveStateFull));
assert(type_sp.get());
@@ -410,7 +410,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
}
}
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", dwarf->MakeUserID(die.GetOffset()),
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
DW_TAG_value_to_name(tag), type_name_cstr);
Type *element_type = dwarf->ResolveTypeUID(type_die_offset);
@@ -433,7 +433,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
{
compiler_type = m_ast.CreateArrayType(type_name_const_str, array_element_type, 0);
}
- type_sp.reset(new Type(dwarf->MakeUserID(die.GetOffset()), dwarf, type_name_const_str,
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
byte_stride, NULL, type_die_offset, Type::eEncodingIsUID, &decl,
compiler_type, Type::eResolveStateFull));
type_sp->SetEncodingType(element_type);
@@ -463,7 +463,7 @@ DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, cons
else if (sc.function != NULL && sc_parent_die)
{
symbol_context_scope =
- sc.function->GetBlock(true).FindBlockByID(dwarf->MakeUserID(sc_parent_die.GetOffset()));
+ sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
if (symbol_context_scope == NULL)
symbol_context_scope = sc.function;
}
@@ -510,7 +510,7 @@ DWARFASTParserGo::ParseChildParameters(const SymbolContext &sc,
if (num_attributes > 0)
{
Declaration decl;
- dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
+ DWARFFormValue param_type_die_offset;
uint32_t i;
for (i = 0; i < num_attributes; ++i)
@@ -525,7 +525,7 @@ DWARFASTParserGo::ParseChildParameters(const SymbolContext &sc,
// = form_value.AsCString();
break;
case DW_AT_type:
- param_type_die_offset = form_value.Reference();
+ param_type_die_offset = form_value;
break;
case DW_AT_location:
// if (form_value.BlockData())
@@ -547,7 +547,7 @@ DWARFASTParserGo::ParseChildParameters(const SymbolContext &sc,
}
}
- Type *type = parent_die.ResolveTypeUID(param_type_die_offset);
+ Type *type = parent_die.ResolveTypeUID(DIERef(param_type_die_offset));
if (type)
{
function_param_types.push_back(type->GetForwardCompilerType());
@@ -628,7 +628,7 @@ DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type
Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
if (log)
dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
- log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", dwarf->MakeUserID(die.GetOffset()),
+ log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", die.GetID(),
DW_TAG_value_to_name(tag), type->GetName().AsCString());
assert(compiler_type);
DWARFAttributes attributes;
@@ -683,7 +683,7 @@ DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &par
Declaration decl;
const char *name = NULL;
- lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
+ DWARFFormValue encoding_uid;
uint32_t member_byte_offset = UINT32_MAX;
uint32_t i;
for (i = 0; i < num_attributes; ++i)
@@ -698,7 +698,7 @@ DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &par
name = form_value.AsCString();
break;
case DW_AT_type:
- encoding_uid = form_value.Reference();
+ encoding_uid = form_value;
break;
case DW_AT_data_member_location:
if (form_value.BlockData())
@@ -715,7 +715,7 @@ DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &par
NULL, // RegisterContext *
module_sp, debug_info_data, die.GetCU(),
block_offset, block_length, eRegisterKindDWARF,
- &initialValue, memberOffset, NULL))
+ &initialValue, NULL, memberOffset, NULL))
{
member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
@@ -735,7 +735,7 @@ DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &par
}
}
- Type *member_type = die.ResolveTypeUID(encoding_uid);
+ Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid));
if (member_type)
{
CompilerType member_go_type = member_type->GetFullCompilerType();
@@ -808,10 +808,12 @@ DWARFASTParserGo::ParseFunctionFromDWARF(const SymbolContext &sc, const DWARFDIE
if (dwarf->FixupAddress(func_range.GetBaseAddress()))
{
- const user_id_t func_user_id = dwarf->MakeUserID(die.GetOffset());
+ const user_id_t func_user_id = die.GetID();
func_sp.reset(new Function(sc.comp_unit,
- dwarf->MakeUserID(func_user_id), // UserID is the DIE offset
- dwarf->MakeUserID(func_user_id), func_name, func_type,
+ func_user_id, // UserID is the DIE offset
+ func_user_id,
+ func_name,
+ func_type,
func_range)); // first address range
if (func_sp.get() != NULL)
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
new file mode 100644
index 000000000000..b21bf2ded489
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
@@ -0,0 +1,555 @@
+//===-- DWARFASTParserJava.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFASTParserJava.h"
+#include "DWARFAttribute.h"
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugInfoEntry.h"
+#include "DWARFDebugInfoEntry.h"
+#include "DWARFDeclContext.h"
+#include "SymbolFileDWARF.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/SymbolContextScope.h"
+#include "lldb/Symbol/TypeList.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+DWARFASTParserJava::DWARFASTParserJava(JavaASTContext &ast) : m_ast(ast)
+{
+}
+
+DWARFASTParserJava::~DWARFASTParserJava()
+{
+}
+
+TypeSP
+DWARFASTParserJava::ParseBaseTypeFromDIE(const DWARFDIE &die)
+{
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ ConstString type_name;
+ uint64_t byte_size = 0;
+
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ for (uint32_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attr)
+ {
+ case DW_AT_name:
+ type_name.SetCString(form_value.AsCString());
+ break;
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ break;
+ case DW_AT_encoding:
+ break;
+ default:
+ assert(false && "Unsupported attribute for DW_TAG_base_type");
+ }
+ }
+ }
+
+ Declaration decl;
+ CompilerType compiler_type = m_ast.CreateBaseType(type_name);
+ return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size, nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, decl, compiler_type, Type::eResolveStateFull);
+}
+
+TypeSP
+DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die)
+{
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ ConstString linkage_name;
+ DWARFFormValue type_attr_value;
+ lldb::addr_t data_offset = LLDB_INVALID_ADDRESS;
+ DWARFExpression length_expression(die.GetCU());
+
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ for (uint32_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attr)
+ {
+ case DW_AT_linkage_name:
+ linkage_name.SetCString(form_value.AsCString());
+ break;
+ case DW_AT_type:
+ type_attr_value = form_value;
+ break;
+ case DW_AT_data_member_location:
+ data_offset = form_value.Unsigned();
+ break;
+ case DW_AT_declaration:
+ break;
+ default:
+ assert(false && "Unsupported attribute for DW_TAG_array_type");
+ }
+ }
+ }
+
+ for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); child_die = child_die.GetSibling())
+ {
+ if (child_die.Tag() == DW_TAG_subrange_type)
+ {
+ DWARFAttributes attributes;
+ const size_t num_attributes = child_die.GetAttributes(attributes);
+ for (uint32_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attr)
+ {
+ case DW_AT_count:
+ if (form_value.BlockData())
+ length_expression.CopyOpcodeData(form_value.BlockData(), form_value.Unsigned(),
+ child_die.GetCU()->GetByteOrder(),
+ child_die.GetCU()->GetAddressByteSize());
+ break;
+ default:
+ assert(false && "Unsupported attribute for DW_TAG_subrange_type");
+ }
+ }
+ }
+ }
+ else
+ {
+ assert(false && "Unsupported child for DW_TAG_array_type");
+ }
+ }
+
+ DIERef type_die_ref(type_attr_value);
+ Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
+ if (!element_type)
+ return nullptr;
+
+ CompilerType element_compiler_type = element_type->GetForwardCompilerType();
+ CompilerType array_compiler_type =
+ m_ast.CreateArrayType(linkage_name, element_compiler_type, length_expression, data_offset);
+
+ Declaration decl;
+ TypeSP type_sp(new Type(die.GetID(), dwarf, array_compiler_type.GetTypeName(), -1, nullptr,
+ type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl,
+ array_compiler_type, Type::eResolveStateFull));
+ type_sp->SetEncodingType(element_type);
+ return type_sp;
+}
+
+TypeSP
+DWARFASTParserJava::ParseReferenceTypeFromDIE(const DWARFDIE &die)
+{
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ Declaration decl;
+ DWARFFormValue type_attr_value;
+
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ for (uint32_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attr)
+ {
+ case DW_AT_type:
+ type_attr_value = form_value;
+ break;
+ default:
+ assert(false && "Unsupported attribute for DW_TAG_array_type");
+ }
+ }
+ }
+
+ DIERef type_die_ref(type_attr_value);
+ Type *pointee_type = dwarf->ResolveTypeUID(type_die_ref);
+ if (!pointee_type)
+ return nullptr;
+
+ CompilerType pointee_compiler_type = pointee_type->GetForwardCompilerType();
+ CompilerType reference_compiler_type = m_ast.CreateReferenceType(pointee_compiler_type);
+ TypeSP type_sp(new Type(die.GetID(), dwarf, reference_compiler_type.GetTypeName(), -1, nullptr,
+ type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl,
+ reference_compiler_type, Type::eResolveStateFull));
+ type_sp->SetEncodingType(pointee_type);
+ return type_sp;
+}
+
+lldb::TypeSP
+DWARFASTParserJava::ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type)
+{
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ Declaration decl;
+ ConstString name;
+ ConstString linkage_name;
+ bool is_forward_declaration = false;
+ uint32_t byte_size = 0;
+
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ for (uint32_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attr)
+ {
+ case DW_AT_name:
+ name.SetCString(form_value.AsCString());
+ break;
+ case DW_AT_declaration:
+ is_forward_declaration = form_value.Boolean();
+ break;
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ break;
+ case DW_AT_linkage_name:
+ linkage_name.SetCString(form_value.AsCString());
+ break;
+ default:
+ assert(false && "Unsupported attribute for DW_TAG_class_type");
+ }
+ }
+ }
+
+ UniqueDWARFASTType unique_ast_entry;
+ if (name)
+ {
+ std::string qualified_name;
+ if (die.GetQualifiedName(qualified_name))
+ {
+ name.SetCString(qualified_name.c_str());
+ if (dwarf->GetUniqueDWARFASTTypeMap().Find(name, die, Declaration(), -1, unique_ast_entry))
+ {
+ if (unique_ast_entry.m_type_sp)
+ {
+ dwarf->GetDIEToType()[die.GetDIE()] = unique_ast_entry.m_type_sp.get();
+ is_new_type = false;
+ return unique_ast_entry.m_type_sp;
+ }
+ }
+ }
+ }
+
+ if (is_forward_declaration)
+ {
+ DWARFDeclContext die_decl_ctx;
+ die.GetDWARFDeclContext(die_decl_ctx);
+
+ TypeSP type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+ if (type_sp)
+ {
+ // We found a real definition for this type elsewhere so lets use it
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ is_new_type = false;
+ return type_sp;
+ }
+ }
+
+ CompilerType compiler_type(&m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ if (!compiler_type)
+ compiler_type = m_ast.CreateObjectType(name, linkage_name, byte_size);
+
+ is_new_type = true;
+ TypeSP type_sp(new Type(die.GetID(), dwarf, name,
+ -1, // byte size isn't specified
+ nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
+ Type::eResolveStateForward));
+
+ // Add our type to the unique type map
+ unique_ast_entry.m_type_sp = type_sp;
+ unique_ast_entry.m_die = die;
+ unique_ast_entry.m_declaration = decl;
+ unique_ast_entry.m_byte_size = -1;
+ dwarf->GetUniqueDWARFASTTypeMap().Insert(name, unique_ast_entry);
+
+ if (!is_forward_declaration)
+ {
+ // Leave this as a forward declaration until we need to know the details of the type
+ dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = compiler_type.GetOpaqueQualType();
+ dwarf->GetForwardDeclClangTypeToDie()[compiler_type.GetOpaqueQualType()] = die.GetDIERef();
+ }
+ return type_sp;
+}
+
+lldb::TypeSP
+DWARFASTParserJava::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+ lldb_private::Log *log, bool *type_is_new_ptr)
+{
+ if (type_is_new_ptr)
+ *type_is_new_ptr = false;
+
+ if (!die)
+ return nullptr;
+
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+
+ Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
+ if (type_ptr == DIE_IS_BEING_PARSED)
+ return nullptr;
+ if (type_ptr != nullptr)
+ return type_ptr->shared_from_this();
+
+ TypeSP type_sp;
+ if (type_is_new_ptr)
+ *type_is_new_ptr = true;
+
+ switch (die.Tag())
+ {
+ case DW_TAG_base_type:
+ {
+ type_sp = ParseBaseTypeFromDIE(die);
+ break;
+ }
+ case DW_TAG_array_type:
+ {
+ type_sp = ParseArrayTypeFromDIE(die);
+ break;
+ }
+ case DW_TAG_class_type:
+ {
+ bool is_new_type = false;
+ type_sp = ParseClassTypeFromDIE(die, is_new_type);
+ if (!is_new_type)
+ return type_sp;
+ break;
+ }
+ case DW_TAG_reference_type:
+ {
+ type_sp = ParseReferenceTypeFromDIE(die);
+ break;
+ }
+ }
+
+ if (!type_sp)
+ return nullptr;
+
+ DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
+ dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+
+ SymbolContextScope *symbol_context_scope = nullptr;
+ if (sc_parent_tag == DW_TAG_compile_unit)
+ {
+ symbol_context_scope = sc.comp_unit;
+ }
+ else if (sc.function != nullptr && sc_parent_die)
+ {
+ symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
+ if (symbol_context_scope == nullptr)
+ symbol_context_scope = sc.function;
+ }
+
+ if (symbol_context_scope != nullptr)
+ type_sp->SetSymbolContextScope(symbol_context_scope);
+
+ dwarf->GetTypeList()->Insert(type_sp);
+ dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
+
+ return type_sp;
+}
+
+lldb_private::Function *
+DWARFASTParserJava::ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die)
+{
+ assert(die.Tag() == DW_TAG_subprogram);
+
+ const char *name = nullptr;
+ const char *mangled = nullptr;
+ int decl_file = 0;
+ int decl_line = 0;
+ int decl_column = 0;
+ int call_file = 0;
+ int call_line = 0;
+ int call_column = 0;
+ DWARFRangeList func_ranges;
+ DWARFExpression frame_base(die.GetCU());
+
+ if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line,
+ call_column, &frame_base))
+ {
+ // Union of all ranges in the function DIE (if the function is discontiguous)
+ AddressRange func_range;
+ lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
+ lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
+ if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
+ {
+ ModuleSP module_sp(die.GetModule());
+ func_range.GetBaseAddress().ResolveAddressUsingFileSections(lowest_func_addr, module_sp->GetSectionList());
+ if (func_range.GetBaseAddress().IsValid())
+ func_range.SetByteSize(highest_func_addr - lowest_func_addr);
+ }
+
+ if (func_range.GetBaseAddress().IsValid())
+ {
+ std::unique_ptr<Declaration> decl_ap;
+ if (decl_file != 0 || decl_line != 0 || decl_column != 0)
+ decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line,
+ decl_column));
+
+ if (die.GetDWARF()->FixupAddress(func_range.GetBaseAddress()))
+ {
+ FunctionSP func_sp(new Function(sc.comp_unit, die.GetID(), die.GetID(),
+ Mangled(ConstString(name), false),
+ nullptr, // No function types in java
+ func_range));
+ if (frame_base.IsValid())
+ func_sp->GetFrameBaseExpression() = frame_base;
+ sc.comp_unit->AddFunction(func_sp);
+
+ return func_sp.get();
+ }
+ }
+ }
+ return nullptr;
+}
+
+bool
+DWARFASTParserJava::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
+ lldb_private::CompilerType &java_type)
+{
+ switch (die.Tag())
+ {
+ case DW_TAG_class_type:
+ {
+ if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 0)
+ {
+ if (die.HasChildren())
+ ParseChildMembers(die, java_type);
+ m_ast.CompleteObjectType(java_type);
+ return java_type.IsValid();
+ }
+ }
+ break;
+ default:
+ assert(false && "Not a forward java type declaration!");
+ break;
+ }
+ return false;
+}
+
+void
+DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die, CompilerType &compiler_type)
+{
+ DWARFCompileUnit *dwarf_cu = parent_die.GetCU();
+ for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
+ {
+ switch (die.Tag())
+ {
+ case DW_TAG_member:
+ {
+ const char *name = nullptr;
+ DWARFFormValue encoding_uid;
+ uint32_t member_byte_offset = UINT32_MAX;
+ DWARFExpression member_location_expression(dwarf_cu);
+
+ DWARFAttributes attributes;
+ size_t num_attributes = die.GetAttributes(attributes);
+ for (size_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attributes.AttributeAtIndex(i))
+ {
+ case DW_AT_name:
+ name = form_value.AsCString();
+ break;
+ case DW_AT_type:
+ encoding_uid = form_value;
+ break;
+ case DW_AT_data_member_location:
+ if (form_value.BlockData())
+ member_location_expression.CopyOpcodeData(
+ form_value.BlockData(), form_value.Unsigned(), dwarf_cu->GetByteOrder(),
+ dwarf_cu->GetAddressByteSize());
+ else
+ member_byte_offset = form_value.Unsigned();
+ break;
+ case DW_AT_artificial:
+ static_cast<void>(form_value.Boolean());
+ break;
+ case DW_AT_accessibility:
+ // TODO: Handle when needed
+ break;
+ default:
+ assert(false && "Unhandled attribute for DW_TAG_member");
+ break;
+ }
+ }
+ }
+
+ if (strcmp(name, ".dynamic_type") == 0)
+ m_ast.SetDynamicTypeId(compiler_type, member_location_expression);
+ else
+ {
+ if (Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid)))
+ m_ast.AddMemberToObject(compiler_type, ConstString(name), member_type->GetFullCompilerType(),
+ member_byte_offset);
+ }
+ break;
+ }
+ case DW_TAG_inheritance:
+ {
+ DWARFFormValue encoding_uid;
+ uint32_t member_byte_offset = UINT32_MAX;
+
+ DWARFAttributes attributes;
+ size_t num_attributes = die.GetAttributes(attributes);
+ for (size_t i = 0; i < num_attributes; ++i)
+ {
+ DWARFFormValue form_value;
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ {
+ switch (attributes.AttributeAtIndex(i))
+ {
+ case DW_AT_type:
+ encoding_uid = form_value;
+ break;
+ case DW_AT_data_member_location:
+ member_byte_offset = form_value.Unsigned();
+ break;
+ case DW_AT_accessibility:
+ // In java all base class is public so we can ignore this attribute
+ break;
+ default:
+ assert(false && "Unhandled attribute for DW_TAG_member");
+ break;
+ }
+ }
+ }
+ if (Type *base_type = die.ResolveTypeUID(DIERef(encoding_uid)))
+ m_ast.AddBaseClassToObject(compiler_type, base_type->GetFullCompilerType(), member_byte_offset);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h
new file mode 100644
index 000000000000..6a7eee75e6f7
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h
@@ -0,0 +1,90 @@
+//===-- DWARFASTParserJava.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SymbolFileDWARF_DWARFASTParserJava_h_
+#define SymbolFileDWARF_DWARFASTParserJava_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+
+// Project includes
+#include "DWARFASTParser.h"
+#include "DWARFDIE.h"
+#include "DWARFDefines.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/JavaASTContext.h"
+
+class DWARFDebugInfoEntry;
+class DWARFDIECollection;
+
+class DWARFASTParserJava : public DWARFASTParser
+{
+public:
+ DWARFASTParserJava(lldb_private::JavaASTContext &ast);
+ ~DWARFASTParserJava() override;
+
+ lldb::TypeSP
+ ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die, lldb_private::Log *log,
+ bool *type_is_new_ptr) override;
+
+ lldb_private::Function *
+ ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die) override;
+
+ bool
+ CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
+ lldb_private::CompilerType &java_type) override;
+
+ lldb_private::CompilerDeclContext
+ GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override
+ {
+ return lldb_private::CompilerDeclContext();
+ }
+
+ lldb_private::CompilerDeclContext
+ GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override
+ {
+ return lldb_private::CompilerDeclContext();
+ }
+
+ lldb_private::CompilerDecl
+ GetDeclForUIDFromDWARF(const DWARFDIE &die) override
+ {
+ return lldb_private::CompilerDecl();
+ }
+
+ std::vector<DWARFDIE>
+ GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) override
+ {
+ return std::vector<DWARFDIE>();
+ }
+
+ void
+ ParseChildMembers(const DWARFDIE &parent_die, lldb_private::CompilerType &class_compiler_type);
+
+private:
+ lldb_private::JavaASTContext &m_ast;
+
+ lldb::TypeSP
+ ParseBaseTypeFromDIE(const DWARFDIE &die);
+
+ lldb::TypeSP
+ ParseArrayTypeFromDIE(const DWARFDIE &die);
+
+ lldb::TypeSP
+ ParseReferenceTypeFromDIE(const DWARFDIE &die);
+
+ lldb::TypeSP
+ ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type);
+};
+
+#endif // SymbolFileDWARF_DWARFASTParserJava_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index e7cb2b413ad7..c5d7568b5272 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -311,46 +311,12 @@ DWARFCompileUnit::AddCompileUnitDIE(DWARFDebugInfoEntry& die)
{
assert (m_die_array.empty() && "Compile unit DIE already added");
AddDIE(die);
-
- DWARFDebugInfoEntry& cu_die = m_die_array.front();
-
- const char* dwo_name = cu_die.GetAttributeValueAsString(m_dwarf2Data,
- this,
- DW_AT_GNU_dwo_name,
- nullptr);
- if (!dwo_name)
- return;
-
- FileSpec dwo_file(dwo_name, true);
- if (dwo_file.IsRelative())
- {
- const char* comp_dir = cu_die.GetAttributeValueAsString(m_dwarf2Data,
- this,
- DW_AT_comp_dir,
- nullptr);
- if (!comp_dir)
- return;
-
- dwo_file.SetFile(comp_dir, true);
- dwo_file.AppendPathComponent(dwo_name);
- }
-
- if (!dwo_file.Exists())
- return;
- DataBufferSP dwo_file_data_sp;
- lldb::offset_t dwo_file_data_offset = 0;
- ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(m_dwarf2Data->GetObjectFile()->GetModule(),
- &dwo_file,
- 0 /* file_offset */,
- dwo_file.GetByteSize(),
- dwo_file_data_sp,
- dwo_file_data_offset);
- if (dwo_obj_file == nullptr)
+ const DWARFDebugInfoEntry &cu_die = m_die_array.front();
+ std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file = m_dwarf2Data->GetDwoSymbolFileForCompileUnit(*this, cu_die);
+ if (!dwo_symbol_file)
return;
- std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file(new SymbolFileDWARFDwo(dwo_obj_file, this));
-
DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit();
if (!dwo_cu)
return; // Can't fetch the compile unit from the dwo file.
@@ -467,7 +433,7 @@ DWARFCompileUnit::GetID () const
{
dw_offset_t local_id = m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset;
if (m_dwarf2Data)
- return m_dwarf2Data->MakeUserID(local_id);
+ return DIERef(local_id, local_id).GetUID(m_dwarf2Data);
else
return local_id;
}
@@ -665,7 +631,7 @@ DWARFCompileUnit::GetDIE (dw_offset_t die_offset)
{
// Don't specify the compile unit offset as we don't know it because the DIE belongs to
// a different compile unit in the same symbol file.
- return m_dwarf2Data->DebugInfo()->GetDIE (DIERef(die_offset));
+ return m_dwarf2Data->DebugInfo()->GetDIEForDIEOffset(die_offset);
}
}
return DWARFDIE(); // Not found
@@ -789,20 +755,21 @@ DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu,
switch (tag)
{
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
+ case DW_TAG_array_type:
case DW_TAG_base_type:
case DW_TAG_class_type:
case DW_TAG_constant:
case DW_TAG_enumeration_type:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_namespace:
case DW_TAG_string_type:
- case DW_TAG_subroutine_type:
case DW_TAG_structure_type:
- case DW_TAG_union_type:
+ case DW_TAG_subprogram:
+ case DW_TAG_subroutine_type:
case DW_TAG_typedef:
- case DW_TAG_namespace:
- case DW_TAG_variable:
+ case DW_TAG_union_type:
case DW_TAG_unspecified_type:
+ case DW_TAG_variable:
break;
default:
@@ -977,7 +944,7 @@ DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu,
// as our name. If it starts with '_', then it is ok, else compare
// the string to make sure it isn't the same and we don't end up
// with duplicate entries
- if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (name && ::strcmp(name, mangled_cstr) != 0)))
+ if (name && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0)))
{
Mangled mangled (ConstString(mangled_cstr), true);
func_fullnames.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset()));
@@ -1000,7 +967,7 @@ DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu,
// as our name. If it starts with '_', then it is ok, else compare
// the string to make sure it isn't the same and we don't end up
// with duplicate entries
- if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0)))
+ if (name && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0)))
{
Mangled mangled (ConstString(mangled_cstr), true);
func_fullnames.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset()));
@@ -1014,20 +981,21 @@ DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu,
}
break;
+ case DW_TAG_array_type:
case DW_TAG_base_type:
case DW_TAG_class_type:
case DW_TAG_constant:
case DW_TAG_enumeration_type:
case DW_TAG_string_type:
- case DW_TAG_subroutine_type:
case DW_TAG_structure_type:
- case DW_TAG_union_type:
+ case DW_TAG_subroutine_type:
case DW_TAG_typedef:
+ case DW_TAG_union_type:
case DW_TAG_unspecified_type:
- if (name && is_declaration == false)
- {
+ if (name && !is_declaration)
types.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
- }
+ if (mangled_cstr && !is_declaration)
+ types.Insert (ConstString(mangled_cstr), DIERef(cu_offset, die.GetOffset()));
break;
case DW_TAG_namespace:
@@ -1180,7 +1148,7 @@ DWARFCompileUnit::LanguageTypeFromDWARF(uint64_t val)
{
case DW_LANG_Mips_Assembler:
return eLanguageTypeMipsAssembler;
- case 0x8e57: // FIXME: needs to be added to llvm
+ case DW_LANG_GOOGLE_RenderScript:
return eLanguageTypeExtRenderScript;
default:
return static_cast<LanguageType>(val);
@@ -1259,3 +1227,9 @@ DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base, dw_offset_t base_obj_offset)
m_addr_base = addr_base;
m_base_obj_offset = base_obj_offset;
}
+
+lldb::ByteOrder
+DWARFCompileUnit::GetByteOrder() const
+{
+ return m_dwarf2Data->GetObjectFile()->GetByteOrder();
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
index 0fcaaca09ed8..8d96e3698ab2 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -59,6 +59,8 @@ public:
void BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data,
DWARFDebugAranges* debug_aranges);
+ lldb::ByteOrder
+ GetByteOrder() const;
lldb_private::TypeSystem *
GetTypeSystem();
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 0564de9e5dd1..0f02c74fd2eb 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -9,6 +9,7 @@
#include "DWARFDIE.h"
+#include "DWARFASTParser.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
@@ -127,6 +128,21 @@ DWARFDIE::GetAttributeValueAsSigned (const dw_attr_t attr, int64_t fail_value) c
return fail_value;
}
+DWARFDIE
+DWARFDIE::GetAttributeValueAsReferenceDIE (const dw_attr_t attr) const
+{
+ if (IsValid())
+ {
+ DWARFCompileUnit *cu = GetCU();
+ SymbolFileDWARF *dwarf = cu->GetSymbolFileDWARF();
+ const bool check_specification_or_abstract_origin = true;
+ DWARFFormValue form_value;
+ if (m_die->GetAttributeValue(dwarf, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
+ return dwarf->GetDIE(DIERef(form_value));
+ }
+ return DWARFDIE();
+}
+
uint64_t
DWARFDIE::GetAttributeValueAsReference (const dw_attr_t attr, uint64_t fail_value) const
{
@@ -166,7 +182,7 @@ DWARFDIE::LookupDeepestBlock (lldb::addr_t file_addr) const
if (cu->ContainsDIEOffset(block_die->GetOffset()))
return DWARFDIE(cu, block_die);
else
- return DWARFDIE(dwarf->DebugInfo()->GetCompileUnitContainingDIE(DIERef(cu->GetOffset(), block_die->GetOffset())), block_die);
+ return DWARFDIE(dwarf->DebugInfo()->GetCompileUnit(DIERef(cu->GetOffset(), block_die->GetOffset())), block_die);
}
}
}
@@ -176,27 +192,7 @@ DWARFDIE::LookupDeepestBlock (lldb::addr_t file_addr) const
lldb::user_id_t
DWARFDIE::GetID () const
{
- const dw_offset_t die_offset = GetOffset();
- if (die_offset != DW_INVALID_OFFSET)
- {
- lldb::user_id_t id = 0;
- SymbolFileDWARF *dwarf = GetDWARF();
- if (dwarf)
- id = dwarf->MakeUserID(die_offset);
- else
- id = die_offset;
-
- if (m_cu)
- {
- lldb::user_id_t cu_id = m_cu->GetID()&0xffffffff00000000ull;
- assert ((id&0xffffffff00000000ull) == 0 ||
- (cu_id&0xffffffff00000000ll) == 0 ||
- (id&0xffffffff00000000ull) == (cu_id&0xffffffff00000000ll));
- id |= cu_id;
- }
- return id;
- }
- return LLDB_INVALID_UID;
+ return GetDIERef().GetUID(GetDWARF());
}
const char *
@@ -274,11 +270,11 @@ DWARFDIE::ResolveType () const
}
lldb_private::Type *
-DWARFDIE::ResolveTypeUID (lldb::user_id_t uid) const
+DWARFDIE::ResolveTypeUID (const DIERef &die_ref) const
{
SymbolFileDWARF *dwarf = GetDWARF();
if (dwarf)
- return dwarf->ResolveTypeUID(uid);
+ return dwarf->ResolveTypeUID(dwarf->GetDIE(die_ref), true);
else
return nullptr;
}
@@ -302,6 +298,7 @@ DWARFDIE::GetDWARFDeclContext (DWARFDeclContext &dwarf_decl_ctx) const
{
if (IsValid())
{
+ dwarf_decl_ctx.SetLanguage(GetLanguage());
m_die->GetDWARFDeclContext (GetDWARF(), GetCU(), dwarf_decl_ctx);
}
else
@@ -530,6 +527,36 @@ DWARFDIE::Dump (lldb_private::Stream *s, const uint32_t recurse_depth) const
}
+CompilerDecl
+DWARFDIE::GetDecl () const
+{
+ DWARFASTParser *dwarf_ast = GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclForUIDFromDWARF(*this);
+ else
+ return CompilerDecl();
+}
+
+CompilerDeclContext
+DWARFDIE::GetDeclContext () const
+{
+ DWARFASTParser *dwarf_ast = GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclContextForUIDFromDWARF(*this);
+ else
+ return CompilerDeclContext();
+}
+
+CompilerDeclContext
+DWARFDIE::GetContainingDeclContext () const
+{
+ DWARFASTParser *dwarf_ast = GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclContextContainingUIDFromDWARF(*this);
+ else
+ return CompilerDeclContext();
+}
+
bool operator == (const DWARFDIE &lhs, const DWARFDIE &rhs)
{
return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU();
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index db37a45ad01a..2dcd1d7dc43e 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -58,7 +58,7 @@ public:
//----------------------------------------------------------------------
// Tests
//----------------------------------------------------------------------
- operator bool () const
+ explicit operator bool () const
{
return IsValid();
}
@@ -180,9 +180,11 @@ public:
lldb_private::Type *
ResolveType () const;
+ //----------------------------------------------------------------------
// Resolve a type by UID using this DIE's DWARF file
+ //----------------------------------------------------------------------
lldb_private::Type *
- ResolveTypeUID (lldb::user_id_t uid) const;
+ ResolveTypeUID (const DIERef &die_ref) const;
//----------------------------------------------------------------------
// Functions for obtaining DIE relations and references
@@ -245,6 +247,9 @@ public:
uint64_t
GetAttributeValueAsReference (const dw_attr_t attr, uint64_t fail_value) const;
+ DWARFDIE
+ GetAttributeValueAsReferenceDIE (const dw_attr_t attr) const;
+
uint64_t
GetAttributeValueAsAddress (const dw_attr_t attr, uint64_t fail_value) const;
@@ -270,6 +275,15 @@ public:
void
Dump (lldb_private::Stream *s, const uint32_t recurse_depth) const;
+ lldb_private::CompilerDecl
+ GetDecl () const;
+
+ lldb_private::CompilerDeclContext
+ GetDeclContext() const;
+
+ lldb_private::CompilerDeclContext
+ GetContainingDeclContext() const;
+
protected:
DWARFCompileUnit *m_cu;
DWARFDebugInfoEntry *m_die;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
index 9e021c7185bd..e9f09fd8776c 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
@@ -16,17 +16,6 @@
using namespace lldb_private;
using namespace std;
-bool
-DWARFDIECollection::Insert(const DWARFDIE &die)
-{
- iterator end_pos = m_dies.end();
- iterator insert_pos = upper_bound(m_dies.begin(), end_pos, die);
- if (insert_pos != end_pos && (*insert_pos == die))
- return false;
- m_dies.insert(insert_pos, die);
- return true;
-}
-
void
DWARFDIECollection::Append (const DWARFDIE &die)
{
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
index e39e1aa4ccda..83d58ec49300 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
@@ -33,9 +33,6 @@ public:
DWARFDIE
GetDIEAtIndex (uint32_t idx) const;
- bool
- Insert(const DWARFDIE &die);
-
size_t
Size() const;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index a1b00d1892e9..417f2cd79bda 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -209,48 +209,51 @@ DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr)
}
DWARFCompileUnit *
-DWARFDebugInfo::GetCompileUnitContainingDIE (const DIERef& die_ref)
+DWARFDebugInfo::GetCompileUnit (const DIERef& die_ref)
{
- dw_offset_t search_offset = die_ref.die_offset;
- bool is_cu_offset = false;
- if (m_dwarf2Data->GetID() == 0 && die_ref.cu_offset != DW_INVALID_OFFSET)
- {
- is_cu_offset = true;
- search_offset = die_ref.cu_offset;
- }
+ if (die_ref.cu_offset == DW_INVALID_OFFSET)
+ return GetCompileUnitContainingDIEOffset(die_ref.die_offset);
+ else
+ return GetCompileUnit(die_ref.cu_offset);
+}
+
+DWARFCompileUnit*
+DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset)
+{
+ ParseCompileUnitHeadersIfNeeded();
DWARFCompileUnitSP cu_sp;
- if (search_offset != DW_INVALID_OFFSET)
- {
- ParseCompileUnitHeadersIfNeeded();
- // Watch out for single compile unit executable as they are pretty common
- const size_t num_cus = m_compile_units.size();
- if (num_cus == 1)
- {
- if ((is_cu_offset && m_compile_units[0]->GetOffset() == search_offset) ||
- (!is_cu_offset && m_compile_units[0]->ContainsDIEOffset(search_offset)))
- {
- cu_sp = m_compile_units[0];
- }
- }
- else if (num_cus)
+ // Watch out for single compile unit executable as they are pretty common
+ const size_t num_cus = m_compile_units.size();
+ if (num_cus == 1)
+ {
+ if (m_compile_units[0]->ContainsDIEOffset(die_offset))
+ return m_compile_units[0].get();
+ }
+ else if (num_cus)
+ {
+ CompileUnitColl::const_iterator end_pos = m_compile_units.end();
+ CompileUnitColl::const_iterator begin_pos = m_compile_units.begin();
+ CompileUnitColl::const_iterator pos = std::upper_bound(begin_pos, end_pos, die_offset, OffsetLessThanCompileUnitOffset);
+ if (pos != begin_pos)
{
- CompileUnitColl::const_iterator end_pos = m_compile_units.end();
- CompileUnitColl::const_iterator begin_pos = m_compile_units.begin();
- CompileUnitColl::const_iterator pos = std::upper_bound(begin_pos, end_pos, search_offset, OffsetLessThanCompileUnitOffset);
- if (pos != begin_pos)
- {
- --pos;
- if ((is_cu_offset && (*pos)->GetOffset() == search_offset) ||
- (!is_cu_offset && (*pos)->ContainsDIEOffset(search_offset)))
- {
- cu_sp = *pos;
- }
- }
+ --pos;
+ if ((*pos)->ContainsDIEOffset(die_offset))
+ return (*pos).get();
}
}
- return cu_sp.get();
+
+ return nullptr;
+}
+
+DWARFDIE
+DWARFDebugInfo::GetDIEForDIEOffset(dw_offset_t die_offset)
+{
+ DWARFCompileUnit* cu = GetCompileUnitContainingDIEOffset(die_offset);
+ if (cu)
+ return cu->GetDIE(die_offset);
+ return DWARFDIE();
}
//----------------------------------------------------------------------
@@ -261,7 +264,7 @@ DWARFDebugInfo::GetCompileUnitContainingDIE (const DIERef& die_ref)
DWARFDIE
DWARFDebugInfo::GetDIE(const DIERef& die_ref)
{
- DWARFCompileUnit *cu = GetCompileUnitContainingDIE(die_ref);
+ DWARFCompileUnit *cu = GetCompileUnit(die_ref);
if (cu)
return cu->GetDIE (die_ref.die_offset);
return DWARFDIE(); // Not found
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index ea2e204db702..7783135bdb95 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -39,9 +39,10 @@ public:
size_t GetNumCompileUnits();
bool ContainsCompileUnit (const DWARFCompileUnit *cu) const;
DWARFCompileUnit* GetCompileUnitAtIndex (uint32_t idx);
- DWARFCompileUnit* GetCompileUnit (dw_offset_t cu_offset, uint32_t* idx_ptr = NULL);
- DWARFCompileUnit* GetCompileUnitContainingDIE (const DIERef& die_ref);
-
+ DWARFCompileUnit* GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr = NULL);
+ DWARFCompileUnit* GetCompileUnitContainingDIEOffset (dw_offset_t die_offset);
+ DWARFCompileUnit* GetCompileUnit(const DIERef& die_ref);
+ DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset);
DWARFDIE GetDIE (const DIERef& die_ref);
void Dump(lldb_private::Stream *s, const uint32_t die_offset, const uint32_t recurse_depth);
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index b9d825489aef..f48d8fc9eeb2 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -482,11 +482,19 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges
case DW_AT_ranges:
{
const DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
- debug_ranges->FindRanges(form_value.Unsigned(), ranges);
- // All DW_AT_ranges are relative to the base address of the
- // compile unit. We add the compile unit base address to make
- // sure all the addresses are properly fixed up.
- ranges.Slide(cu->GetBaseAddress());
+ if (debug_ranges)
+ {
+ debug_ranges->FindRanges(form_value.Unsigned(), ranges);
+ // All DW_AT_ranges are relative to the base address of the
+ // compile unit. We add the compile unit base address to make
+ // sure all the addresses are properly fixed up.
+ ranges.Slide(cu->GetBaseAddress());
+ }
+ else
+ {
+ cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute yet DWARF has no .debug_ranges, please file a bug and attach the file at the start of this error message",
+ m_offset, form_value.Unsigned());
+ }
}
break;
@@ -602,7 +610,7 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges
{
if (die_ref.die_offset != DW_INVALID_OFFSET)
{
- DWARFDIE die = dwarf2Data->DebugInfo()->GetDIE(die_ref);
+ DWARFDIE die = dwarf2Data->GetDIE(die_ref);
if (die)
die.GetDIE()->GetDIENamesAndRanges(die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column);
}
@@ -934,7 +942,7 @@ DWARFDebugInfoEntry::GetAttributes (const DWARFCompileUnit* cu,
// referencing this DIE because curr_depth is not zero
break;
}
- // Fall through...
+ LLVM_FALLTHROUGH;
default:
attributes.Append(cu, offset, attr, form);
break;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 02bbff8defc0..27b4fe93bc33 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -115,6 +115,13 @@ public:
DWARFAttributes& attrs,
uint32_t curr_depth = 0) const; // "curr_depth" for internal use only, don't set this yourself!!!
+ dw_offset_t GetAttributeValue(SymbolFileDWARF* dwarf2Data,
+ const DWARFCompileUnit* cu,
+ const dw_attr_t attr,
+ DWARFFormValue& formValue,
+ dw_offset_t* end_attr_offset_ptr = nullptr,
+ bool check_specification_or_abstract_origin = false) const;
+
const char* GetAttributeValueAsString(
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
@@ -382,12 +389,6 @@ public:
DWARFDebugInfoEntry::collection &die_collection);
protected:
- dw_offset_t GetAttributeValue(SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- DWARFFormValue& formValue,
- dw_offset_t* end_attr_offset_ptr = nullptr,
- bool check_specification_or_abstract_origin = false) const;
dw_offset_t m_offset; // Offset within the .debug_info of the start of this entry
uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. If zero this die has no parent
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index 4c29447b47bb..2452274a293b 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -64,7 +64,8 @@ public:
};
DWARFDeclContext () :
- m_entries()
+ m_entries(),
+ m_language(lldb::eLanguageTypeUnknown)
{
}
@@ -115,10 +116,23 @@ public:
m_qualified_name.clear();
}
+ lldb::LanguageType
+ GetLanguage() const
+ {
+ return m_language;
+ }
+
+ void
+ SetLanguage(lldb::LanguageType language)
+ {
+ m_language = language;
+ }
+
protected:
typedef std::vector<Entry> collection;
collection m_entries;
mutable std::string m_qualified_name;
+ lldb::LanguageType m_language;
};
#endif // SymbolFileDWARF_DWARFDeclContext_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index a0ed9731a565..addc14858461 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -167,6 +167,14 @@ DWARFFormValue::DWARFFormValue(const DWARFCompileUnit* cu, dw_form_t form) :
{
}
+void
+DWARFFormValue::Clear()
+{
+ m_cu = nullptr;
+ m_form = 0;
+ memset(&m_value, 0, sizeof(m_value));
+}
+
bool
DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr)
{
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index b10f4d3a0ac9..07bd038d9486 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -101,6 +101,7 @@ public:
static FixedFormSizes GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64);
static int Compare (const DWARFFormValue& a,
const DWARFFormValue& b);
+ void Clear();
protected:
const DWARFCompileUnit* m_cu; // Compile unit for this form
dw_form_t m_form; // Form for this value
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index 0db416054ae8..12e1e89c36bd 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -220,7 +220,7 @@ DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form)
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
hash_data_has_fixed_byte_size = false;
- // Fall through to the cases below...
+ LLVM_FALLTHROUGH;
case DW_FORM_flag:
case DW_FORM_data1:
case DW_FORM_ref1:
@@ -230,7 +230,7 @@ DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form)
case DW_FORM_block2:
hash_data_has_fixed_byte_size = false;
- // Fall through to the cases below...
+ LLVM_FALLTHROUGH;
case DW_FORM_data2:
case DW_FORM_ref2:
min_hash_data_byte_size += 2;
@@ -238,7 +238,7 @@ DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form)
case DW_FORM_block4:
hash_data_has_fixed_byte_size = false;
- // Fall through to the cases below...
+ LLVM_FALLTHROUGH;
case DW_FORM_data4:
case DW_FORM_ref4:
case DW_FORM_addr:
@@ -346,7 +346,8 @@ DWARFMappedHash::Header::Read (const lldb_private::DWARFDataExtractor &data,
case eAtomTypeTag: // DW_TAG value for the DIE
hash_data.tag = (dw_tag_t)form_value.Unsigned ();
-
+ break;
+
case eAtomTypeTypeFlags: // Flags from enum TypeFlags
hash_data.type_flags = (uint32_t)form_value.Unsigned ();
break;
@@ -671,6 +672,9 @@ DWARFMappedHash::MemoryTable::AppendAllDIEsInRange (const uint32_t die_offset_st
size_t
DWARFMappedHash::MemoryTable::FindByName (const char *name, DIEArray &die_offsets)
{
+ if (!name || !name[0])
+ return 0;
+
DIEInfoArray die_info_array;
if (FindByName(name, die_info_array))
DWARFMappedHash::ExtractDIEArray (die_info_array, die_offsets);
@@ -736,6 +740,9 @@ DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName (const char *name,
size_t
DWARFMappedHash::MemoryTable::FindByName (const char *name, DIEInfoArray &die_info_array)
{
+ if (!name || !name[0])
+ return 0;
+
Pair kv_pair;
size_t old_size = die_info_array.size();
if (Find (name, kv_pair))
diff --git a/source/Plugins/SymbolFile/DWARF/Makefile b/source/Plugins/SymbolFile/DWARF/Makefile
deleted file mode 100644
index 509065650ab9..000000000000
--- a/source/Plugins/SymbolFile/DWARF/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/SymbolFile/DWARF/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginSymbolFileDWARF
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 2088864bf6b1..942a5d62d9b4 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -35,16 +35,17 @@
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
+#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
-#include "lldb/Symbol/CompileUnit.h"
-#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/DebugMacros.h"
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
-#include "lldb/Symbol/TypeMap.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
@@ -54,7 +55,9 @@
#include "lldb/Utility/TaskPool.h"
#include "DWARFASTParser.h"
+#include "DWARFASTParserClang.h"
#include "DWARFCompileUnit.h"
+#include "DWARFDIECollection.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
@@ -63,11 +66,10 @@
#include "DWARFDebugPubnames.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
-#include "DWARFDIECollection.h"
#include "DWARFFormValue.h"
#include "LogChannelDWARF.h"
-#include "SymbolFileDWARFDwo.h"
#include "SymbolFileDWARFDebugMap.h"
+#include "SymbolFileDWARFDwo.h"
#include <map>
@@ -277,9 +279,11 @@ SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
TypeList *
SymbolFileDWARF::GetTypeList ()
{
- if (GetDebugMapSymfile ())
- return m_debug_map_symfile->GetTypeList();
- return m_obj_file->GetModule()->GetTypeList();
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ return debug_map_symfile->GetTypeList();
+ else
+ return m_obj_file->GetModule()->GetTypeList();
}
void
@@ -483,15 +487,17 @@ GetDWARFMachOSegmentName ()
UniqueDWARFASTTypeMap &
SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
{
- if (GetDebugMapSymfile ())
- return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
- return m_unique_ast_type_map;
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ return debug_map_symfile->GetUniqueDWARFASTTypeMap ();
+ else
+ return m_unique_ast_type_map;
}
TypeSystem *
SymbolFileDWARF::GetTypeSystemForLanguage (LanguageType language)
{
- SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
TypeSystem *type_system;
if (debug_map_symfile)
{
@@ -823,30 +829,13 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
DWARFDebugInfo* info = DebugInfo();
if (info)
{
- if (GetDebugMapSymfile ())
- {
- // The debug map symbol file made the compile units for this DWARF
- // file which is .o file with DWARF in it, and we should have
- // only 1 compile unit which is at offset zero in the DWARF.
- // TODO: modify to support LTO .o files where each .o file might
- // have multiple DW_TAG_compile_unit tags.
-
- DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0);
- if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
- dwarf_cu->SetUserData(comp_unit);
- return dwarf_cu;
- }
- else
- {
- // Just a normal DWARF file whose user ID for the compile unit is
- // the DWARF offset itself
+ // Just a normal DWARF file whose user ID for the compile unit is
+ // the DWARF offset itself
- DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
- if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
- dwarf_cu->SetUserData(comp_unit);
- return dwarf_cu;
-
- }
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
+ if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
+ dwarf_cu->SetUserData(comp_unit);
+ return dwarf_cu;
}
return NULL;
}
@@ -893,7 +882,7 @@ SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
{
return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, cu_idx);
}
- else if (GetDebugMapSymfile ())
+ else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile ())
{
// Let the debug map create the compile unit
cu_sp = m_debug_map_symfile->GetCompileUnit(this);
@@ -926,12 +915,8 @@ SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
bool is_optimized = dwarf_cu->GetIsOptimized ();
- cu_sp.reset(new CompileUnit (module_sp,
- dwarf_cu,
- cu_file_spec,
- dwarf_cu->GetID(),
- cu_language,
- is_optimized));
+ cu_sp.reset(new CompileUnit(module_sp, dwarf_cu, cu_file_spec, dwarf_cu->GetID(), cu_language,
+ is_optimized ? eLazyBoolYes : eLazyBoolNo));
if (cu_sp)
{
// If we just created a compile unit with an invalid file spec, try and get the
@@ -1007,7 +992,7 @@ SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFD
bool
SymbolFileDWARF::FixupAddress (Address &addr)
{
- SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
+ SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile();
if (debug_map_symfile)
{
return debug_map_symfile->LinkOSOAddress(addr);
@@ -1063,7 +1048,6 @@ SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpec
if (cu_die)
{
const char * cu_comp_dir = resolveCompDir(cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
-
const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
if (stmt_list != DW_INVALID_OFFSET)
{
@@ -1082,7 +1066,17 @@ SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpec
}
bool
-SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules)
+SymbolFileDWARF::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc)
+{
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu)
+ return dwarf_cu->GetIsOptimized();
+ return false;
+}
+
+bool
+SymbolFileDWARF::ParseImportedModules(const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules)
{
assert (sc.comp_unit);
DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
@@ -1091,9 +1085,40 @@ SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, st
if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
{
UpdateExternalModuleListIfNeeded();
- for (const auto &pair : m_external_type_modules)
+
+ if (sc.comp_unit)
{
- imported_modules.push_back(pair.first);
+ const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
+
+ if (die)
+ {
+ for (DWARFDIE child_die = die.GetFirstChild();
+ child_die;
+ child_die = child_die.GetSibling())
+ {
+ if (child_die.Tag() == DW_TAG_imported_declaration)
+ {
+ if (DWARFDIE module_die = child_die.GetReferencedDIE(DW_AT_import))
+ {
+ if (module_die.Tag() == DW_TAG_module)
+ {
+ if (const char *name = module_die.GetAttributeValueAsString(DW_AT_name, nullptr))
+ {
+ ConstString const_name(name);
+ imported_modules.push_back(const_name);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for (const auto &pair : m_external_type_modules)
+ {
+ imported_modules.push_back(pair.first);
+ }
}
}
}
@@ -1198,13 +1223,14 @@ SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
lldb::offset_t offset = cu_line_offset;
DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
- if (m_debug_map_symfile)
+ 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.
- sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
+ sc.comp_unit->SetLineTable (debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
}
else
{
@@ -1439,63 +1465,71 @@ SymbolFileDWARF::ParseDeclsForContext (CompilerDeclContext decl_ctx)
ast_parser->GetDeclForUIDFromDWARF(decl);
}
+SymbolFileDWARF *
+SymbolFileDWARF::GetDWARFForUID (lldb::user_id_t uid)
+{
+ // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
+ // we must make sure we use the correct DWARF file when resolving things.
+ // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
+ // SymbolFileDWARF classes, one for each .o file. We can often end up
+ // with references to other DWARF objects and we must be ready to receive
+ // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
+ // instance.
+ SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile();
+ if (debug_map)
+ return debug_map->GetSymbolFileByOSOIndex(debug_map->GetOSOIndexFromUserID(uid));
+ return this;
+}
+
+DWARFDIE
+SymbolFileDWARF::GetDIEFromUID (lldb::user_id_t uid)
+{
+ // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
+ // we must make sure we use the correct DWARF file when resolving things.
+ // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
+ // SymbolFileDWARF classes, one for each .o file. We can often end up
+ // with references to other DWARF objects and we must be ready to receive
+ // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
+ // instance.
+ SymbolFileDWARF *dwarf = GetDWARFForUID(uid);
+ if (dwarf)
+ return dwarf->GetDIE(DIERef(uid, dwarf));
+ return DWARFDIE();
+}
+
CompilerDecl
SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid)
{
- if (UserIDMatches(type_uid))
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
- if (die)
- {
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->GetDeclForUIDFromDWARF(die);
- }
- }
- }
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE die = GetDIEFromUID(type_uid);
+ if (die)
+ return die.GetDecl();
return CompilerDecl();
}
CompilerDeclContext
SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid)
{
- if (UserIDMatches(type_uid))
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
- if (die)
- {
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
- }
- }
- }
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE die = GetDIEFromUID(type_uid);
+ if (die)
+ return die.GetDeclContext();
return CompilerDeclContext();
}
CompilerDeclContext
SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid)
{
- if (UserIDMatches(type_uid))
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
- if (die)
- {
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
- }
- }
- }
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE die = GetDIEFromUID(type_uid);
+ if (die)
+ return die.GetContainingDeclContext();
return CompilerDeclContext();
}
@@ -1503,20 +1537,20 @@ SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid)
Type*
SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
{
- if (UserIDMatches(type_uid))
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- DWARFDIE type_die = debug_info->GetDIE (DIERef(type_uid));
- if (type_die)
- {
- const bool assert_not_being_parsed = true;
- return ResolveTypeUID (type_die, assert_not_being_parsed);
- }
- }
- }
- return NULL;
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE type_die = GetDIEFromUID(type_uid);
+ if (type_die)
+ return type_die.ResolveType();
+ else
+ return nullptr;
+}
+
+Type*
+SymbolFileDWARF::ResolveTypeUID (const DIERef &die_ref)
+{
+ return ResolveType (GetDIE(die_ref), true);
}
Type*
@@ -1573,35 +1607,36 @@ SymbolFileDWARF::ResolveTypeUID (const DWARFDIE &die, bool assert_not_being_pars
bool
SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type)
{
- CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
+ CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type);
if (GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType()))
{
return true;
}
TypeSystem *type_system = compiler_type.GetTypeSystem();
- if (type_system)
- {
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->CanCompleteType(compiler_type);
- }
- return false;
+
+ ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ if (!clang_type_system)
+ return false;
+ DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
+ return ast_parser->GetClangASTImporter().CanImport(compiler_type);
}
bool
SymbolFileDWARF::CompleteType (CompilerType &compiler_type)
{
- TypeSystem *type_system = compiler_type.GetTypeSystem();
- if (type_system)
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFile()->GetModule()->GetMutex());
+
+ ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem());
+ if (clang_type_system)
{
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
- if (dwarf_ast && dwarf_ast->CanCompleteType(compiler_type))
- return dwarf_ast->CompleteType(compiler_type);
+ DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
+ if (ast_parser && ast_parser->GetClangASTImporter().CanImport(compiler_type))
+ return ast_parser->GetClangASTImporter().CompleteType(compiler_type);
}
// We have a struct/union/class/enum that needs to be fully resolved.
- CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
+ CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type);
auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType());
if (die_it == GetForwardDeclClangTypeToDie().end())
{
@@ -1609,30 +1644,29 @@ SymbolFileDWARF::CompleteType (CompilerType &compiler_type)
return true;
}
- DWARFDebugInfo* debug_info = DebugInfo();
- DWARFDIE dwarf_die = debug_info->GetDIE(die_it->getSecond());
-
- assert(UserIDMatches(die_it->getSecond().GetUID()) && "CompleteType called on the wrong SymbolFile");
-
- // Once we start resolving this type, remove it from the forward declaration
- // map in case anyone child members or other types require this type to get resolved.
- // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
- // are done.
- GetForwardDeclClangTypeToDie().erase (die_it);
+ DWARFDIE dwarf_die = GetDIE(die_it->getSecond());
+ if (dwarf_die)
+ {
+ // Once we start resolving this type, remove it from the forward declaration
+ // map in case anyone child members or other types require this type to get resolved.
+ // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
+ // are done.
+ GetForwardDeclClangTypeToDie().erase (die_it);
- Type *type = GetDIEToType().lookup (dwarf_die.GetDIE());
+ Type *type = GetDIEToType().lookup (dwarf_die.GetDIE());
- Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
- if (log)
- GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
- "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
- dwarf_die.GetID(),
- dwarf_die.GetTagAsCString(),
- type->GetName().AsCString());
- assert (compiler_type);
- DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, compiler_type);
+ Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
+ if (log)
+ GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
+ "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
+ dwarf_die.GetID(),
+ dwarf_die.GetTagAsCString(),
+ type->GetName().AsCString());
+ assert (compiler_type);
+ DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, compiler_type);
+ }
return false;
}
@@ -1641,10 +1675,7 @@ SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed,
{
if (die)
{
- Type *type = GetDIEToType().lookup (die.GetDIE());
-
- if (type == NULL)
- type = GetTypeForDIE (die, resolve_function_context).get();
+ Type *type = GetTypeForDIE (die, resolve_function_context).get();
if (assert_not_being_parsed)
{
@@ -1730,6 +1761,55 @@ SymbolFileDWARF::GetDWOModule (ConstString name)
return lldb::ModuleSP();
}
+DWARFDIE
+SymbolFileDWARF::GetDIE (const DIERef &die_ref)
+{
+ DWARFDebugInfo * debug_info = DebugInfo();
+ if (debug_info)
+ return debug_info->GetDIE(die_ref);
+ else
+ return DWARFDIE();
+}
+
+
+std::unique_ptr<SymbolFileDWARFDwo>
+SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die)
+{
+ // If we are using a dSYM file, we never want the standard DWO files since
+ // the -gmodule support uses the same DWO machanism to specify full debug
+ // info files for modules.
+ if (GetDebugMapSymfile())
+ return nullptr;
+
+ const char *dwo_name = cu_die.GetAttributeValueAsString(this, &dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
+ if (!dwo_name)
+ return nullptr;
+
+ FileSpec dwo_file(dwo_name, true);
+ if (dwo_file.IsRelative())
+ {
+ const char *comp_dir = cu_die.GetAttributeValueAsString(this, &dwarf_cu, DW_AT_comp_dir, nullptr);
+ if (!comp_dir)
+ return nullptr;
+
+ dwo_file.SetFile(comp_dir, true);
+ dwo_file.AppendPathComponent(dwo_name);
+ }
+
+ if (!dwo_file.Exists())
+ return nullptr;
+
+ const lldb::offset_t file_offset = 0;
+ DataBufferSP dwo_file_data_sp;
+ lldb::offset_t dwo_file_data_offset = 0;
+ ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(GetObjectFile()->GetModule(), &dwo_file, file_offset,
+ dwo_file.GetByteSize(), dwo_file_data_sp, dwo_file_data_offset);
+ if (dwo_obj_file == nullptr)
+ return nullptr;
+
+ return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, &dwarf_cu);
+}
+
void
SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
{
@@ -1760,9 +1840,25 @@ SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
{
ModuleSpec dwo_module_spec;
dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
+ if (dwo_module_spec.GetFileSpec().IsRelative())
+ {
+ const char *comp_dir = die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr);
+ if (comp_dir)
+ {
+ dwo_module_spec.GetFileSpec().SetFile(comp_dir, true);
+ dwo_module_spec.GetFileSpec().AppendPathComponent(dwo_path);
+ }
+ }
dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
//printf ("Loading dwo = '%s'\n", dwo_path);
Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
+ if (!module_sp)
+ {
+ GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: unable to locate module needed for external types: %s\nerror: %s\nDebugging will be degraded due to missing types. Rebuilding your project will regenerate the needed module files.",
+ die.GetOffset(),
+ dwo_module_spec.GetFileSpec().GetPath().c_str(),
+ error.AsCString("unknown error"));
+ }
}
m_external_type_modules[const_name] = module_sp;
}
@@ -1799,7 +1895,7 @@ SymbolFileDWARF::GetGlobalAranges()
const DWARFExpression &location = var_sp->LocationExpression();
Value location_result;
Error error;
- if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
+ if (location.Evaluate(nullptr, nullptr, nullptr, LLDB_INVALID_ADDRESS, nullptr, nullptr, location_result, &error))
{
if (location_result.GetValueType() == Value::eValueTypeFileAddress)
{
@@ -2094,6 +2190,9 @@ SymbolFileDWARF::Index ()
if (debug_info)
{
const uint32_t num_compile_units = GetNumCompileUnits();
+ if (num_compile_units == 0)
+ return;
+
std::vector<NameToDIE> function_basename_index(num_compile_units);
std::vector<NameToDIE> function_fullname_index(num_compile_units);
std::vector<NameToDIE> function_method_index(num_compile_units);
@@ -2102,7 +2201,8 @@ SymbolFileDWARF::Index ()
std::vector<NameToDIE> global_index(num_compile_units);
std::vector<NameToDIE> type_index(num_compile_units);
std::vector<NameToDIE> namespace_index(num_compile_units);
-
+
+ std::vector<bool> clear_cu_dies(num_compile_units, false);
auto parser_fn = [this,
debug_info,
&function_basename_index,
@@ -2115,25 +2215,62 @@ SymbolFileDWARF::Index ()
&namespace_index](uint32_t cu_idx)
{
DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded(false) > 1;
-
- dwarf_cu->Index(function_basename_index[cu_idx],
- function_fullname_index[cu_idx],
- function_method_index[cu_idx],
- function_selector_index[cu_idx],
- objc_class_selectors_index[cu_idx],
- global_index[cu_idx],
- type_index[cu_idx],
- namespace_index[cu_idx]);
-
- // Keep memory down by clearing DIEs if this generate function
- // caused them to be parsed
- if (clear_dies)
- dwarf_cu->ClearDIEs(true);
-
+ if (dwarf_cu)
+ {
+ dwarf_cu->Index(function_basename_index[cu_idx],
+ function_fullname_index[cu_idx],
+ function_method_index[cu_idx],
+ function_selector_index[cu_idx],
+ objc_class_selectors_index[cu_idx],
+ global_index[cu_idx],
+ type_index[cu_idx],
+ namespace_index[cu_idx]);
+ }
return cu_idx;
};
+ auto extract_fn = [this,
+ debug_info,
+ num_compile_units](uint32_t cu_idx)
+ {
+ DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu)
+ {
+ // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the
+ // DIEs for a compile unit have already been parsed.
+ return std::make_pair(cu_idx, dwarf_cu->ExtractDIEsIfNeeded(false) > 1);
+ }
+ return std::make_pair(cu_idx, false);
+ };
+
+ // Create a task runner that extracts dies for each DWARF compile unit in a separate thread
+ TaskRunner<std::pair<uint32_t, bool>> task_runner_extract;
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ task_runner_extract.AddTask(extract_fn, cu_idx);
+
+ //----------------------------------------------------------------------
+ // First figure out which compile units didn't have their DIEs already
+ // parsed and remember this. If no DIEs were parsed prior to this index
+ // function call, we are going to want to clear the CU dies after we
+ // are done indexing to make sure we don't pull in all DWARF dies, but
+ // we need to wait until all compile units have been indexed in case
+ // a DIE in one compile unit refers to another and the indexes accesses
+ // those DIEs.
+ //----------------------------------------------------------------------
+ while (true)
+ {
+ auto f = task_runner_extract.WaitForNextCompletedTask();
+ if (!f.valid())
+ break;
+ unsigned cu_idx;
+ bool clear;
+ std::tie(cu_idx, clear) = f.get();
+ clear_cu_dies[cu_idx] = clear;
+ }
+
+ // Now create a task runner that can index each DWARF compile unit in a separate
+ // thread so we can index quickly.
+
TaskRunner<uint32_t> task_runner;
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
task_runner.AddTask(parser_fn, cu_idx);
@@ -2165,6 +2302,16 @@ SymbolFileDWARF::Index ()
[&]() { m_type_index.Finalize(); },
[&]() { m_namespace_index.Finalize(); });
+ //----------------------------------------------------------------------
+ // Keep memory down by clearing DIEs for any compile units if indexing
+ // caused us to load the compile unit's DIEs.
+ //----------------------------------------------------------------------
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ {
+ if (clear_cu_dies[cu_idx])
+ debug_info->GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true);
+ }
+
#if defined (ENABLE_DEBUG_PRINTF)
StreamFile s(stdout, false);
s.Printf ("DWARF index for '%s':",
@@ -2265,12 +2412,11 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDec
sc.module_sp = m_obj_file->GetModule();
assert (sc.module_sp);
- DWARFDebugInfo* debug_info = DebugInfo();
bool done = false;
for (size_t i=0; i<num_die_matches && !done; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = debug_info->GetDIE (die_ref);
+ DWARFDIE die = GetDIE (die_ref);
if (die)
{
@@ -2383,11 +2529,10 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append
const size_t num_matches = die_offsets.size();
if (num_matches)
{
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = debug_info->GetDIE (die_ref);
+ DWARFDIE die = GetDIE (die_ref);
if (die)
{
@@ -2971,9 +3116,20 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
const 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();
+
+ // Make sure we haven't already searched this SymbolFile before...
+ if (searched_symbol_files.count(this))
+ return 0;
+ else
+ searched_symbol_files.insert(this);
+
DWARFDebugInfo* info = DebugInfo();
if (info == NULL)
return 0;
@@ -2996,10 +3152,6 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
max_matches);
}
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- types.Clear();
-
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
return 0;
@@ -3026,11 +3178,10 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
if (num_die_matches)
{
const uint32_t initial_types_size = types.GetSize();
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_die_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = debug_info->GetDIE (die_ref);
+ DWARFDIE die = GetDIE (die_ref);
if (die)
{
@@ -3097,6 +3248,7 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
parent_decl_ctx,
append,
max_matches,
+ searched_symbol_files,
types);
if (num_external_matches)
return num_external_matches;
@@ -3124,6 +3276,9 @@ SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context,
ConstString name = context.back().name;
+ if (!name)
+ return 0;
+
if (m_using_apple_tables)
{
if (m_apple_types_ap.get())
@@ -3145,11 +3300,10 @@ SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context,
if (num_die_matches)
{
size_t num_matches = 0;
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_die_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = debug_info->GetDIE (die_ref);
+ DWARFDIE die = GetDIE (die_ref);
if (die)
{
@@ -3228,11 +3382,10 @@ SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
const size_t num_matches = die_offsets.size();
if (num_matches)
{
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = debug_info->GetDIE (die_ref);
+ DWARFDIE die = GetDIE (die_ref);
if (die)
{
@@ -3447,11 +3600,10 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
if (num_matches)
{
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE type_die = debug_info->GetDIE (die_ref);
+ DWARFDIE type_die = GetDIE (die_ref);
if (type_die)
{
@@ -3667,18 +3819,26 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &
}
const size_t num_matches = die_offsets.size();
-
-
+
+ // Get the type system that we are looking to find a type for. We will 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);
+
if (num_matches)
{
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE type_die = debug_info->GetDIE (die_ref);
+ DWARFDIE type_die = GetDIE (die_ref);
if (type_die)
{
+ // Make sure type_die's langauge matches the type system we are looking for.
+ // We don't want to find a "Foo" type from Java if we are looking for a "Foo"
+ // type for C, C++, ObjC, or ObjC++.
+ if (type_system && !type_system->SupportsLanguage(type_die.GetLanguage()))
+ continue;
bool try_resolving_type = false;
// Don't try and resolve the DIE we are looking for with the DIE itself!
@@ -3919,7 +4079,7 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
if (sc.function)
{
- DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID()));
+ DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID(), this));
const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress (DW_AT_low_pc, LLDB_INVALID_ADDRESS);
if (func_lo_pc != LLDB_INVALID_ADDRESS)
@@ -3974,11 +4134,10 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
const size_t num_matches = die_offsets.size();
if (num_matches)
{
- DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = debug_info->GetDIE (die_ref);
+ DWARFDIE die = GetDIE (die_ref);
if (die)
{
VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
@@ -4047,6 +4206,7 @@ SymbolFileDWARF::ParseVariableDIE
bool location_is_const_value_data = false;
bool has_explicit_location = false;
DWARFFormValue const_value;
+ Variable::RangeList scope_ranges;
//AccessType accessibility = eAccessNone;
for (i=0; i<num_attributes; ++i)
@@ -4156,19 +4316,47 @@ SymbolFileDWARF::ParseVariableDIE
}
break;
case DW_AT_specification:
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- spec_die = debug_info->GetDIE(DIERef(form_value));
+ spec_die = GetDIE(DIERef(form_value));
+ break;
+ case DW_AT_start_scope:
+ {
+ if (form_value.Form() == DW_FORM_sec_offset)
+ {
+ DWARFRangeList dwarf_scope_ranges;
+ const DWARFDebugRanges* debug_ranges = DebugRanges();
+ debug_ranges->FindRanges(form_value.Unsigned(), dwarf_scope_ranges);
+
+ // All DW_AT_start_scope are relative to the base address of the
+ // compile unit. We add the compile unit base address to make
+ // sure all the addresses are properly fixed up.
+ for (size_t i = 0, count = dwarf_scope_ranges.GetSize(); i < count; ++i)
+ {
+ const DWARFRangeList::Entry& range = dwarf_scope_ranges.GetEntryRef(i);
+ scope_ranges.Append(range.GetRangeBase() + die.GetCU()->GetBaseAddress(),
+ range.GetByteSize());
+ }
+ }
+ else
+ {
+ // TODO: Handle the case when DW_AT_start_scope have form constant. The
+ // dwarf spec is a bit ambiguous about what is the expected behavior in
+ // case the enclosing block have a non coninious address range and the
+ // DW_AT_start_scope entry have a form constant.
+ GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_start_scope has unsupported form type (0x%x)\n",
+ die.GetID(),
+ form_value.Form());
+ }
+
+ scope_ranges.Sort();
+ scope_ranges.CombineConsecutiveRanges();
+ }
break;
- }
case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
case DW_AT_declaration:
case DW_AT_description:
case DW_AT_endianity:
case DW_AT_segment:
- case DW_AT_start_scope:
case DW_AT_visibility:
default:
case DW_AT_abstract_origin:
@@ -4232,6 +4420,7 @@ SymbolFileDWARF::ParseVariableDIE
GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die.GetOffset(), die.GetTagAsCString(), strm.GetString().c_str());
}
}
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
{
@@ -4240,9 +4429,6 @@ SymbolFileDWARF::ParseVariableDIE
else
scope = eValueTypeVariableStatic;
-
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
-
if (debug_map_symfile)
{
// When leaving the DWARF in the .o files on darwin,
@@ -4320,7 +4506,22 @@ SymbolFileDWARF::ParseVariableDIE
if (location_is_const_value_data)
scope = eValueTypeVariableStatic;
else
+ {
scope = eValueTypeVariableLocal;
+ if (debug_map_symfile)
+ {
+ // We need to check for TLS addresses that we need to fixup
+ if (location.ContainsThreadLocalStorage())
+ {
+ location.LinkThreadLocalStorage(
+ debug_map_symfile->GetObjectFile()->GetModule(),
+ [this, debug_map_symfile](lldb::addr_t unlinked_file_addr) -> lldb::addr_t {
+ return debug_map_symfile->LinkOSOFileAddress(this, unlinked_file_addr);
+ });
+ scope = eValueTypeVariableThreadLocal;
+ }
+ }
+ }
}
}
@@ -4347,20 +4548,21 @@ SymbolFileDWARF::ParseVariableDIE
if (symbol_context_scope)
{
- SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID()));
-
+ SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID(this)));
+
if (const_value.Form() && type_sp && type_sp->GetType())
location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize());
-
+
var_sp.reset (new Variable (die.GetID(),
- name,
+ name,
mangled,
type_sp,
- scope,
- symbol_context_scope,
- &decl,
- location,
- is_external,
+ scope,
+ symbol_context_scope,
+ scope_ranges,
+ &decl,
+ location,
+ is_external,
is_artificial,
is_static_member));
@@ -4505,7 +4707,7 @@ SymbolFileDWARF::ParseVariables (const SymbolContext& sc,
// a concrete block counterpart in the current function. We need
// to find the concrete block so we can correctly add the
// variable to it
- const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID()),
+ const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID(), this),
sc_parent_die.GetOffset());
if (concrete_block_die)
block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID());
@@ -4596,7 +4798,7 @@ SymbolFileDWARF::DumpIndexes ()
SymbolFileDWARFDebugMap *
-SymbolFileDWARF::GetDebugMapSymfile ()
+SymbolFileDWARF::GetDebugMapSymfile()
{
if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired())
{
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index be097595346e..865e58962700 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -58,6 +58,7 @@ class DWARFDeclContext;
class DWARFDIECollection;
class DWARFFormValue;
class SymbolFileDWARFDebugMap;
+class SymbolFileDWARFDwo;
#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
@@ -67,9 +68,12 @@ public:
friend class SymbolFileDWARFDebugMap;
friend class SymbolFileDWARFDwo;
friend class DebugMapModule;
+ friend struct DIERef;
friend class DWARFCompileUnit;
+ friend class DWARFDIE;
friend class DWARFASTParserClang;
friend class DWARFASTParserGo;
+ friend class DWARFASTParserJava;
//------------------------------------------------------------------
// Static Functions
@@ -133,8 +137,11 @@ public:
lldb_private::FileSpecList& support_files) override;
bool
- ParseImportedModules (const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) override;
+ ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override;
+
+ bool
+ ParseImportedModules(const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) override;
size_t
ParseFunctionBlocks (const lldb_private::SymbolContext& sc) override;
@@ -156,6 +163,12 @@ public:
bool assert_not_being_parsed = true,
bool resolve_function_context = false);
+ SymbolFileDWARF *
+ GetDWARFForUID (lldb::user_id_t uid);
+
+ DWARFDIE
+ GetDIEFromUID (lldb::user_id_t uid);
+
lldb_private::CompilerDecl
GetDeclForUID (lldb::user_id_t uid) override;
@@ -218,6 +231,7 @@ public:
const lldb_private::CompilerDeclContext *parent_decl_ctx,
bool append,
uint32_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap& types) override;
size_t
@@ -299,12 +313,6 @@ public:
GetCompUnitForDWARFCompUnit(DWARFCompileUnit* dwarf_cu,
uint32_t cu_idx = UINT32_MAX);
- lldb::user_id_t
- MakeUserID (dw_offset_t die_offset) const
- {
- return GetID() | die_offset;
- }
-
size_t
GetObjCMethodDIEOffsets (lldb_private::ConstString class_name,
DIEArray &method_die_offsets);
@@ -327,6 +335,12 @@ public:
lldb::ModuleSP
GetDWOModule (lldb_private::ConstString name);
+ virtual DWARFDIE
+ GetDIE(const DIERef &die_ref);
+
+ virtual std::unique_ptr<SymbolFileDWARFDwo>
+ GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die);
+
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> DIEToVariableSP;
@@ -387,8 +401,10 @@ protected:
bool *type_is_new);
lldb_private::Type *
- ResolveTypeUID (const DWARFDIE &die,
- bool assert_not_being_parsed);
+ ResolveTypeUID(const DWARFDIE &die, bool assert_not_being_parsed);
+
+ lldb_private::Type *
+ ResolveTypeUID(const DIERef &die_ref);
lldb::VariableSP
ParseVariableDIE(const lldb_private::SymbolContext& sc,
@@ -483,15 +499,6 @@ protected:
GetUniqueDWARFASTTypeMap ();
bool
- UserIDMatches (lldb::user_id_t uid) const
- {
- const lldb::user_id_t high_uid = uid & 0xffffffff00000000ull;
- if (high_uid != 0 && GetID() != 0)
- return high_uid == GetID();
- return true;
- }
-
- bool
DIEDeclContextsMatch (const DWARFDIE &die1,
const DWARFDIE &die2);
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index be25dfc99dee..ca819624c715 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -123,8 +123,9 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa
// Add the inverse OSO file address to debug map entry mapping
exe_symfile->AddOSOFileRange (this,
exe_symbol->GetAddressRef().GetFileAddress(),
+ exe_symbol->GetByteSize(),
oso_fun_symbol->GetAddressRef().GetFileAddress(),
- std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize()));
+ oso_fun_symbol->GetByteSize());
}
}
@@ -157,8 +158,9 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa
// Add the inverse OSO file address to debug map entry mapping
exe_symfile->AddOSOFileRange (this,
exe_symbol->GetAddressRef().GetFileAddress(),
+ exe_symbol->GetByteSize(),
oso_gsym_symbol->GetAddressRef().GetFileAddress(),
- std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize()));
+ oso_gsym_symbol->GetByteSize());
}
}
break;
@@ -206,7 +208,7 @@ public:
ObjectFile *oso_objfile = GetObjectFile ();
if (oso_objfile)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
if (symbol_vendor)
{
@@ -635,13 +637,9 @@ SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
// zero in each .o file since each .o file can only have
// one compile unit for now.
lldb::user_id_t cu_id = 0;
- m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
- NULL,
- so_file_spec,
- cu_id,
- eLanguageTypeUnknown,
- false));
-
+ m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit(
+ m_obj_file->GetModule(), NULL, 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
@@ -725,7 +723,16 @@ SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc,
}
bool
-SymbolFileDWARFDebugMap::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules)
+SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc)
+{
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitIsOptimized(sc);
+ return false;
+}
+
+bool
+SymbolFileDWARFDebugMap::ParseImportedModules(const SymbolContext &sc, std::vector<ConstString> &imported_modules)
{
SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
if (oso_dwarf)
@@ -1276,7 +1283,8 @@ SymbolFileDWARFDebugMap::FindTypes
const 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
)
{
@@ -1290,13 +1298,16 @@ SymbolFileDWARFDebugMap::FindTypes
{
oso_dwarf = GetSymbolFile (sc);
if (oso_dwarf)
- return oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, types);
+ return oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
}
else
{
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, types);
- return false;
+ oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
+ if (types.GetSize() >= max_matches)
+ return true;
+ else
+ return false;
});
}
@@ -1452,6 +1463,7 @@ SymbolFileDWARFDebugMap::ParseDeclsForContext (lldb_private::CompilerDeclContext
bool
SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
lldb::addr_t exe_file_addr,
+ lldb::addr_t exe_byte_size,
lldb::addr_t oso_file_addr,
lldb::addr_t oso_byte_size)
{
@@ -1460,7 +1472,14 @@ SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
{
DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
- cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr));
+ addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
+ if (range_size == 0)
+ {
+ range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
+ if (range_size == 0)
+ range_size = 1;
+ }
+ cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
return true;
}
return false;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index 1eb33c927bdf..fcf02975a58f 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -65,6 +65,8 @@ public:
bool ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc) override;
bool ParseCompileUnitDebugMacros (const lldb_private::SymbolContext& sc) override;
bool ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files) override;
+ bool
+ ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override;
bool ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules) override;
size_t ParseFunctionBlocks (const lldb_private::SymbolContext& sc) override;
size_t ParseTypes (const lldb_private::SymbolContext& sc) override;
@@ -82,7 +84,7 @@ public:
uint32_t FindGlobalVariables (const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override;
uint32_t FindFunctions (const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t 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 FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, lldb_private::TypeMap& types) override;
+ uint32_t FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap& types) override;
lldb_private::CompilerDeclContext
FindNamespace (const lldb_private::SymbolContext& sc,
const lldb_private::ConstString &name,
@@ -107,10 +109,11 @@ protected:
kNumFlags
};
- friend class DWARFCompileUnit;
- friend class SymbolFileDWARF;
friend class DebugMapModule;
+ friend struct DIERef;
friend class DWARFASTParserClang;
+ friend class DWARFCompileUnit;
+ friend class SymbolFileDWARF;
struct OSOInfo
{
lldb::ModuleSP module_sp;
@@ -348,6 +351,7 @@ protected:
bool
AddOSOFileRange (CompileUnitInfo *cu_info,
lldb::addr_t exe_file_addr,
+ lldb::addr_t exe_byte_size,
lldb::addr_t oso_file_addr,
lldb::addr_t oso_byte_size);
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index 326c397c83d5..14603aa460c9 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -12,6 +12,7 @@
#include "lldb/Core/Section.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugInfo.h"
@@ -129,3 +130,10 @@ SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language)
{
return GetBaseSymbolFile()->GetTypeSystemForLanguage(language);
}
+
+DWARFDIE
+SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref)
+{
+ lldbassert(m_base_dwarf_cu->GetOffset() == die_ref.cu_offset);
+ return DebugInfo()->GetDIEForDIEOffset(die_ref.die_offset);
+}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 39ed6502229b..9391a2824948 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -38,6 +38,15 @@ public:
lldb_private::TypeSystem*
GetTypeSystemForLanguage(lldb::LanguageType language) override;
+ DWARFDIE
+ GetDIE(const DIERef &die_ref) override;
+
+ std::unique_ptr<SymbolFileDWARFDwo>
+ GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) override
+ {
+ return nullptr;
+ }
+
protected:
void
LoadSectionData (lldb::SectionType sect_type, lldb_private::DWARFDataExtractor& data) override;
diff --git a/source/Plugins/SymbolFile/PDB/CMakeLists.txt b/source/Plugins/SymbolFile/PDB/CMakeLists.txt
new file mode 100644
index 000000000000..79d8a25d6979
--- /dev/null
+++ b/source/Plugins/SymbolFile/PDB/CMakeLists.txt
@@ -0,0 +1,7 @@
+set(LLVM_PRIVATE_LINK_COMPONENTS
+ DebugInfoPDB)
+
+add_lldb_library(lldbPluginSymbolFilePDB
+ PDBASTParser.cpp
+ SymbolFilePDB.cpp
+ )
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
new file mode 100644
index 000000000000..1e8e040fd47c
--- /dev/null
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -0,0 +1,237 @@
+//===-- PDBASTParser.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PDBASTParser.h"
+
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
+#include "lldb/Symbol/Declaration.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/TypeSystem.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+using namespace llvm::pdb;
+
+namespace
+{
+int
+TranslateUdtKind(PDB_UdtType pdb_kind)
+{
+ switch (pdb_kind)
+ {
+ case PDB_UdtType::Class:
+ return clang::TTK_Class;
+ case PDB_UdtType::Struct:
+ return clang::TTK_Struct;
+ case PDB_UdtType::Union:
+ return clang::TTK_Union;
+ case PDB_UdtType::Interface:
+ return clang::TTK_Interface;
+ }
+ return clang::TTK_Class;
+}
+
+lldb::Encoding
+TranslateBuiltinEncoding(PDB_BuiltinType type)
+{
+ switch (type)
+ {
+ case PDB_BuiltinType::Float:
+ return lldb::eEncodingIEEE754;
+ case PDB_BuiltinType::Int:
+ case PDB_BuiltinType::Long:
+ case PDB_BuiltinType::Char:
+ return lldb::eEncodingSint;
+ case PDB_BuiltinType::Bool:
+ case PDB_BuiltinType::UInt:
+ case PDB_BuiltinType::ULong:
+ case PDB_BuiltinType::HResult:
+ return lldb::eEncodingUint;
+ default:
+ return lldb::eEncodingInvalid;
+ }
+}
+}
+
+PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast)
+{
+}
+
+PDBASTParser::~PDBASTParser()
+{
+}
+
+// DebugInfoASTParser interface
+
+lldb::TypeSP
+PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type)
+{
+ // PDB doesn't maintain enough information to robustly rebuild the entire
+ // tree, and this is most problematic when it comes to figure out the
+ // right DeclContext to put a type in. So for now, everything goes in
+ // the translation unit decl as a fully qualified type.
+ clang::DeclContext *tu_decl_ctx = m_ast.GetTranslationUnitDecl();
+ Declaration decl;
+
+ if (auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type))
+ {
+ AccessType access = lldb::eAccessPublic;
+ PDB_UdtType udt_kind = udt->getUdtKind();
+
+ if (udt_kind == PDB_UdtType::Class)
+ access = lldb::eAccessPrivate;
+
+ CompilerType clang_type =
+ m_ast.CreateRecordType(tu_decl_ctx, access, udt->getName().c_str(), TranslateUdtKind(udt_kind),
+ lldb::eLanguageTypeC_plus_plus, nullptr);
+
+ m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
+
+ return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(udt->getName()),
+ udt->getLength(), nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
+ clang_type, Type::eResolveStateForward);
+ }
+ else if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type))
+ {
+ std::string name = enum_type->getName();
+ lldb::Encoding encoding = TranslateBuiltinEncoding(enum_type->getBuiltinType());
+ uint64_t bytes = enum_type->getLength();
+ CompilerType builtin_type = m_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, bytes * 8);
+
+ CompilerType ast_enum = m_ast.CreateEnumerationType(name.c_str(), tu_decl_ctx, decl, builtin_type);
+ auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
+ while (auto enum_value = enum_values->getNext())
+ {
+ if (enum_value->getDataKind() != PDB_DataKind::Constant)
+ continue;
+ AddEnumValue(ast_enum, *enum_value);
+ }
+
+ return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ast_enum, Type::eResolveStateFull);
+ }
+ else if (auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type))
+ {
+ Type *target_type = m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
+ std::string name = type_def->getName();
+ uint64_t bytes = type_def->getLength();
+ if (!target_type)
+ return nullptr;
+ CompilerType target_ast_type = target_type->GetFullCompilerType();
+ CompilerDeclContext target_decl_ctx = m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID());
+ CompilerType ast_typedef = m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx);
+ return std::make_shared<Type>(type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes,
+ nullptr, target_type->GetID(), Type::eEncodingIsTypedefUID, decl, ast_typedef,
+ Type::eResolveStateFull);
+ }
+ else if (auto func_sig = llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type))
+ {
+ auto arg_enum = func_sig->getArguments();
+ uint32_t num_args = arg_enum->getChildCount();
+ std::vector<CompilerType> arg_list(num_args);
+ while (auto arg = arg_enum->getNext())
+ {
+ Type *arg_type = m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId());
+ // If there's some error looking up one of the dependent types of this function signature, bail.
+ if (!arg_type)
+ return nullptr;
+ CompilerType arg_ast_type = arg_type->GetFullCompilerType();
+ arg_list.push_back(arg_ast_type);
+ }
+ auto pdb_return_type = func_sig->getReturnType();
+ Type *return_type = m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId());
+ // If there's some error looking up one of the dependent types of this function signature, bail.
+ if (!return_type)
+ return nullptr;
+ CompilerType return_ast_type = return_type->GetFullCompilerType();
+ uint32_t type_quals = 0;
+ if (func_sig->isConstType())
+ type_quals |= clang::Qualifiers::Const;
+ if (func_sig->isVolatileType())
+ type_quals |= clang::Qualifiers::Volatile;
+ CompilerType func_sig_ast_type =
+ m_ast.CreateFunctionType(return_ast_type, &arg_list[0], num_args, false, type_quals);
+
+ return std::make_shared<Type>(func_sig->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), 0, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_sig_ast_type,
+ Type::eResolveStateFull);
+ }
+ else if (auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type))
+ {
+ uint32_t num_elements = array_type->getCount();
+ uint32_t element_uid = array_type->getElementType()->getSymIndexId();
+ uint32_t bytes = array_type->getLength();
+
+ Type *element_type = m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
+ CompilerType element_ast_type = element_type->GetFullCompilerType();
+ CompilerType array_ast_type = m_ast.CreateArrayType(element_ast_type, num_elements, false);
+ return std::make_shared<Type>(array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), bytes, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, decl, array_ast_type,
+ Type::eResolveStateFull);
+ }
+ return nullptr;
+}
+
+bool
+PDBASTParser::AddEnumValue(CompilerType enum_type, const PDBSymbolData &enum_value) const
+{
+ Declaration decl;
+ Variant v = enum_value.getValue();
+ std::string name = enum_value.getName();
+ int64_t raw_value;
+ switch (v.Type)
+ {
+ case PDB_VariantType::Int8:
+ raw_value = v.Value.Int8;
+ break;
+ case PDB_VariantType::Int16:
+ raw_value = v.Value.Int16;
+ break;
+ case PDB_VariantType::Int32:
+ raw_value = v.Value.Int32;
+ break;
+ case PDB_VariantType::Int64:
+ raw_value = v.Value.Int64;
+ break;
+ case PDB_VariantType::UInt8:
+ raw_value = v.Value.UInt8;
+ break;
+ case PDB_VariantType::UInt16:
+ raw_value = v.Value.UInt16;
+ break;
+ case PDB_VariantType::UInt32:
+ raw_value = v.Value.UInt32;
+ break;
+ case PDB_VariantType::UInt64:
+ raw_value = v.Value.UInt64;
+ break;
+ default:
+ return false;
+ }
+ CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType());
+ uint32_t byte_size = m_ast.getASTContext()->getTypeSize(ClangUtil::GetQualType(underlying_type));
+ return m_ast.AddEnumerationValueToEnumerationType(enum_type.GetOpaqueQualType(), underlying_type, decl,
+ name.c_str(), raw_value, byte_size * 8);
+}
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.h b/source/Plugins/SymbolFile/PDB/PDBASTParser.h
new file mode 100644
index 000000000000..ca425c17c451
--- /dev/null
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.h
@@ -0,0 +1,58 @@
+//===-- PDBASTParser.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H
+#define LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H
+
+#include "lldb/lldb-forward.h"
+
+#include "lldb/Symbol/ClangASTImporter.h"
+
+namespace clang
+{
+class CharUnits;
+class CXXRecordDecl;
+class FieldDecl;
+class RecordDecl;
+}
+
+namespace lldb_private
+{
+class ClangASTContext;
+class CompilerType;
+}
+
+namespace llvm
+{
+namespace pdb
+{
+class PDBSymbol;
+class PDBSymbolData;
+class PDBSymbolTypeBuiltin;
+}
+}
+
+class PDBASTParser
+{
+public:
+ PDBASTParser(lldb_private::ClangASTContext &ast);
+ ~PDBASTParser();
+
+ lldb::TypeSP
+ CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type);
+
+private:
+ bool
+ AddEnumValue(lldb_private::CompilerType enum_type, const llvm::pdb::PDBSymbolData &data) const;
+
+ lldb_private::ClangASTContext &m_ast;
+ lldb_private::ClangASTImporter m_ast_importer;
+};
+
+#endif // SymbolFileDWARF_DWARFASTParserClang_h_
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
new file mode 100644
index 000000000000..d8092c011acb
--- /dev/null
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -0,0 +1,733 @@
+//===-- SymbolFilePDB.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFilePDB.h"
+
+#include "clang/Lex/Lexer.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/TypeMap.h"
+
+#include "llvm/DebugInfo/PDB/GenericError.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+
+#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
+
+#include <regex>
+
+using namespace lldb_private;
+using namespace llvm::pdb;
+
+namespace
+{
+lldb::LanguageType
+TranslateLanguage(PDB_Lang lang)
+{
+ switch (lang)
+ {
+ case PDB_Lang::Cpp:
+ return lldb::LanguageType::eLanguageTypeC_plus_plus;
+ case PDB_Lang::C:
+ return lldb::LanguageType::eLanguageTypeC;
+ default:
+ return lldb::LanguageType::eLanguageTypeUnknown;
+ }
+ }
+
+ bool
+ ShouldAddLine(uint32_t requested_line, uint32_t actual_line, uint32_t addr_length)
+ {
+ return ((requested_line == 0 || actual_line == requested_line) && addr_length > 0);
+ }
+}
+
+void
+SymbolFilePDB::Initialize()
+{
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
+}
+
+void
+SymbolFilePDB::Terminate()
+{
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+void
+SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger)
+{
+}
+
+lldb_private::ConstString
+SymbolFilePDB::GetPluginNameStatic()
+{
+ static ConstString g_name("pdb");
+ return g_name;
+}
+
+const char *
+SymbolFilePDB::GetPluginDescriptionStatic()
+{
+ return "Microsoft PDB debug symbol file reader.";
+}
+
+lldb_private::SymbolFile *
+SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file)
+{
+ return new SymbolFilePDB(obj_file);
+}
+
+SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
+ : SymbolFile(object_file), m_cached_compile_unit_count(0)
+{
+}
+
+SymbolFilePDB::~SymbolFilePDB()
+{
+}
+
+uint32_t
+SymbolFilePDB::CalculateAbilities()
+{
+ if (!m_session_up)
+ {
+ // Lazily load and match the PDB file, but only do this once.
+ std::string exePath = m_obj_file->GetFileSpec().GetPath();
+ auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath), m_session_up);
+ if (error)
+ {
+ llvm::consumeError(std::move(error));
+ return 0;
+ }
+ }
+ return CompileUnits | LineTables;
+}
+
+void
+SymbolFilePDB::InitializeObject()
+{
+ lldb::addr_t obj_load_address = m_obj_file->GetFileOffset();
+ m_session_up->setLoadAddress(obj_load_address);
+
+ TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(type_system, clang_type_system->GetTranslationUnitDecl());
+}
+
+uint32_t
+SymbolFilePDB::GetNumCompileUnits()
+{
+ if (m_cached_compile_unit_count == 0)
+ {
+ auto global = m_session_up->getGlobalScope();
+ auto compilands = global->findAllChildren<PDBSymbolCompiland>();
+ 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_cu = compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
+ std::string name = last_cu->getName();
+ if (name == "* Linker *")
+ --m_cached_compile_unit_count;
+ }
+ return m_cached_compile_unit_count;
+}
+
+lldb::CompUnitSP
+SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index)
+{
+ auto global = m_session_up->getGlobalScope();
+ auto compilands = global->findAllChildren<PDBSymbolCompiland>();
+ auto cu = compilands->getChildAtIndex(index);
+
+ uint32_t id = cu->getSymIndexId();
+
+ return ParseCompileUnitForSymIndex(id);
+}
+
+lldb::LanguageType
+SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc)
+{
+ // What fields should I expect to be filled out on the SymbolContext? Is it
+ // safe to assume that `sc.comp_unit` is valid?
+ if (!sc.comp_unit)
+ return lldb::eLanguageTypeUnknown;
+
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID());
+ if (!cu)
+ return lldb::eLanguageTypeUnknown;
+ auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
+ if (!details)
+ return lldb::eLanguageTypeUnknown;
+ return TranslateLanguage(details->getLanguage());
+}
+
+size_t
+SymbolFilePDB::ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc)
+{
+ // TODO: Implement this
+ return size_t();
+}
+
+bool
+SymbolFilePDB::ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc)
+{
+ return ParseCompileUnitLineTable(sc, 0);
+}
+
+bool
+SymbolFilePDB::ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc)
+{
+ // PDB doesn't contain information about macros
+ return false;
+}
+
+bool
+SymbolFilePDB::ParseCompileUnitSupportFiles(const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files)
+{
+ if (!sc.comp_unit)
+ return false;
+
+ // In theory this is unnecessary work for us, because all of this information is easily
+ // (and quickly) accessible from DebugInfoPDB, so caching it a 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.
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID());
+ if (!cu)
+ return false;
+ auto files = m_session_up->getSourceFilesForCompiland(*cu);
+ if (!files || files->getChildCount() == 0)
+ return false;
+
+ while (auto file = files->getNext())
+ {
+ FileSpec spec(file->getFileName(), false);
+ support_files.Append(spec);
+ }
+ return true;
+}
+
+bool
+SymbolFilePDB::ParseImportedModules(const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules)
+{
+ // PDB does not yet support module debug info
+ return false;
+}
+
+size_t
+SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc)
+{
+ // TODO: Implement this
+ return size_t();
+}
+
+size_t
+SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc)
+{
+ // TODO: Implement this
+ return size_t();
+}
+
+size_t
+SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc)
+{
+ // TODO: Implement this
+ return size_t();
+}
+
+lldb_private::Type *
+SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid)
+{
+ auto find_result = m_types.find(type_uid);
+ if (find_result != m_types.end())
+ return find_result->second.get();
+
+ TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ if (!clang_type_system)
+ return nullptr;
+ PDBASTParser *pdb = llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser());
+ if (!pdb)
+ return nullptr;
+
+ auto pdb_type = m_session_up->getSymbolById(type_uid);
+ if (pdb_type == nullptr)
+ return nullptr;
+
+ lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
+ m_types.insert(std::make_pair(type_uid, result));
+ return result.get();
+}
+
+bool
+SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type)
+{
+ // TODO: Implement this
+ return false;
+}
+
+lldb_private::CompilerDecl
+SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid)
+{
+ return lldb_private::CompilerDecl();
+}
+
+lldb_private::CompilerDeclContext
+SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid)
+{
+ // PDB always uses the translation unit decl context for everything. We can improve this later
+ // but it's not easy because PDB doesn't provide a high enough level of type fidelity in this area.
+ return *m_tu_decl_ctx_up;
+}
+
+lldb_private::CompilerDeclContext
+SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid)
+{
+ return *m_tu_decl_ctx_up;
+}
+
+void
+SymbolFilePDB::ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx)
+{
+}
+
+uint32_t
+SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope,
+ lldb_private::SymbolContext &sc)
+{
+ return uint32_t();
+}
+
+uint32_t
+SymbolFilePDB::ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
+ uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list)
+{
+ if (resolve_scope & lldb::eSymbolContextCompUnit)
+ {
+ // Locate all compilation units with line numbers referencing the specified file. For example, if
+ // `file_spec` is <vector>, then this should return all source files and header files that reference
+ // <vector>, either directly or indirectly.
+ auto compilands =
+ m_session_up->findCompilandsForSourceFile(file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);
+
+ // For each one, either find get its previously parsed data, or parse it afresh and add it to
+ // the symbol context list.
+ while (auto compiland = compilands->getNext())
+ {
+ // If we're not checking inlines, then don't add line information for this file unless the FileSpec
+ // matches.
+ if (!check_inlines)
+ {
+ // `getSourceFileName` returns the basename of the original source file used to generate this compiland.
+ // It does not return the full path. Currently the only way to get that is to do a basename lookup to
+ // get the IPDBSourceFile, but this is ambiguous in the case of two source files with the same name
+ // contributing to the same compiland. This is a moderately extreme edge case, so we consider this ok
+ // for now, although we need to find a long term solution.
+ std::string source_file = compiland->getSourceFileName();
+ auto pdb_file = m_session_up->findOneSourceFile(compiland.get(), source_file,
+ PDB_NameSearchFlags::NS_CaseInsensitive);
+ source_file = pdb_file->getFileName();
+ FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows);
+ if (!file_spec.FileEquals(this_spec))
+ continue;
+ }
+
+ SymbolContext sc;
+ auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId());
+ sc.comp_unit = cu.get();
+ sc.module_sp = cu->GetModule();
+ sc_list.Append(sc);
+
+ // If we were asked to resolve line entries, add all entries to the line table that match the requested
+ // line (or all lines if `line` == 0)
+ if (resolve_scope & lldb::eSymbolContextLineEntry)
+ ParseCompileUnitLineTable(sc, line);
+ }
+ }
+ return sc_list.GetSize();
+}
+
+uint32_t
+SymbolFilePDB::FindGlobalVariables(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
+ uint32_t max_matches, lldb_private::VariableList &variables)
+{
+ return uint32_t();
+}
+
+uint32_t
+SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex, bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables)
+{
+ return uint32_t();
+}
+
+uint32_t
+SymbolFilePDB::FindFunctions(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask,
+ bool include_inlines, bool append, lldb_private::SymbolContextList &sc_list)
+{
+ return uint32_t();
+}
+
+uint32_t
+SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex, bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list)
+{
+ return uint32_t();
+}
+
+void
+SymbolFilePDB::GetMangledNamesForFunction(const std::string &scope_qualified_name,
+ std::vector<lldb_private::ConstString> &mangled_names)
+{
+}
+
+uint32_t
+SymbolFilePDB::FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+ lldb_private::TypeMap &types)
+{
+ if (!append)
+ types.Clear();
+ if (!name)
+ return 0;
+
+ searched_symbol_files.clear();
+ searched_symbol_files.insert(this);
+
+ std::string name_str = name.AsCString();
+
+ // If this might be a regex, we have to return EVERY symbol and process them one by one, which is going
+ // to destroy performance on large PDB files. So try really hard not to use a regex match.
+ if (name_str.find_first_of("[]?*.-+\\") != std::string::npos)
+ FindTypesByRegex(name_str, max_matches, types);
+ else
+ FindTypesByName(name_str, max_matches, types);
+ return types.GetSize();
+}
+
+void
+SymbolFilePDB::FindTypesByRegex(const std::string &regex, uint32_t max_matches, lldb_private::TypeMap &types)
+{
+ // When searching by regex, we need to go out of our way to limit the search space as much as possible, since
+ // the way this is implemented is by searching EVERYTHING in the PDB and manually doing a regex compare. PDB
+ // library isn't optimized for regex searches or searches across multiple symbol types at the same time, so the
+ // best we can do is to search enums, then typedefs, then classes one by one, and do a regex compare against all
+ // of them.
+ PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef, PDB_SymType::UDT};
+ auto global = m_session_up->getGlobalScope();
+ std::unique_ptr<IPDBEnumSymbols> results;
+
+ std::regex re(regex);
+
+ uint32_t matches = 0;
+
+ for (auto tag : tags_to_search)
+ {
+ results = global->findAllChildren(tag);
+ while (auto result = results->getNext())
+ {
+ if (max_matches > 0 && matches >= max_matches)
+ break;
+
+ std::string type_name;
+ if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get()))
+ type_name = enum_type->getName();
+ else if (auto typedef_type = llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get()))
+ type_name = typedef_type->getName();
+ else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get()))
+ type_name = class_type->getName();
+ else
+ {
+ // We're only looking for types that have names. Skip symbols, as well as
+ // unnamed types such as arrays, pointers, etc.
+ continue;
+ }
+
+ if (!std::regex_match(type_name, re))
+ continue;
+
+ // This should cause the type to get cached and stored in the `m_types` lookup.
+ if (!ResolveTypeUID(result->getSymIndexId()))
+ continue;
+
+ auto iter = m_types.find(result->getSymIndexId());
+ if (iter == m_types.end())
+ continue;
+ types.Insert(iter->second);
+ ++matches;
+ }
+ }
+}
+
+void
+SymbolFilePDB::FindTypesByName(const std::string &name, uint32_t max_matches, lldb_private::TypeMap &types)
+{
+ auto global = m_session_up->getGlobalScope();
+ std::unique_ptr<IPDBEnumSymbols> results;
+ results = global->findChildren(PDB_SymType::None, name.c_str(), PDB_NameSearchFlags::NS_Default);
+
+ uint32_t matches = 0;
+
+ while (auto result = results->getNext())
+ {
+ if (max_matches > 0 && matches >= max_matches)
+ break;
+ switch (result->getSymTag())
+ {
+ case PDB_SymType::Enum:
+ case PDB_SymType::UDT:
+ case PDB_SymType::Typedef:
+ break;
+ default:
+ // We're only looking for types that have names. Skip symbols, as well as
+ // unnamed types such as arrays, pointers, etc.
+ continue;
+ }
+
+ // This should cause the type to get cached and stored in the `m_types` lookup.
+ if (!ResolveTypeUID(result->getSymIndexId()))
+ continue;
+
+ auto iter = m_types.find(result->getSymIndexId());
+ if (iter == m_types.end())
+ continue;
+ types.Insert(iter->second);
+ ++matches;
+ }
+}
+
+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 nullptr;
+}
+
+size_t
+SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask,
+ lldb_private::TypeList &type_list)
+{
+ return size_t();
+}
+
+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;
+}
+
+lldb_private::CompilerDeclContext
+SymbolFilePDB::FindNamespace(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx)
+{
+ return lldb_private::CompilerDeclContext();
+}
+
+lldb_private::ConstString
+SymbolFilePDB::GetPluginName()
+{
+ static ConstString g_name("pdb");
+ return g_name;
+}
+
+uint32_t
+SymbolFilePDB::GetPluginVersion()
+{
+ return 1;
+}
+
+IPDBSession &
+SymbolFilePDB::GetPDBSession()
+{
+ return *m_session_up;
+}
+
+const IPDBSession &
+SymbolFilePDB::GetPDBSession() const
+{
+ return *m_session_up;
+}
+
+lldb::CompUnitSP
+SymbolFilePDB::ParseCompileUnitForSymIndex(uint32_t id)
+{
+ auto found_cu = m_comp_units.find(id);
+ if (found_cu != m_comp_units.end())
+ return found_cu->second;
+
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(id);
+
+ // `getSourceFileName` returns the basename of the original source file used to generate this compiland. It does
+ // not return the full path. Currently the only way to get that is to do a basename lookup to get the
+ // IPDBSourceFile, but this is ambiguous in the case of two source files with the same name contributing to the
+ // same compiland. This is a moderately extreme edge case, so we consider this ok for now, although we need to find
+ // a long term solution.
+ auto file =
+ m_session_up->findOneSourceFile(cu.get(), cu->getSourceFileName(), PDB_NameSearchFlags::NS_CaseInsensitive);
+ std::string path = file->getFileName();
+
+ lldb::LanguageType lang;
+ auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
+ if (!details)
+ lang = lldb::eLanguageTypeC_plus_plus;
+ else
+ lang = TranslateLanguage(details->getLanguage());
+
+ // Don't support optimized code for now, DebugInfoPDB does not return this information.
+ LazyBool optimized = eLazyBoolNo;
+ auto result = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, path.c_str(), id, lang, optimized);
+ m_comp_units.insert(std::make_pair(id, result));
+ return result;
+}
+
+bool
+SymbolFilePDB::ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, uint32_t match_line)
+{
+ auto global = m_session_up->getGlobalScope();
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID());
+
+ // LineEntry needs the *index* of the file into the list of support files returned by
+ // ParseCompileUnitSupportFiles. But the underlying SDK gives us a globally unique
+ // idenfitifier in the namespace of the PDB. So, we have to do a mapping so that we
+ // can hand out indices.
+ llvm::DenseMap<uint32_t, uint32_t> index_map;
+ BuildSupportFileIdToSupportFileIndexMap(*cu, index_map);
+ auto line_table = llvm::make_unique<LineTable>(sc.comp_unit);
+
+ // Find contributions to `cu` from all source and header files.
+ std::string path = sc.comp_unit->GetPath();
+ auto files = m_session_up->getSourceFilesForCompiland(*cu);
+
+ // For each source and header file, create a LineSequence for contributions to the cu
+ // from that file, and add the sequence.
+ while (auto file = files->getNext())
+ {
+ std::unique_ptr<LineSequence> sequence(line_table->CreateLineSequenceContainer());
+ auto lines = m_session_up->findLineNumbers(*cu, *file);
+ int entry_count = lines->getChildCount();
+
+ uint64_t prev_addr;
+ uint32_t prev_length;
+ uint32_t prev_line;
+ uint32_t prev_source_idx;
+
+ for (int i = 0; i < entry_count; ++i)
+ {
+ auto line = lines->getChildAtIndex(i);
+
+ uint64_t lno = line->getLineNumber();
+ uint64_t addr = line->getVirtualAddress();
+ uint32_t length = line->getLength();
+ uint32_t source_id = line->getSourceFileId();
+ uint32_t col = line->getColumnNumber();
+ uint32_t source_idx = index_map[source_id];
+
+ // There was a gap between the current entry and the previous entry if the addresses don't perfectly line
+ // up.
+ bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
+
+ // Before inserting the current entry, insert a terminal entry at the end of the previous entry's address
+ // range if the current entry resulted in a gap from the previous entry.
+ if (is_gap && ShouldAddLine(match_line, prev_line, prev_length))
+ {
+ line_table->AppendLineEntryToSequence(sequence.get(), prev_addr + prev_length, prev_line, 0,
+ prev_source_idx, false, false, false, false, true);
+ }
+
+ if (ShouldAddLine(match_line, lno, length))
+ {
+ bool is_statement = line->isStatement();
+ bool is_prologue = false;
+ bool is_epilogue = false;
+ auto func = m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);
+ if (func)
+ {
+ auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();
+ is_prologue = (addr == prologue->getVirtualAddress());
+
+ auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();
+ is_epilogue = (addr == epilogue->getVirtualAddress());
+ }
+
+ line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col, source_idx, is_statement, false,
+ is_prologue, is_epilogue, false);
+ }
+
+ prev_addr = addr;
+ prev_length = length;
+ prev_line = lno;
+ prev_source_idx = source_idx;
+ }
+
+ if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length))
+ {
+ // The end is always a terminal entry, so insert it regardless.
+ line_table->AppendLineEntryToSequence(sequence.get(), prev_addr + prev_length, prev_line, 0,
+ prev_source_idx, false, false, false, false, true);
+ }
+
+ line_table->InsertSequence(sequence.release());
+ }
+
+ sc.comp_unit->SetLineTable(line_table.release());
+ return true;
+}
+
+void
+SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(const PDBSymbolCompiland &cu,
+ llvm::DenseMap<uint32_t, uint32_t> &index_map) const
+{
+ // This is a hack, but we need to convert the source id into an index into the support
+ // files array. We don't want to do path comparisons to avoid basename / full path
+ // issues that may or may not even be a problem, so we use the globally unique source
+ // file identifiers. Ideally we could use the global identifiers everywhere, but LineEntry
+ // currently assumes indices.
+ auto source_files = m_session_up->getSourceFilesForCompiland(cu);
+ int index = 0;
+
+ while (auto file = source_files->getNext())
+ {
+ uint32_t source_id = file->getUniqueId();
+ index_map[source_id] = index++;
+ }
+}
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
new file mode 100644
index 000000000000..cf75de8ac78e
--- /dev/null
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -0,0 +1,204 @@
+//===-- SymbolFilePDB.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
+#define lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
+
+#include "lldb/Core/UserID.h"
+#include "lldb/Symbol/SymbolFile.h"
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDB.h"
+
+class SymbolFilePDB : public lldb_private::SymbolFile
+{
+public:
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static void
+ DebuggerInitialize(lldb_private::Debugger &debugger);
+
+ static lldb_private::ConstString
+ GetPluginNameStatic();
+
+ static const char *
+ GetPluginDescriptionStatic();
+
+ static lldb_private::SymbolFile *
+ CreateInstance(lldb_private::ObjectFile *obj_file);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFilePDB(lldb_private::ObjectFile *ofile);
+
+ ~SymbolFilePDB() 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
+ ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
+
+ size_t
+ ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
+
+ bool
+ ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
+
+ bool
+ ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override;
+
+ bool
+ ParseCompileUnitSupportFiles(const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files) override;
+
+ bool
+ ParseImportedModules(const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) override;
+
+ size_t
+ ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
+
+ size_t
+ ParseTypes(const lldb_private::SymbolContext &sc) override;
+
+ size_t
+ ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
+
+ lldb_private::Type *
+ ResolveTypeUID(lldb::user_id_t type_uid) override;
+
+ bool
+ CompleteType(lldb_private::CompilerType &compiler_type) override;
+
+ lldb_private::CompilerDecl
+ GetDeclForUID(lldb::user_id_t uid) override;
+
+ lldb_private::CompilerDeclContext
+ GetDeclContextForUID(lldb::user_id_t uid) override;
+
+ lldb_private::CompilerDeclContext
+ GetDeclContextContainingUID(lldb::user_id_t uid) override;
+
+ void
+ ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
+
+ uint32_t
+ ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope,
+ lldb_private::SymbolContext &sc) override;
+
+ uint32_t
+ ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
+ uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) override;
+
+ uint32_t
+ FindGlobalVariables(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches, lldb_private::VariableList &variables) override;
+
+ uint32_t
+ FindGlobalVariables(const lldb_private::RegularExpression &regex, bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
+
+ uint32_t
+ FindFunctions(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ uint32_t 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;
+
+ void
+ GetMangledNamesForFunction(const std::string &scope_qualified_name,
+ std::vector<lldb_private::ConstString> &mangled_names) override;
+
+ uint32_t
+ FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, 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;
+
+ lldb_private::TypeList *
+ GetTypeList() override;
+
+ size_t
+ GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask,
+ lldb_private::TypeList &type_list) override;
+
+ lldb_private::TypeSystem *
+ GetTypeSystemForLanguage(lldb::LanguageType language) override;
+
+ lldb_private::CompilerDeclContext
+ FindNamespace(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
+
+ lldb_private::ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
+
+ llvm::pdb::IPDBSession &
+ GetPDBSession();
+
+ const llvm::pdb::IPDBSession &
+ GetPDBSession() const;
+
+private:
+ lldb::CompUnitSP
+ ParseCompileUnitForSymIndex(uint32_t id);
+
+ bool
+ ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, uint32_t match_line);
+
+ void
+ BuildSupportFileIdToSupportFileIndexMap(const llvm::pdb::PDBSymbolCompiland &cu,
+ llvm::DenseMap<uint32_t, uint32_t> &index_map) const;
+
+ void
+ FindTypesByRegex(const std::string &regex, uint32_t max_matches, lldb_private::TypeMap &types);
+
+ void
+ FindTypesByName(const std::string &name, uint32_t max_matches, lldb_private::TypeMap &types);
+
+ llvm::DenseMap<uint32_t, lldb::CompUnitSP> m_comp_units;
+ llvm::DenseMap<uint32_t, lldb::TypeSP> m_types;
+
+ std::vector<lldb::TypeSP> m_builtin_types;
+ std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
+ uint32_t m_cached_compile_unit_count;
+ std::unique_ptr<lldb_private::CompilerDeclContext> m_tu_decl_ctx_up;
+};
+
+#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
diff --git a/source/Plugins/SymbolFile/Symtab/Makefile b/source/Plugins/SymbolFile/Symtab/Makefile
deleted file mode 100644
index 2c3dbb6d86ab..000000000000
--- a/source/Plugins/SymbolFile/Symtab/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/SymbolFile/Symtab/Makefile -----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginSymbolFileSymtab
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index d3dd1ae923e0..24175079c95f 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -153,7 +153,8 @@ SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
{
const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
if (cu_symbol)
- cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0, eLanguageTypeUnknown, false));
+ cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0,
+ eLanguageTypeUnknown, eLazyBoolNo));
}
return cu_sp;
}
diff --git a/source/Plugins/SymbolVendor/ELF/Makefile b/source/Plugins/SymbolVendor/ELF/Makefile
deleted file mode 100644
index 47c24a2bda34..000000000000
--- a/source/Plugins/SymbolVendor/ELF/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/SymbolVendor/ELF/Makefile ---------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginSymbolVendorELF
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/SymbolVendor/MacOSX/Makefile b/source/Plugins/SymbolVendor/MacOSX/Makefile
deleted file mode 100644
index 9f71ad669aa0..000000000000
--- a/source/Plugins/SymbolVendor/MacOSX/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/SymbolVendor/MacOSX/Makefile ---------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginSymbolVendorMacOSX
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
index 2ca367c0cce8..38998469dcbe 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
@@ -19,6 +19,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Value.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -95,12 +96,12 @@ extern \"C\"
} \n\
";
-AppleGetItemInfoHandler::AppleGetItemInfoHandler (Process *process) :
- m_process (process),
- m_get_item_info_impl_code (),
- m_get_item_info_function_mutex(),
- m_get_item_info_return_buffer_addr (LLDB_INVALID_ADDRESS),
- m_get_item_info_retbuffer_mutex()
+AppleGetItemInfoHandler::AppleGetItemInfoHandler(Process *process)
+ : m_process(process),
+ m_get_item_info_impl_code(),
+ m_get_item_info_function_mutex(),
+ m_get_item_info_return_buffer_addr(LLDB_INVALID_ADDRESS),
+ m_get_item_info_retbuffer_mutex()
{
}
@@ -109,14 +110,14 @@ AppleGetItemInfoHandler::~AppleGetItemInfoHandler ()
}
void
-AppleGetItemInfoHandler::Detach ()
+AppleGetItemInfoHandler::Detach()
{
if (m_process && m_process->IsAlive() && m_get_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS)
{
- Mutex::Locker locker;
- locker.TryLock (m_get_item_info_retbuffer_mutex); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory (m_get_item_info_return_buffer_addr);
+ std::unique_lock<std::mutex> lock(m_get_item_info_retbuffer_mutex, std::defer_lock);
+ lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
+ m_process->DeallocateMemory(m_get_item_info_return_buffer_addr);
}
}
@@ -132,18 +133,18 @@ AppleGetItemInfoHandler::Detach ()
// make the function call.
lldb::addr_t
-AppleGetItemInfoHandler::SetupGetItemInfoFunction (Thread &thread, ValueList &get_item_info_arglist)
+AppleGetItemInfoHandler::SetupGetItemInfoFunction(Thread &thread, ValueList &get_item_info_arglist)
{
- ExecutionContext exe_ctx (thread.shared_from_this());
- StreamString errors;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
FunctionCaller *get_item_info_caller = nullptr;
// Scope for mutex locker:
{
- Mutex::Locker locker(m_get_item_info_function_mutex);
-
+ std::lock_guard<std::mutex> guard(m_get_item_info_function_mutex);
+
// First stage is to make the UtilityFunction to hold our injected function:
if (!m_get_item_info_impl_code.get())
@@ -161,11 +162,14 @@ AppleGetItemInfoHandler::SetupGetItemInfoFunction (Thread &thread, ValueList &ge
log->Printf ("Failed to get utility function: %s.", error.AsCString());
return args_addr;
}
-
- if (!m_get_item_info_impl_code->Install(errors, exe_ctx))
+
+ if (!m_get_item_info_impl_code->Install(diagnostics, exe_ctx))
{
if (log)
- log->Printf ("Failed to install get-item-info introspection: %s.", errors.GetData());
+ {
+ log->Printf("Failed to install get-item-info introspection.");
+ diagnostics.Dump(log);
+ }
m_get_item_info_impl_code.reset();
return args_addr;
}
@@ -174,7 +178,6 @@ AppleGetItemInfoHandler::SetupGetItemInfoFunction (Thread &thread, ValueList &ge
{
if (log)
log->Printf("No get-item-info introspection code found.");
- errors.Printf ("No get-item-info introspection code found.");
return LLDB_INVALID_ADDRESS;
}
@@ -186,6 +189,7 @@ AppleGetItemInfoHandler::SetupGetItemInfoFunction (Thread &thread, ValueList &ge
get_item_info_caller = m_get_item_info_impl_code->MakeFunctionCaller(get_item_info_return_type,
get_item_info_arglist,
+ thread.shared_from_this(),
error);
if (error.Fail())
{
@@ -207,20 +211,24 @@ AppleGetItemInfoHandler::SetupGetItemInfoFunction (Thread &thread, ValueList &ge
}
}
}
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Now write down the argument values for this particular call. This looks like it might be a race condition
// if other threads were calling into here, but actually it isn't because we allocate a new args structure for
// this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (!get_item_info_caller->WriteFunctionArguments (exe_ctx, args_addr, get_item_info_arglist, errors))
+ if (!get_item_info_caller->WriteFunctionArguments(exe_ctx, args_addr, get_item_info_arglist, diagnostics))
{
if (log)
- log->Printf ("Error writing get-item-info function arguments: \"%s\".", errors.GetData());
+ {
+ log->Printf("Error writing get-item-info function arguments.");
+ diagnostics.Dump(log);
+ }
+
return args_addr;
}
-
+
return args_addr;
}
@@ -288,8 +296,7 @@ AppleGetItemInfoHandler::GetItemInfo (Thread &thread, uint64_t item, addr_t page
page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
page_to_free_size_value.SetCompilerType (clang_uint64_type);
-
- Mutex::Locker locker(m_get_item_info_retbuffer_mutex);
+ std::lock_guard<std::mutex> guard(m_get_item_info_retbuffer_mutex);
if (m_get_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS)
{
addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
@@ -322,12 +329,12 @@ AppleGetItemInfoHandler::GetItemInfo (Thread &thread, uint64_t item, addr_t page
page_to_free_size_value.GetScalar() = page_to_free_size;
argument_values.PushValue (page_to_free_size_value);
- addr_t args_addr = SetupGetItemInfoFunction (thread, argument_values);
+ addr_t args_addr = SetupGetItemInfoFunction(thread, argument_values);
- StreamString errors;
+ DiagnosticManager diagnostics;
ExecutionContext exe_ctx;
EvaluateExpressionOptions options;
- options.SetUnwindOnError (true);
+ options.SetUnwindOnError(true);
options.SetIgnoreBreakpoints (true);
options.SetStopOthers (true);
options.SetTimeoutUsec(500000);
@@ -351,8 +358,8 @@ AppleGetItemInfoHandler::GetItemInfo (Thread &thread, uint64_t item, addr_t page
error.SetErrorString("Could not retrieve function caller for __introspection_dispatch_queue_item_get_info.");
return return_value;
}
-
- func_call_ret = func_caller->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+
+ func_call_ret = func_caller->ExecuteFunction(exe_ctx, &args_addr, options, diagnostics, results);
if (func_call_ret != eExpressionCompleted || !error.Success())
{
if (log)
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
index 51182a624939..dc341d672d6a 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
@@ -13,13 +13,14 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
#include <vector>
+
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
#include "lldb/Expression/UtilityFunction.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/CompilerType.h"
// This class will insert a UtilityFunction into the inferior process for
@@ -105,11 +106,10 @@ private:
lldb_private::Process *m_process;
std::unique_ptr<UtilityFunction> m_get_item_info_impl_code;
- Mutex m_get_item_info_function_mutex;
+ std::mutex m_get_item_info_function_mutex;
lldb::addr_t m_get_item_info_return_buffer_addr;
- Mutex m_get_item_info_retbuffer_mutex;
-
+ std::mutex m_get_item_info_retbuffer_mutex;
};
} // using namespace lldb_private
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
index 97699878f5ee..d311f5fb5f6e 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
@@ -19,6 +19,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Value.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -99,12 +100,12 @@ extern \"C\"
} \n\
";
-AppleGetPendingItemsHandler::AppleGetPendingItemsHandler (Process *process) :
- m_process (process),
- m_get_pending_items_impl_code (),
- m_get_pending_items_function_mutex(),
- m_get_pending_items_return_buffer_addr (LLDB_INVALID_ADDRESS),
- m_get_pending_items_retbuffer_mutex()
+AppleGetPendingItemsHandler::AppleGetPendingItemsHandler(Process *process)
+ : m_process(process),
+ m_get_pending_items_impl_code(),
+ m_get_pending_items_function_mutex(),
+ m_get_pending_items_return_buffer_addr(LLDB_INVALID_ADDRESS),
+ m_get_pending_items_retbuffer_mutex()
{
}
@@ -113,14 +114,13 @@ AppleGetPendingItemsHandler::~AppleGetPendingItemsHandler ()
}
void
-AppleGetPendingItemsHandler::Detach ()
+AppleGetPendingItemsHandler::Detach()
{
-
if (m_process && m_process->IsAlive() && m_get_pending_items_return_buffer_addr != LLDB_INVALID_ADDRESS)
{
- Mutex::Locker locker;
- locker.TryLock (m_get_pending_items_retbuffer_mutex); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory (m_get_pending_items_return_buffer_addr);
+ std::unique_lock<std::mutex> lock(m_get_pending_items_retbuffer_mutex, std::defer_lock);
+ lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
+ m_process->DeallocateMemory(m_get_pending_items_return_buffer_addr);
}
}
@@ -136,18 +136,20 @@ AppleGetPendingItemsHandler::Detach ()
// make the function call.
lldb::addr_t
-AppleGetPendingItemsHandler::SetupGetPendingItemsFunction (Thread &thread, ValueList &get_pending_items_arglist)
+AppleGetPendingItemsHandler::SetupGetPendingItemsFunction(Thread &thread, ValueList &get_pending_items_arglist)
{
- ExecutionContext exe_ctx (thread.shared_from_this());
- StreamString errors;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+ ThreadSP thread_sp (thread.shared_from_this());
+ ExecutionContext exe_ctx (thread_sp);
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
FunctionCaller *get_pending_items_caller = nullptr;
-
+
// Scope for mutex locker:
{
- Mutex::Locker locker(m_get_pending_items_function_mutex);
-
+ std::lock_guard<std::mutex> guard(m_get_pending_items_function_mutex);
+
// First stage is to make the ClangUtility to hold our injected function:
if (!m_get_pending_items_impl_code.get())
@@ -165,11 +167,14 @@ AppleGetPendingItemsHandler::SetupGetPendingItemsFunction (Thread &thread, Value
log->Printf ("Failed to get UtilityFunction for pending-items introspection: %s.", error.AsCString());
return args_addr;
}
-
- if (!m_get_pending_items_impl_code->Install(errors, exe_ctx))
+
+ if (!m_get_pending_items_impl_code->Install(diagnostics, exe_ctx))
{
if (log)
- log->Printf ("Failed to install pending-items introspection: %s.", errors.GetData());
+ {
+ log->Printf("Failed to install pending-items introspection.");
+ diagnostics.Dump(log);
+ }
m_get_pending_items_impl_code.reset();
return args_addr;
}
@@ -187,6 +192,7 @@ AppleGetPendingItemsHandler::SetupGetPendingItemsFunction (Thread &thread, Value
CompilerType get_pending_items_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
get_pending_items_caller = m_get_pending_items_impl_code->MakeFunctionCaller (get_pending_items_return_type,
get_pending_items_arglist,
+ thread_sp,
error);
if (error.Fail())
{
@@ -196,11 +202,10 @@ AppleGetPendingItemsHandler::SetupGetPendingItemsFunction (Thread &thread, Value
return args_addr;
}
}
-
}
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
if (get_pending_items_caller == nullptr)
{
if (log)
@@ -212,13 +217,17 @@ AppleGetPendingItemsHandler::SetupGetPendingItemsFunction (Thread &thread, Value
// if other threads were calling into here, but actually it isn't because we allocate a new args structure for
// this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (!get_pending_items_caller->WriteFunctionArguments (exe_ctx, args_addr, get_pending_items_arglist, errors))
+ if (!get_pending_items_caller->WriteFunctionArguments(exe_ctx, args_addr, get_pending_items_arglist, diagnostics))
{
if (log)
- log->Printf ("Error writing pending-items function arguments: \"%s\".", errors.GetData());
+ {
+ log->Printf("Error writing pending-items function arguments.");
+ diagnostics.Dump(log);
+ }
+
return args_addr;
}
-
+
return args_addr;
}
@@ -288,8 +297,7 @@ AppleGetPendingItemsHandler::GetPendingItems (Thread &thread, addr_t queue, addr
page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
page_to_free_size_value.SetCompilerType (clang_uint64_type);
-
- Mutex::Locker locker(m_get_pending_items_retbuffer_mutex);
+ std::lock_guard<std::mutex> guard(m_get_pending_items_retbuffer_mutex);
if (m_get_pending_items_return_buffer_addr == LLDB_INVALID_ADDRESS)
{
addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
@@ -322,12 +330,12 @@ AppleGetPendingItemsHandler::GetPendingItems (Thread &thread, addr_t queue, addr
page_to_free_size_value.GetScalar() = page_to_free_size;
argument_values.PushValue (page_to_free_size_value);
- addr_t args_addr = SetupGetPendingItemsFunction (thread, argument_values);
+ addr_t args_addr = SetupGetPendingItemsFunction(thread, argument_values);
- StreamString errors;
+ DiagnosticManager diagnostics;
ExecutionContext exe_ctx;
FunctionCaller *get_pending_items_caller = m_get_pending_items_impl_code->GetFunctionCaller();
-
+
EvaluateExpressionOptions options;
options.SetUnwindOnError (true);
options.SetIgnoreBreakpoints (true);
@@ -342,10 +350,9 @@ AppleGetPendingItemsHandler::GetPendingItems (Thread &thread, addr_t queue, addr
return return_value;
}
-
ExpressionResults func_call_ret;
Value results;
- func_call_ret = get_pending_items_caller->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+ func_call_ret = get_pending_items_caller->ExecuteFunction(exe_ctx, &args_addr, options, diagnostics, results);
if (func_call_ret != eExpressionCompleted || !error.Success())
{
if (log)
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
index 445c4a0fb82b..96fbf4a548c4 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
@@ -13,12 +13,13 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
#include <vector>
+
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/CompilerType.h"
// This class will insert a UtilityFunction into the inferior process for
@@ -107,11 +108,10 @@ private:
lldb_private::Process *m_process;
std::unique_ptr<UtilityFunction> m_get_pending_items_impl_code;
- Mutex m_get_pending_items_function_mutex;
+ std::mutex m_get_pending_items_function_mutex;
lldb::addr_t m_get_pending_items_return_buffer_addr;
- Mutex m_get_pending_items_retbuffer_mutex;
-
+ std::mutex m_get_pending_items_retbuffer_mutex;
};
} // using namespace lldb_private
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
index 3370b3257a25..e90fe6d5d17d 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
@@ -18,6 +18,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Value.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -95,12 +96,12 @@ extern \"C\"
} \n\
";
-AppleGetQueuesHandler::AppleGetQueuesHandler (Process *process) :
- m_process (process),
- m_get_queues_impl_code_up (),
- m_get_queues_function_mutex(),
- m_get_queues_return_buffer_addr (LLDB_INVALID_ADDRESS),
- m_get_queues_retbuffer_mutex()
+AppleGetQueuesHandler::AppleGetQueuesHandler(Process *process)
+ : m_process(process),
+ m_get_queues_impl_code_up(),
+ m_get_queues_function_mutex(),
+ m_get_queues_return_buffer_addr(LLDB_INVALID_ADDRESS),
+ m_get_queues_retbuffer_mutex()
{
}
@@ -109,14 +110,14 @@ AppleGetQueuesHandler::~AppleGetQueuesHandler ()
}
void
-AppleGetQueuesHandler::Detach ()
+AppleGetQueuesHandler::Detach()
{
if (m_process && m_process->IsAlive() && m_get_queues_return_buffer_addr != LLDB_INVALID_ADDRESS)
{
- Mutex::Locker locker;
- locker.TryLock (m_get_queues_retbuffer_mutex); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory (m_get_queues_return_buffer_addr);
+ std::unique_lock<std::mutex> lock(m_get_queues_retbuffer_mutex, std::defer_lock);
+ lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
+ m_process->DeallocateMemory(m_get_queues_return_buffer_addr);
}
}
@@ -146,18 +147,20 @@ AppleGetQueuesHandler::Detach ()
lldb::addr_t
AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_queues_arglist)
{
- ExecutionContext exe_ctx (thread.shared_from_this());
+ ThreadSP thread_sp(thread.shared_from_this());
+ ExecutionContext exe_ctx (thread_sp);
+
Address impl_code_address;
- StreamString errors;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
-
+
FunctionCaller *get_queues_caller = nullptr;
// Scope for mutex locker:
{
- Mutex::Locker locker(m_get_queues_function_mutex);
-
+ std::lock_guard<std::mutex> guard(m_get_queues_function_mutex);
+
// First stage is to make the ClangUtility to hold our injected function:
if (!m_get_queues_impl_code_up.get())
@@ -175,11 +178,14 @@ AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_qu
log->Printf ("Failed to get UtilityFunction for queues introspection: %s.", error.AsCString());
return args_addr;
}
-
- if (!m_get_queues_impl_code_up->Install(errors, exe_ctx))
+
+ if (!m_get_queues_impl_code_up->Install(diagnostics, exe_ctx))
{
if (log)
- log->Printf ("Failed to install queues introspection: %s.", errors.GetData());
+ {
+ log->Printf("Failed to install queues introspection");
+ diagnostics.Dump(log);
+ }
m_get_queues_impl_code_up.reset();
return args_addr;
}
@@ -187,18 +193,21 @@ AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_qu
else
{
if (log)
+ {
log->Printf("No queues introspection code found.");
- errors.Printf ("No queues introspection code found.");
+ diagnostics.Dump(log);
+ }
return LLDB_INVALID_ADDRESS;
}
}
-
+
// Next make the runner function for our implementation utility function.
ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
CompilerType get_queues_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
Error error;
get_queues_caller = m_get_queues_impl_code_up->MakeFunctionCaller (get_queues_return_type,
get_queues_arglist,
+ thread_sp,
error);
if (error.Fail())
{
@@ -207,20 +216,23 @@ AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_qu
return args_addr;
}
}
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Now write down the argument values for this particular call. This looks like it might be a race condition
// if other threads were calling into here, but actually it isn't because we allocate a new args structure for
// this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (!get_queues_caller->WriteFunctionArguments (exe_ctx, args_addr, get_queues_arglist, errors))
+ if (!get_queues_caller->WriteFunctionArguments(exe_ctx, args_addr, get_queues_arglist, diagnostics))
{
if (log)
- log->Printf ("Error writing get-queues function arguments: \"%s\".", errors.GetData());
+ {
+ log->Printf("Error writing get-queues function arguments.");
+ diagnostics.Dump(log);
+ }
return args_addr;
}
-
+
return args_addr;
}
@@ -285,8 +297,7 @@ AppleGetQueuesHandler::GetCurrentQueues (Thread &thread, addr_t page_to_free, ui
page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
page_to_free_size_value.SetCompilerType (clang_uint64_type);
-
- Mutex::Locker locker(m_get_queues_retbuffer_mutex);
+ std::lock_guard<std::mutex> guard(m_get_queues_retbuffer_mutex);
if (m_get_queues_return_buffer_addr == LLDB_INVALID_ADDRESS)
{
addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
@@ -332,10 +343,10 @@ AppleGetQueuesHandler::GetCurrentQueues (Thread &thread, addr_t page_to_free, ui
return return_value;
}
- StreamString errors;
+ DiagnosticManager diagnostics;
ExecutionContext exe_ctx;
EvaluateExpressionOptions options;
- options.SetUnwindOnError (true);
+ options.SetUnwindOnError(true);
options.SetIgnoreBreakpoints (true);
options.SetStopOthers (true);
options.SetTimeoutUsec(500000);
@@ -344,7 +355,7 @@ AppleGetQueuesHandler::GetCurrentQueues (Thread &thread, addr_t page_to_free, ui
ExpressionResults func_call_ret;
Value results;
- func_call_ret = get_queues_caller->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+ func_call_ret = get_queues_caller->ExecuteFunction(exe_ctx, &args_addr, options, diagnostics, results);
if (func_call_ret != eExpressionCompleted || !error.Success())
{
if (log)
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
index 6f3df5f62807..b7ca26dafc30 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
@@ -13,12 +13,13 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
#include <vector>
+
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/CompilerType.h"
// This class will insert a UtilityFunction into the inferior process for
@@ -104,11 +105,10 @@ private:
lldb_private::Process *m_process;
std::unique_ptr<UtilityFunction> m_get_queues_impl_code_up;
- Mutex m_get_queues_function_mutex;
+ std::mutex m_get_queues_function_mutex;
lldb::addr_t m_get_queues_return_buffer_addr;
- Mutex m_get_queues_retbuffer_mutex;
-
+ std::mutex m_get_queues_retbuffer_mutex;
};
} // using namespace lldb_private
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
index ba03f51152c0..85ad012c59fc 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
@@ -14,12 +14,12 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Value.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/Expression.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
@@ -30,6 +30,7 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-private.h"
using namespace lldb;
using namespace lldb_private;
@@ -102,12 +103,12 @@ extern \"C\"
} \n\
";
-AppleGetThreadItemInfoHandler::AppleGetThreadItemInfoHandler (Process *process) :
- m_process (process),
- m_get_thread_item_info_impl_code (),
- m_get_thread_item_info_function_mutex(),
- m_get_thread_item_info_return_buffer_addr (LLDB_INVALID_ADDRESS),
- m_get_thread_item_info_retbuffer_mutex()
+AppleGetThreadItemInfoHandler::AppleGetThreadItemInfoHandler(Process *process)
+ : m_process(process),
+ m_get_thread_item_info_impl_code(),
+ m_get_thread_item_info_function_mutex(),
+ m_get_thread_item_info_return_buffer_addr(LLDB_INVALID_ADDRESS),
+ m_get_thread_item_info_retbuffer_mutex()
{
}
@@ -116,14 +117,14 @@ AppleGetThreadItemInfoHandler::~AppleGetThreadItemInfoHandler ()
}
void
-AppleGetThreadItemInfoHandler::Detach ()
+AppleGetThreadItemInfoHandler::Detach()
{
if (m_process && m_process->IsAlive() && m_get_thread_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS)
{
- Mutex::Locker locker;
- locker.TryLock (m_get_thread_item_info_retbuffer_mutex); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory (m_get_thread_item_info_return_buffer_addr);
+ std::unique_lock<std::mutex> lock(m_get_thread_item_info_retbuffer_mutex, std::defer_lock);
+ lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
+ m_process->DeallocateMemory(m_get_thread_item_info_return_buffer_addr);
}
}
@@ -141,17 +142,18 @@ AppleGetThreadItemInfoHandler::Detach ()
lldb::addr_t
AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, ValueList &get_thread_item_info_arglist)
{
- ExecutionContext exe_ctx (thread.shared_from_this());
+ ThreadSP thread_sp(thread.shared_from_this());
+ ExecutionContext exe_ctx (thread_sp);
Address impl_code_address;
- StreamString errors;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
FunctionCaller *get_thread_item_info_caller = nullptr;
// Scope for mutex locker:
{
- Mutex::Locker locker(m_get_thread_item_info_function_mutex);
-
+ std::lock_guard<std::mutex> guard(m_get_thread_item_info_function_mutex);
+
// First stage is to make the ClangUtility to hold our injected function:
if (!m_get_thread_item_info_impl_code.get())
@@ -171,11 +173,15 @@ AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, V
m_get_thread_item_info_impl_code.reset();
return args_addr;
}
-
- if (!m_get_thread_item_info_impl_code->Install(errors, exe_ctx))
+
+ if (!m_get_thread_item_info_impl_code->Install(diagnostics, exe_ctx))
{
if (log)
- log->Printf ("Failed to install get-thread-item-info introspection: %s.", errors.GetData());
+ {
+ log->Printf("Failed to install get-thread-item-info introspection.");
+ diagnostics.Dump(log);
+ }
+
m_get_thread_item_info_impl_code.reset();
return args_addr;
}
@@ -184,10 +190,9 @@ AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, V
{
if (log)
log->Printf("No get-thread-item-info introspection code found.");
- errors.Printf ("No get-thread-item-info introspection code found.");
return LLDB_INVALID_ADDRESS;
}
-
+
// Also make the FunctionCaller for this UtilityFunction:
ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
@@ -195,6 +200,7 @@ AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, V
get_thread_item_info_caller = m_get_thread_item_info_impl_code->MakeFunctionCaller (get_thread_item_info_return_type,
get_thread_item_info_arglist,
+ thread_sp,
error);
if (error.Fail())
{
@@ -210,20 +216,24 @@ AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, V
get_thread_item_info_caller = m_get_thread_item_info_impl_code->GetFunctionCaller();
}
}
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Now write down the argument values for this particular call. This looks like it might be a race condition
// if other threads were calling into here, but actually it isn't because we allocate a new args structure for
// this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (!get_thread_item_info_caller->WriteFunctionArguments (exe_ctx, args_addr, get_thread_item_info_arglist, errors))
+ if (!get_thread_item_info_caller->WriteFunctionArguments(exe_ctx, args_addr, get_thread_item_info_arglist,
+ diagnostics))
{
if (log)
- log->Printf ("Error writing get-thread-item-info function arguments: \"%s\".", errors.GetData());
+ {
+ log->Printf("Error writing get-thread-item-info function arguments");
+ diagnostics.Dump(log);
+ }
return args_addr;
}
-
+
return args_addr;
}
@@ -290,8 +300,7 @@ AppleGetThreadItemInfoHandler::GetThreadItemInfo (Thread &thread, tid_t thread_i
page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
page_to_free_size_value.SetCompilerType (clang_uint64_type);
-
- Mutex::Locker locker(m_get_thread_item_info_retbuffer_mutex);
+ std::lock_guard<std::mutex> guard(m_get_thread_item_info_retbuffer_mutex);
if (m_get_thread_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS)
{
addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
@@ -324,13 +333,13 @@ AppleGetThreadItemInfoHandler::GetThreadItemInfo (Thread &thread, tid_t thread_i
page_to_free_size_value.GetScalar() = page_to_free_size;
argument_values.PushValue (page_to_free_size_value);
- addr_t args_addr = SetupGetThreadItemInfoFunction (thread, argument_values);
+ addr_t args_addr = SetupGetThreadItemInfoFunction(thread, argument_values);
- StreamString errors;
+ DiagnosticManager diagnostics;
ExecutionContext exe_ctx;
EvaluateExpressionOptions options;
FunctionCaller *get_thread_item_info_caller = nullptr;
-
+
options.SetUnwindOnError (true);
options.SetIgnoreBreakpoints (true);
options.SetStopOthers (true);
@@ -354,7 +363,7 @@ AppleGetThreadItemInfoHandler::GetThreadItemInfo (Thread &thread, tid_t thread_i
ExpressionResults func_call_ret;
Value results;
- func_call_ret = get_thread_item_info_caller->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+ func_call_ret = get_thread_item_info_caller->ExecuteFunction(exe_ctx, &args_addr, options, diagnostics, results);
if (func_call_ret != eExpressionCompleted || !error.Success())
{
if (log)
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
index c1798fb515b4..21a63e8c225a 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
@@ -13,12 +13,13 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
#include <vector>
+
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/CompilerType.h"
// This class will insert a UtilityFunction into the inferior process for
@@ -101,11 +102,10 @@ private:
lldb_private::Process *m_process;
std::unique_ptr<UtilityFunction> m_get_thread_item_info_impl_code;
- Mutex m_get_thread_item_info_function_mutex;
+ std::mutex m_get_thread_item_info_function_mutex;
lldb::addr_t m_get_thread_item_info_return_buffer_addr;
- Mutex m_get_thread_item_info_retbuffer_mutex;
-
+ std::mutex m_get_thread_item_info_retbuffer_mutex;
};
} // using namespace lldb_private
diff --git a/source/Plugins/SystemRuntime/MacOSX/Makefile b/source/Plugins/SystemRuntime/MacOSX/Makefile
deleted file mode 100644
index eebfb52073d5..000000000000
--- a/source/Plugins/SystemRuntime/MacOSX/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/SystemRuntime/MacOSX ----*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginSystemRuntimeMacOSX
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index 1097ef36960e..9ec36b383af3 100644
--- a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -83,25 +83,25 @@ SystemRuntimeMacOSX::CreateInstance (Process* process)
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-SystemRuntimeMacOSX::SystemRuntimeMacOSX (Process* process) :
- SystemRuntime(process),
- m_break_id(LLDB_INVALID_BREAK_ID),
- m_mutex(Mutex::eMutexTypeRecursive),
- m_get_queues_handler(process),
- m_get_pending_items_handler(process),
- m_get_item_info_handler(process),
- m_get_thread_item_info_handler(process),
- m_page_to_free(LLDB_INVALID_ADDRESS),
- m_page_to_free_size(0),
- m_lib_backtrace_recording_info(),
- m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS),
- m_libdispatch_offsets(),
- m_libpthread_layout_offsets_addr (LLDB_INVALID_ADDRESS),
- m_libpthread_offsets(),
- m_dispatch_tsd_indexes_addr (LLDB_INVALID_ADDRESS),
- m_libdispatch_tsd_indexes(),
- m_dispatch_voucher_offsets_addr (LLDB_INVALID_ADDRESS),
- m_libdispatch_voucher_offsets()
+SystemRuntimeMacOSX::SystemRuntimeMacOSX(Process *process)
+ : SystemRuntime(process),
+ m_break_id(LLDB_INVALID_BREAK_ID),
+ m_mutex(),
+ m_get_queues_handler(process),
+ m_get_pending_items_handler(process),
+ m_get_item_info_handler(process),
+ m_get_thread_item_info_handler(process),
+ m_page_to_free(LLDB_INVALID_ADDRESS),
+ m_page_to_free_size(0),
+ m_lib_backtrace_recording_info(),
+ m_dispatch_queue_offsets_addr(LLDB_INVALID_ADDRESS),
+ m_libdispatch_offsets(),
+ m_libpthread_layout_offsets_addr(LLDB_INVALID_ADDRESS),
+ m_libpthread_offsets(),
+ m_dispatch_tsd_indexes_addr(LLDB_INVALID_ADDRESS),
+ m_libdispatch_tsd_indexes(),
+ m_dispatch_voucher_offsets_addr(LLDB_INVALID_ADDRESS),
+ m_libdispatch_voucher_offsets()
{
}
@@ -128,7 +128,7 @@ SystemRuntimeMacOSX::Detach ()
void
SystemRuntimeMacOSX::Clear (bool clear_process)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
m_process->ClearBreakpointSiteByID(m_break_id);
@@ -486,7 +486,7 @@ SystemRuntimeMacOSX::GetExtendedBacktraceThread (ThreadSP real_thread, ConstStri
}
else
{
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
+ ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo ret = m_get_thread_item_info_handler.GetThreadItemInfo (*cur_thread_sp.get(), real_thread->GetID(), m_page_to_free, m_page_to_free_size, error);
m_page_to_free = LLDB_INVALID_ADDRESS;
m_page_to_free_size = 0;
@@ -524,7 +524,7 @@ SystemRuntimeMacOSX::GetExtendedBacktraceFromItemRef (lldb::addr_t item_ref)
ThreadSP return_thread_sp;
AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
+ ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
Error error;
ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), item_ref, m_page_to_free, m_page_to_free_size, error);
m_page_to_free = LLDB_INVALID_ADDRESS;
@@ -696,7 +696,7 @@ SystemRuntimeMacOSX::PopulateQueueList (lldb_private::QueueList &queue_list)
if (BacktraceRecordingHeadersInitialized())
{
AppleGetQueuesHandler::GetQueuesReturnInfo queue_info_pointer;
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
+ ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
if (cur_thread_sp)
{
Error error;
@@ -760,7 +760,7 @@ SystemRuntimeMacOSX::GetPendingItemRefsForQueue (lldb::addr_t queue)
{
PendingItemsForQueue pending_item_refs;
AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer;
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
+ ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
if (cur_thread_sp)
{
Error error;
@@ -859,7 +859,7 @@ SystemRuntimeMacOSX::CompleteQueueItem (QueueItem *queue_item, addr_t item_ref)
{
AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
+ ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
Error error;
ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), item_ref, m_page_to_free, m_page_to_free_size, error);
m_page_to_free = LLDB_INVALID_ADDRESS;
diff --git a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
index 8fe15fa4d8a5..b685a056f5c2 100644
--- a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
+++ b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
@@ -12,8 +12,9 @@
// C Includes
// C++ Includes
-#include <vector>
+#include <mutex>
#include <string>
+#include <vector>
// Other libraries and framework include
// Project includes
@@ -23,7 +24,6 @@
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/UUID.h"
#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/QueueItem.h"
@@ -124,7 +124,7 @@ public:
protected:
lldb::user_id_t m_break_id;
- mutable lldb_private::Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
private:
struct libBacktraceRecording_info {
diff --git a/source/Plugins/UnwindAssembly/InstEmulation/Makefile b/source/Plugins/UnwindAssembly/InstEmulation/Makefile
deleted file mode 100644
index e006235864f1..000000000000
--- a/source/Plugins/UnwindAssembly/InstEmulation/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##==- source/Plugins/UnwindAssembly/InstEmulation/Makefile -*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginUnwindAssemblyInstEmulation
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index eb5fec34fc20..72adf7576270 100644
--- a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -125,6 +125,10 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
RegisterInfo ra_reg_info;
m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, ra_reg_info);
+ // The architecture dependent condition code of the last processed instruction.
+ EmulateInstruction::InstructionCondition last_condition = EmulateInstruction::UnconditionalCondition;
+ lldb::addr_t condition_block_start_offset = 0;
+
for (size_t idx=0; idx<num_instructions; ++idx)
{
m_curr_row_modified = false;
@@ -146,7 +150,41 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
UnwindPlan::Row *newrow = new UnwindPlan::Row;
*newrow = *it->second.first;
m_curr_row.reset(newrow);
- m_register_values = it->second.second;;
+ m_register_values = it->second.second;
+ }
+
+ m_inst_emulator_ap->SetInstruction (inst->GetOpcode(),
+ inst->GetAddress(),
+ exe_ctx.GetTargetPtr());
+
+ if (last_condition != m_inst_emulator_ap->GetInstructionCondition())
+ {
+ if (m_inst_emulator_ap->GetInstructionCondition() != EmulateInstruction::UnconditionalCondition &&
+ saved_unwind_states.count(current_offset) == 0)
+ {
+ // If we don't have a saved row for the current offset then save our
+ // current state because we will have to restore it after the
+ // conditional block.
+ auto new_row = std::make_shared<UnwindPlan::Row>(*m_curr_row.get());
+ saved_unwind_states.insert({current_offset, {new_row, m_register_values}});
+ }
+
+ // If the last instruction was conditional with a different condition
+ // then the then current condition then restore the condition.
+ if (last_condition != EmulateInstruction::UnconditionalCondition)
+ {
+ const auto& saved_state = saved_unwind_states.at(condition_block_start_offset);
+ m_curr_row = std::make_shared<UnwindPlan::Row>(*saved_state.first);
+ m_curr_row->SetOffset(current_offset);
+ m_register_values = saved_state.second;
+ bool replace_existing = true; // The last instruction might already
+ // created a row for this offset and
+ // we want to overwrite it.
+ unwind_plan.InsertRow(std::make_shared<UnwindPlan::Row>(*m_curr_row), replace_existing);
+ }
+
+ // We are starting a new conditional block at the catual offset
+ condition_block_start_offset = current_offset;
}
if (log && log->GetVerbose ())
@@ -158,9 +196,7 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
log->PutCString (strm.GetData());
}
- m_inst_emulator_ap->SetInstruction (inst->GetOpcode(),
- inst->GetAddress(),
- exe_ctx.GetTargetPtr());
+ last_condition = m_inst_emulator_ap->GetInstructionCondition();
m_inst_emulator_ap->EvaluateInstruction (eEmulateInstructionOptionIgnoreConditions);
@@ -193,9 +229,6 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
}
}
}
- // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
- // I'll fix that but for now, just clear the list and it will go away nicely.
- disasm_sp->GetInstructionList().Clear();
}
if (log && log->GetVerbose ())
@@ -503,8 +536,7 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
log->PutCString(strm.GetData());
}
- if (!instruction->IsInstructionConditional())
- SetRegisterValue (*reg_info, reg_value);
+ SetRegisterValue (*reg_info, reg_value);
switch (context.type)
{
@@ -519,7 +551,6 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
case EmulateInstruction::eContextTableBranchReadMemory:
case EmulateInstruction::eContextWriteRegisterRandomBits:
case EmulateInstruction::eContextWriteMemoryRandomBits:
- case EmulateInstruction::eContextArithmetic:
case EmulateInstruction::eContextAdvancePC:
case EmulateInstruction::eContextReturnFromException:
case EmulateInstruction::eContextPushRegisterOnStack:
@@ -538,6 +569,22 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
// }
break;
+ case EmulateInstruction::eContextArithmetic:
+ {
+ // If we adjusted the current frame pointer by a constant then adjust the CFA offset
+ // with the same amount.
+ lldb::RegisterKind kind = m_unwind_plan_ptr->GetRegisterKind();
+ if (m_fp_is_cfa && reg_info->kinds[kind] == m_cfa_reg_info.kinds[kind] &&
+ context.info_type == EmulateInstruction::eInfoTypeRegisterPlusOffset &&
+ context.info.RegisterPlusOffset.reg.kinds[kind] == m_cfa_reg_info.kinds[kind])
+ {
+ const int64_t offset = context.info.RegisterPlusOffset.signed_offset;
+ m_curr_row->GetCFAValue().IncOffset(-1 * offset);
+ m_curr_row_modified = true;
+ }
+ }
+ break;
+
case EmulateInstruction::eContextAbsoluteBranchRegister:
case EmulateInstruction::eContextRelativeBranchImmediate:
{
@@ -566,45 +613,42 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
case EmulateInstruction::eContextPopRegisterOffStack:
{
- if (!instruction->IsInstructionConditional())
+ const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
+ const uint32_t generic_regnum = reg_info->kinds[eRegisterKindGeneric];
+ if (reg_num != LLDB_INVALID_REGNUM && generic_regnum != LLDB_REGNUM_GENERIC_SP)
{
- const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
- const uint32_t generic_regnum = reg_info->kinds[eRegisterKindGeneric];
- if (reg_num != LLDB_INVALID_REGNUM && generic_regnum != LLDB_REGNUM_GENERIC_SP)
+ switch (context.info_type)
{
- switch (context.info_type)
- {
- case EmulateInstruction::eInfoTypeAddress:
- if (m_pushed_regs.find(reg_num) != m_pushed_regs.end() &&
- context.info.address == m_pushed_regs[reg_num])
- {
- m_curr_row->SetRegisterLocationToSame(reg_num,
- false /*must_replace*/);
- m_curr_row_modified = true;
- }
- break;
- case EmulateInstruction::eInfoTypeISA:
- assert((generic_regnum == LLDB_REGNUM_GENERIC_PC ||
- generic_regnum == LLDB_REGNUM_GENERIC_FLAGS) &&
- "eInfoTypeISA used for poping a register other the the PC/FLAGS");
- if (generic_regnum != LLDB_REGNUM_GENERIC_FLAGS)
- {
- m_curr_row->SetRegisterLocationToSame(reg_num,
- false /*must_replace*/);
- m_curr_row_modified = true;
- }
- break;
- default:
- assert(false && "unhandled case, add code to handle this!");
- break;
- }
+ case EmulateInstruction::eInfoTypeAddress:
+ if (m_pushed_regs.find(reg_num) != m_pushed_regs.end() &&
+ context.info.address == m_pushed_regs[reg_num])
+ {
+ m_curr_row->SetRegisterLocationToSame(reg_num,
+ false /*must_replace*/);
+ m_curr_row_modified = true;
+ }
+ break;
+ case EmulateInstruction::eInfoTypeISA:
+ assert((generic_regnum == LLDB_REGNUM_GENERIC_PC ||
+ generic_regnum == LLDB_REGNUM_GENERIC_FLAGS) &&
+ "eInfoTypeISA used for poping a register other the the PC/FLAGS");
+ if (generic_regnum != LLDB_REGNUM_GENERIC_FLAGS)
+ {
+ m_curr_row->SetRegisterLocationToSame(reg_num,
+ false /*must_replace*/);
+ m_curr_row_modified = true;
+ }
+ break;
+ default:
+ assert(false && "unhandled case, add code to handle this!");
+ break;
}
}
}
break;
case EmulateInstruction::eContextSetFramePointer:
- if (!m_fp_is_cfa && !instruction->IsInstructionConditional())
+ if (!m_fp_is_cfa)
{
m_fp_is_cfa = true;
m_cfa_reg_info = *reg_info;
@@ -619,7 +663,7 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
case EmulateInstruction::eContextAdjustStackPointer:
// If we have created a frame using the frame pointer, don't follow
// subsequent adjustments to the stack pointer.
- if (!m_fp_is_cfa && !instruction->IsInstructionConditional())
+ if (!m_fp_is_cfa)
{
m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(
m_curr_row->GetCFAValue().GetRegisterNumber(),
diff --git a/source/Plugins/UnwindAssembly/x86/Makefile b/source/Plugins/UnwindAssembly/x86/Makefile
deleted file mode 100644
index 24419c044f04..000000000000
--- a/source/Plugins/UnwindAssembly/x86/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##==-- source/Plugins/UnwindAssembly/x86/Makefile ----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginUnwindAssemblyX86
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Symbol/ArmUnwindInfo.cpp b/source/Symbol/ArmUnwindInfo.cpp
index 0d3e974bebbe..95207cbe320d 100644
--- a/source/Symbol/ArmUnwindInfo.cpp
+++ b/source/Symbol/ArmUnwindInfo.cpp
@@ -103,7 +103,7 @@ ArmUnwindInfo::GetULEB128(const uint32_t* data, uint16_t& offset, uint16_t max_o
while (offset < max_offset)
{
uint8_t byte = GetByteAtOffset(data, offset++);
- result |= (byte & 0x7f) << shift;
+ result |= (uint64_t)(byte & 0x7f) << shift;
if ((byte & 0x80) == 0)
break;
shift += 7;
diff --git a/source/Symbol/Block.cpp b/source/Symbol/Block.cpp
index dfe9217362bd..9d50c5cb7c9a 100644
--- a/source/Symbol/Block.cpp
+++ b/source/Symbol/Block.cpp
@@ -486,16 +486,24 @@ uint32_t
Block::AppendBlockVariables (bool can_create,
bool get_child_block_variables,
bool stop_if_child_block_is_inlined_function,
+ const std::function<bool(Variable*)>& filter,
VariableList *variable_list)
{
uint32_t num_variables_added = 0;
VariableList *block_var_list = GetBlockVariableList (can_create).get();
if (block_var_list)
{
- num_variables_added += block_var_list->GetSize();
- variable_list->AddVariables (block_var_list);
+ for (size_t i = 0; i < block_var_list->GetSize(); ++i)
+ {
+ VariableSP variable = block_var_list->GetVariableAtIndex(i);
+ if (filter(variable.get()))
+ {
+ num_variables_added++;
+ variable_list->AddVariable(variable);
+ }
+ }
}
-
+
if (get_child_block_variables)
{
collection::const_iterator pos, end = m_children.end();
@@ -508,6 +516,7 @@ Block::AppendBlockVariables (bool can_create,
num_variables_added += child_block->AppendBlockVariables (can_create,
get_child_block_variables,
stop_if_child_block_is_inlined_function,
+ filter,
variable_list);
}
}
@@ -521,6 +530,7 @@ Block::AppendVariables
bool can_create,
bool get_parent_variables,
bool stop_if_block_is_inlined_function,
+ const std::function<bool(Variable*)>& filter,
VariableList *variable_list
)
{
@@ -528,12 +538,19 @@ Block::AppendVariables
VariableListSP variable_list_sp(GetBlockVariableList(can_create));
bool is_inlined_function = GetInlinedFunctionInfo() != nullptr;
- if (variable_list_sp.get())
+ if (variable_list_sp)
{
- num_variables_added = variable_list_sp->GetSize();
- variable_list->AddVariables(variable_list_sp.get());
+ for (size_t i = 0; i < variable_list_sp->GetSize(); ++i)
+ {
+ VariableSP variable = variable_list_sp->GetVariableAtIndex(i);
+ if (filter(variable.get()))
+ {
+ num_variables_added++;
+ variable_list->AddVariable(variable);
+ }
+ }
}
-
+
if (get_parent_variables)
{
if (stop_if_block_is_inlined_function && is_inlined_function)
@@ -541,7 +558,11 @@ Block::AppendVariables
Block* parent_block = GetParent();
if (parent_block)
- num_variables_added += parent_block->AppendVariables (can_create, get_parent_variables, stop_if_block_is_inlined_function, variable_list);
+ num_variables_added += parent_block->AppendVariables(can_create,
+ get_parent_variables,
+ stop_if_block_is_inlined_function,
+ filter,
+ variable_list);
}
return num_variables_added;
}
diff --git a/source/Symbol/CMakeLists.txt b/source/Symbol/CMakeLists.txt
index 6372fffde1f1..320a780dc98e 100644
--- a/source/Symbol/CMakeLists.txt
+++ b/source/Symbol/CMakeLists.txt
@@ -5,6 +5,7 @@ add_lldb_library(lldbSymbol
ClangASTImporter.cpp
ClangExternalASTSourceCallbacks.cpp
ClangExternalASTSourceCommon.cpp
+ ClangUtil.cpp
CompilerDecl.cpp
CompilerDeclContext.cpp
CompilerType.cpp
@@ -16,6 +17,7 @@ add_lldb_library(lldbSymbol
Function.cpp
FuncUnwinders.cpp
GoASTContext.cpp
+ JavaASTContext.cpp
LineEntry.cpp
LineTable.cpp
ObjectFile.cpp
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index 621bd1615f80..02882ef2ef4d 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -63,21 +63,24 @@
#include "llvm/Support/Signals.h"
+#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
+#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Flags.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Core/UniqueCStringMap.h"
-#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
-#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
-#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/VerifyDecl.h"
@@ -86,8 +89,10 @@
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
+#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
#include <stdio.h>
@@ -105,7 +110,10 @@ namespace
return language == eLanguageTypeUnknown || // Clang is the default type system
Language::LanguageIsC (language) ||
Language::LanguageIsCPlusPlus (language) ||
- Language::LanguageIsObjC (language);
+ Language::LanguageIsObjC (language) ||
+ // Use Clang for Rust until there is a proper language plugin for it
+ language == eLanguageTypeRust ||
+ language == eLanguageTypeExtRenderScript;
}
}
@@ -332,22 +340,7 @@ ClangASTContext::ClangASTContext (const char *target_triple) :
//----------------------------------------------------------------------
ClangASTContext::~ClangASTContext()
{
- if (m_ast_ap.get())
- {
- GetASTMap().Erase(m_ast_ap.get());
- if (!m_ast_owned)
- m_ast_ap.release();
- }
-
- m_builtins_ap.reset();
- m_selector_table_ap.reset();
- m_identifier_table_ap.reset();
- m_target_info_ap.reset();
- m_target_options_rp.reset();
- m_diagnostics_engine_ap.reset();
- m_source_manager_ap.reset();
- m_language_options_ap.reset();
- m_ast_ap.reset();
+ Finalize();
}
ConstString
@@ -471,6 +464,27 @@ ClangASTContext::Terminate()
PluginManager::UnregisterPlugin (CreateInstance);
}
+void
+ClangASTContext::Finalize()
+{
+ if (m_ast_ap.get())
+ {
+ GetASTMap().Erase(m_ast_ap.get());
+ if (!m_ast_owned)
+ m_ast_ap.release();
+ }
+
+ m_builtins_ap.reset();
+ m_selector_table_ap.reset();
+ m_identifier_table_ap.reset();
+ m_target_info_ap.reset();
+ m_target_options_rp.reset();
+ m_diagnostics_engine_ap.reset();
+ m_source_manager_ap.reset();
+ m_language_options_ap.reset();
+ m_ast_ap.reset();
+ m_scratch_ast_source_ap.reset();
+}
void
ClangASTContext::Clear()
@@ -678,8 +692,9 @@ public:
{
m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
}
-
- void HandleDiagnostic (DiagnosticsEngine::Level DiagLevel, const Diagnostic &info)
+
+ void
+ HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info)
{
if (m_log)
{
@@ -707,11 +722,11 @@ ClangASTContext::getDiagnosticConsumer()
return m_diagnostic_consumer_ap.get();
}
-std::shared_ptr<TargetOptions> &
+std::shared_ptr<clang::TargetOptions> &
ClangASTContext::getTargetOptions() {
if (m_target_options_rp.get() == nullptr && !m_target_triple.empty())
{
- m_target_options_rp = std::make_shared<TargetOptions>();
+ m_target_options_rp = std::make_shared<clang::TargetOptions>();
if (m_target_options_rp.get() != nullptr)
m_target_options_rp->Triple = m_target_triple;
}
@@ -773,8 +788,8 @@ ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding
break;
case eEncodingSint:
- if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
- return CompilerType (ast, ast->CharTy);
+ if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
+ return CompilerType (ast, ast->SignedCharTy);
if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
return CompilerType (ast, ast->ShortTy);
if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
@@ -901,113 +916,12 @@ ClangASTContext::GetBasicType (lldb::BasicType basic_type)
CompilerType
ClangASTContext::GetBasicType (ASTContext *ast, lldb::BasicType basic_type)
{
- if (ast)
- {
- lldb::opaque_compiler_type_t clang_type = nullptr;
-
- switch (basic_type)
- {
- case eBasicTypeInvalid:
- case eBasicTypeOther:
- break;
- case eBasicTypeVoid:
- clang_type = ast->VoidTy.getAsOpaquePtr();
- break;
- case eBasicTypeChar:
- clang_type = ast->CharTy.getAsOpaquePtr();
- break;
- case eBasicTypeSignedChar:
- clang_type = ast->SignedCharTy.getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedChar:
- clang_type = ast->UnsignedCharTy.getAsOpaquePtr();
- break;
- case eBasicTypeWChar:
- clang_type = ast->getWCharType().getAsOpaquePtr();
- break;
- case eBasicTypeSignedWChar:
- clang_type = ast->getSignedWCharType().getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedWChar:
- clang_type = ast->getUnsignedWCharType().getAsOpaquePtr();
- break;
- case eBasicTypeChar16:
- clang_type = ast->Char16Ty.getAsOpaquePtr();
- break;
- case eBasicTypeChar32:
- clang_type = ast->Char32Ty.getAsOpaquePtr();
- break;
- case eBasicTypeShort:
- clang_type = ast->ShortTy.getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedShort:
- clang_type = ast->UnsignedShortTy.getAsOpaquePtr();
- break;
- case eBasicTypeInt:
- clang_type = ast->IntTy.getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedInt:
- clang_type = ast->UnsignedIntTy.getAsOpaquePtr();
- break;
- case eBasicTypeLong:
- clang_type = ast->LongTy.getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedLong:
- clang_type = ast->UnsignedLongTy.getAsOpaquePtr();
- break;
- case eBasicTypeLongLong:
- clang_type = ast->LongLongTy.getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedLongLong:
- clang_type = ast->UnsignedLongLongTy.getAsOpaquePtr();
- break;
- case eBasicTypeInt128:
- clang_type = ast->Int128Ty.getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedInt128:
- clang_type = ast->UnsignedInt128Ty.getAsOpaquePtr();
- break;
- case eBasicTypeBool:
- clang_type = ast->BoolTy.getAsOpaquePtr();
- break;
- case eBasicTypeHalf:
- clang_type = ast->HalfTy.getAsOpaquePtr();
- break;
- case eBasicTypeFloat:
- clang_type = ast->FloatTy.getAsOpaquePtr();
- break;
- case eBasicTypeDouble:
- clang_type = ast->DoubleTy.getAsOpaquePtr();
- break;
- case eBasicTypeLongDouble:
- clang_type = ast->LongDoubleTy.getAsOpaquePtr();
- break;
- case eBasicTypeFloatComplex:
- clang_type = ast->FloatComplexTy.getAsOpaquePtr();
- break;
- case eBasicTypeDoubleComplex:
- clang_type = ast->DoubleComplexTy.getAsOpaquePtr();
- break;
- case eBasicTypeLongDoubleComplex:
- clang_type = ast->LongDoubleComplexTy.getAsOpaquePtr();
- break;
- case eBasicTypeObjCID:
- clang_type = ast->getObjCIdType().getAsOpaquePtr();
- break;
- case eBasicTypeObjCClass:
- clang_type = ast->getObjCClassType().getAsOpaquePtr();
- break;
- case eBasicTypeObjCSel:
- clang_type = ast->getObjCSelType().getAsOpaquePtr();
- break;
- case eBasicTypeNullPtr:
- clang_type = ast->NullPtrTy.getAsOpaquePtr();
- break;
- }
-
- if (clang_type)
- return CompilerType (GetASTContext(ast), clang_type);
- }
+ if (!ast)
+ return CompilerType();
+ lldb::opaque_compiler_type_t clang_type = GetOpaqueCompilerType(ast, basic_type);
+
+ if (clang_type)
+ return CompilerType(GetASTContext(ast), clang_type);
return CompilerType();
}
@@ -1049,7 +963,7 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name
if (::strstr(type_name, "complex"))
{
CompilerType complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
- return CompilerType (ast, ast->getComplexType (GetQualType(complex_int_clang_type)));
+ return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(complex_int_clang_type)));
}
}
break;
@@ -1064,7 +978,7 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name
else
{
CompilerType complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
- return CompilerType (ast, ast->getComplexType (GetQualType(complex_float_clang_type)));
+ return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(complex_float_clang_type)));
}
break;
@@ -1294,9 +1208,9 @@ ClangASTContext::AreTypesSame (CompilerType type1,
if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
return true;
- QualType type1_qual = GetQualType(type1);
- QualType type2_qual = GetQualType(type2);
-
+ QualType type1_qual = ClangUtil::GetQualType(type1);
+ QualType type2_qual = ClangUtil::GetQualType(type2);
+
if (ignore_qualifiers)
{
type1_qual = type1_qual.getUnqualifiedType();
@@ -1488,9 +1402,7 @@ ClangASTContext::CreateFunctionTemplateSpecializationInfo (FunctionDecl *func_de
clang::FunctionTemplateDecl *func_tmpl_decl,
const TemplateParameterInfos &infos)
{
- TemplateArgumentList template_args (TemplateArgumentList::OnStack,
- infos.args.data(),
- infos.args.size());
+ TemplateArgumentList template_args (TemplateArgumentList::OnStack, infos.args);
func_decl->setFunctionTemplateSpecialization (func_tmpl_decl,
&template_args,
@@ -1588,8 +1500,7 @@ ClangASTContext::CreateClassTemplateSpecializationDecl (DeclContext *decl_ctx,
SourceLocation(),
SourceLocation(),
class_template_decl,
- &template_param_infos.args.front(),
- template_param_infos.args.size(),
+ template_param_infos.args,
nullptr);
class_template_specialization_decl->setSpecializationKind(TSK_ExplicitSpecialization);
@@ -1652,25 +1563,14 @@ ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, ui
clang::AccessSpecifier
ClangASTContext::UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs)
{
- clang::AccessSpecifier ret = lhs;
-
// Make the access equal to the stricter of the field and the nested field's access
- switch (ret)
- {
- case clang::AS_none:
- break;
- case clang::AS_private:
- break;
- case clang::AS_protected:
- if (rhs == AS_private)
- ret = AS_private;
- break;
- case clang::AS_public:
- ret = rhs;
- break;
- }
-
- return ret;
+ if (lhs == AS_none || rhs == AS_none)
+ return AS_none;
+ if (lhs == AS_private || rhs == AS_private)
+ return AS_private;
+ if (lhs == AS_protected || rhs == AS_protected)
+ return AS_protected;
+ return AS_public;
}
bool
@@ -1884,6 +1784,17 @@ ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *d
return namespace_decl;
}
+NamespaceDecl *
+ClangASTContext::GetUniqueNamespaceDeclaration (clang::ASTContext *ast,
+ const char *name,
+ clang::DeclContext *decl_ctx)
+{
+ ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(ast);
+ if (ast_ctx == nullptr)
+ return nullptr;
+
+ return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx);
+}
clang::BlockDecl *
ClangASTContext::CreateBlockDeclaration (clang::DeclContext *ctx)
@@ -1977,6 +1888,78 @@ ClangASTContext::CreateVariableDeclaration (clang::DeclContext *decl_context, co
return nullptr;
}
+lldb::opaque_compiler_type_t
+ClangASTContext::GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type)
+{
+ switch (basic_type)
+ {
+ case eBasicTypeVoid:
+ return ast->VoidTy.getAsOpaquePtr();
+ case eBasicTypeChar:
+ return ast->CharTy.getAsOpaquePtr();
+ case eBasicTypeSignedChar:
+ return ast->SignedCharTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedChar:
+ return ast->UnsignedCharTy.getAsOpaquePtr();
+ case eBasicTypeWChar:
+ return ast->getWCharType().getAsOpaquePtr();
+ case eBasicTypeSignedWChar:
+ return ast->getSignedWCharType().getAsOpaquePtr();
+ case eBasicTypeUnsignedWChar:
+ return ast->getUnsignedWCharType().getAsOpaquePtr();
+ case eBasicTypeChar16:
+ return ast->Char16Ty.getAsOpaquePtr();
+ case eBasicTypeChar32:
+ return ast->Char32Ty.getAsOpaquePtr();
+ case eBasicTypeShort:
+ return ast->ShortTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedShort:
+ return ast->UnsignedShortTy.getAsOpaquePtr();
+ case eBasicTypeInt:
+ return ast->IntTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedInt:
+ return ast->UnsignedIntTy.getAsOpaquePtr();
+ case eBasicTypeLong:
+ return ast->LongTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedLong:
+ return ast->UnsignedLongTy.getAsOpaquePtr();
+ case eBasicTypeLongLong:
+ return ast->LongLongTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedLongLong:
+ return ast->UnsignedLongLongTy.getAsOpaquePtr();
+ case eBasicTypeInt128:
+ return ast->Int128Ty.getAsOpaquePtr();
+ case eBasicTypeUnsignedInt128:
+ return ast->UnsignedInt128Ty.getAsOpaquePtr();
+ case eBasicTypeBool:
+ return ast->BoolTy.getAsOpaquePtr();
+ case eBasicTypeHalf:
+ return ast->HalfTy.getAsOpaquePtr();
+ case eBasicTypeFloat:
+ return ast->FloatTy.getAsOpaquePtr();
+ case eBasicTypeDouble:
+ return ast->DoubleTy.getAsOpaquePtr();
+ case eBasicTypeLongDouble:
+ return ast->LongDoubleTy.getAsOpaquePtr();
+ case eBasicTypeFloatComplex:
+ return ast->FloatComplexTy.getAsOpaquePtr();
+ case eBasicTypeDoubleComplex:
+ return ast->DoubleComplexTy.getAsOpaquePtr();
+ case eBasicTypeLongDoubleComplex:
+ return ast->LongDoubleComplexTy.getAsOpaquePtr();
+ case eBasicTypeObjCID:
+ return ast->getObjCIdType().getAsOpaquePtr();
+ case eBasicTypeObjCClass:
+ return ast->getObjCClassType().getAsOpaquePtr();
+ case eBasicTypeObjCSel:
+ return ast->getObjCSelType().getAsOpaquePtr();
+ case eBasicTypeNullPtr:
+ return ast->NullPtrTy.getAsOpaquePtr();
+ default:
+ return nullptr;
+ }
+}
+
#pragma mark Function Types
FunctionDecl *
@@ -1997,31 +1980,17 @@ ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx,
if (name && name[0])
{
- func_decl = FunctionDecl::Create (*ast,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- DeclarationName (&ast->Idents.get(name)),
- GetQualType(function_clang_type),
- nullptr,
- (clang::StorageClass)storage,
- is_inline,
- hasWrittenPrototype,
- isConstexprSpecified);
+ func_decl = FunctionDecl::Create(
+ *ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(&ast->Idents.get(name)),
+ ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, is_inline,
+ hasWrittenPrototype, isConstexprSpecified);
}
else
{
- func_decl = FunctionDecl::Create (*ast,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- DeclarationName (),
- GetQualType(function_clang_type),
- nullptr,
- (clang::StorageClass)storage,
- is_inline,
- hasWrittenPrototype,
- isConstexprSpecified);
+ func_decl =
+ FunctionDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(),
+ ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage,
+ is_inline, hasWrittenPrototype, isConstexprSpecified);
}
if (func_decl)
decl_ctx->addDecl (func_decl);
@@ -2041,10 +2010,33 @@ ClangASTContext::CreateFunctionType (ASTContext *ast,
bool is_variadic,
unsigned type_quals)
{
- assert (ast != nullptr);
+ if (ast == nullptr)
+ return CompilerType(); // invalid AST
+
+ if (!result_type || !ClangUtil::IsClangType(result_type))
+ return CompilerType(); // invalid return type
+
std::vector<QualType> qual_type_args;
+ if (num_args > 0 && args == nullptr)
+ return CompilerType(); // invalid argument array passed in
+
+ // Verify that all arguments are valid and the right type
for (unsigned i=0; i<num_args; ++i)
- qual_type_args.push_back (GetQualType(args[i]));
+ {
+ if (args[i])
+ {
+ // Make sure we have a clang type in args[i] and not a type from another
+ // language whose name might match
+ const bool is_clang_type = ClangUtil::IsClangType(args[i]);
+ lldbassert(is_clang_type);
+ if (is_clang_type)
+ qual_type_args.push_back(ClangUtil::GetQualType(args[i]));
+ else
+ return CompilerType(); // invalid argument type (must be a clang type)
+ }
+ else
+ return CompilerType(); // invalid argument type (empty)
+ }
// TODO: Detect calling convention in DWARF?
FunctionProtoType::ExtProtoInfo proto_info;
@@ -2053,9 +2045,7 @@ ClangASTContext::CreateFunctionType (ASTContext *ast,
proto_info.TypeQuals = type_quals;
proto_info.RefQualifier = RQ_None;
- return CompilerType (ast, ast->getFunctionType (GetQualType(result_type),
- qual_type_args,
- proto_info));
+ return CompilerType(ast, ast->getFunctionType(ClangUtil::GetQualType(result_type), qual_type_args, proto_info));
}
ParmVarDecl *
@@ -2063,15 +2053,9 @@ ClangASTContext::CreateParameterDeclaration (const char *name, const CompilerTyp
{
ASTContext *ast = getASTContext();
assert (ast != nullptr);
- return ParmVarDecl::Create(*ast,
- ast->getTranslationUnitDecl(),
- SourceLocation(),
- SourceLocation(),
- name && name[0] ? &ast->Idents.get(name) : nullptr,
- GetQualType(param_type),
- nullptr,
- (clang::StorageClass)storage,
- nullptr);
+ return ParmVarDecl::Create(*ast, ast->getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
+ name && name[0] ? &ast->Idents.get(name) : nullptr, ClangUtil::GetQualType(param_type),
+ nullptr, (clang::StorageClass)storage, nullptr);
}
void
@@ -2081,6 +2065,13 @@ ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl
function_decl->setParams (ArrayRef<ParmVarDecl*>(params, num_params));
}
+CompilerType
+ClangASTContext::CreateBlockPointerType (const CompilerType &function_type)
+{
+ QualType block_type = m_ast_ap->getBlockPointerType(clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType()));
+
+ return CompilerType (this, block_type.getAsOpaquePtr());
+}
#pragma mark Array Types
@@ -2096,7 +2087,7 @@ ClangASTContext::CreateArrayType (const CompilerType &element_type,
if (is_vector)
{
- return CompilerType (ast, ast->getExtVectorType(GetQualType(element_type), element_count));
+ return CompilerType(ast, ast->getExtVectorType(ClangUtil::GetQualType(element_type), element_count));
}
else
{
@@ -2104,16 +2095,13 @@ ClangASTContext::CreateArrayType (const CompilerType &element_type,
llvm::APInt ap_element_count (64, element_count);
if (element_count == 0)
{
- return CompilerType (ast, ast->getIncompleteArrayType (GetQualType(element_type),
- ArrayType::Normal,
- 0));
+ return CompilerType(ast, ast->getIncompleteArrayType(ClangUtil::GetQualType(element_type),
+ clang::ArrayType::Normal, 0));
}
else
{
- return CompilerType (ast, ast->getConstantArrayType (GetQualType(element_type),
- ap_element_count,
- ArrayType::Normal,
- 0));
+ return CompilerType(ast, ast->getConstantArrayType(ClangUtil::GetQualType(element_type),
+ ap_element_count, clang::ArrayType::Normal, 0));
}
}
}
@@ -2121,13 +2109,17 @@ ClangASTContext::CreateArrayType (const CompilerType &element_type,
}
CompilerType
-ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name,
- const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
- bool packed)
+ClangASTContext::CreateStructForIdentifier (const ConstString &type_name,
+ const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
+ bool packed)
{
CompilerType type;
- if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
+ if (!type_name.IsEmpty() && (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
+ {
+ lldbassert("Trying to create a type for an existing name");
return type;
+ }
+
type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC);
StartTagDeclarationDefinition(type);
for (const auto& field : type_fields)
@@ -2138,6 +2130,20 @@ ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name,
return type;
}
+CompilerType
+ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name,
+ const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
+ bool packed)
+{
+ CompilerType type;
+ if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
+ return type;
+
+ return CreateStructForIdentifier (type_name,
+ type_fields,
+ packed);
+}
+
#pragma mark Enumeration Types
CompilerType
@@ -2171,8 +2177,8 @@ ClangASTContext::CreateEnumerationType
if (enum_decl)
{
// TODO: check if we should be setting the promotion type too?
- enum_decl->setIntegerType(GetQualType(integer_clang_type));
-
+ enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));
+
enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
return CompilerType (ast, ast->getTagDeclType(enum_decl));
@@ -2565,7 +2571,7 @@ ClangASTContext::SetDefaultAccessForRecordFields (clang::RecordDecl* record_decl
clang::DeclContext *
ClangASTContext::GetDeclContextForType (const CompilerType& type)
{
- return GetDeclContextForType(GetQualType(type));
+ return GetDeclContextForType(ClangUtil::GetQualType(type));
}
clang::DeclContext *
@@ -2632,8 +2638,8 @@ GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool all
external_ast_source->CompleteType(cxx_record_decl);
if (cxx_record_decl->isCompleteDefinition())
{
- cxx_record_decl->setHasLoadedFieldsFromExternalStorage (true);
cxx_record_decl->field_begin();
+ cxx_record_decl->setHasLoadedFieldsFromExternalStorage (true);
}
}
}
@@ -3082,9 +3088,11 @@ ClangASTContext::IsHomogeneousAggregate (lldb::opaque_compiler_type_t type, Comp
bool is_hva = false;
bool is_hfa = false;
clang::QualType base_qual_type;
+ uint64_t base_bitwidth = 0;
for (field_pos = record_decl->field_begin(); field_pos != field_end; ++field_pos)
{
clang::QualType field_qual_type = field_pos->getType();
+ uint64_t field_bitwidth = getASTContext()->getTypeSize (qual_type);
if (field_qual_type->isFloatingType())
{
if (field_qual_type->isComplexType())
@@ -3105,22 +3113,21 @@ ClangASTContext::IsHomogeneousAggregate (lldb::opaque_compiler_type_t type, Comp
}
else if (field_qual_type->isVectorType() || field_qual_type->isExtVectorType())
{
- const clang::VectorType *array = field_qual_type.getTypePtr()->getAs<clang::VectorType>();
- if (array && array->getNumElements() <= 4)
+ if (num_fields == 0)
{
- if (num_fields == 0)
- base_qual_type = array->getElementType();
- else
- {
- if (is_hfa)
- return 0;
- is_hva = true;
- if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
- return 0;
- }
+ base_qual_type = field_qual_type;
+ base_bitwidth = field_bitwidth;
}
else
- return 0;
+ {
+ if (is_hfa)
+ return 0;
+ is_hva = true;
+ if (base_bitwidth != field_bitwidth)
+ return 0;
+ if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
+ return 0;
+ }
}
else
return 0;
@@ -3166,7 +3173,7 @@ ClangASTContext::GetFunctionArgumentAtIndex (lldb::opaque_compiler_type_t type,
{
if (type)
{
- clang::QualType qual_type (GetCanonicalQualType(type));
+ clang::QualType qual_type (GetQualType(type));
const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
if (func)
{
@@ -3216,6 +3223,52 @@ ClangASTContext::IsFunctionPointerType (lldb::opaque_compiler_type_t type)
}
bool
+ClangASTContext::IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr)
+{
+ if (type)
+ {
+ clang::QualType qual_type (GetCanonicalQualType(type));
+
+ if (qual_type->isBlockPointerType())
+ {
+ if (function_pointer_type_ptr)
+ {
+ const clang::BlockPointerType *block_pointer_type = qual_type->getAs<clang::BlockPointerType>();
+ QualType pointee_type = block_pointer_type->getPointeeType();
+ QualType function_pointer_type = m_ast_ap->getPointerType(pointee_type);
+ *function_pointer_type_ptr = CompilerType (getASTContext(), function_pointer_type);
+ }
+ return true;
+ }
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ default:
+ break;
+ case clang::Type::Typedef:
+ return IsBlockPointerType (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), function_pointer_type_ptr);
+ case clang::Type::Auto:
+ return IsBlockPointerType (llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), function_pointer_type_ptr);
+ case clang::Type::Elaborated:
+ return IsBlockPointerType (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), function_pointer_type_ptr);
+ case clang::Type::Paren:
+ return IsBlockPointerType (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), function_pointer_type_ptr);
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ {
+ const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ if (reference_type)
+ return IsBlockPointerType(reference_type->getPointeeType().getAsOpaquePtr(), function_pointer_type_ptr);
+ }
+ break;
+ }
+ }
+ return false;
+}
+
+bool
ClangASTContext::IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed)
{
if (!type)
@@ -3237,6 +3290,23 @@ ClangASTContext::IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_sign
}
bool
+ClangASTContext::IsEnumerationType(lldb::opaque_compiler_type_t type, bool &is_signed)
+{
+ if (type)
+ {
+ const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type)->getCanonicalTypeInternal());
+
+ if (enum_type)
+ {
+ IsIntegerType(enum_type->getDecl()->getIntegerType().getAsOpaquePtr(), is_signed);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
ClangASTContext::IsPointerType (lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
{
if (type)
@@ -3466,8 +3536,8 @@ ClangASTContext::IsObjCClassType (const CompilerType& type)
{
if (type)
{
- clang::QualType qual_type (GetCanonicalQualType(type));
-
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+
const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
if (obj_pointer_type)
@@ -3479,13 +3549,33 @@ ClangASTContext::IsObjCClassType (const CompilerType& type)
bool
ClangASTContext::IsObjCObjectOrInterfaceType (const CompilerType& type)
{
- if (IsClangType(type))
- return GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
+ if (ClangUtil::IsClangType(type))
+ return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
return false;
}
bool
-ClangASTContext::IsPolymorphicClass (lldb::opaque_compiler_type_t type)
+ClangASTContext::IsClassType(lldb::opaque_compiler_type_t type)
+{
+ if (!type)
+ return false;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ return (type_class == clang::Type::Record);
+}
+
+bool
+ClangASTContext::IsEnumType(lldb::opaque_compiler_type_t type)
+{
+ if (!type)
+ return false;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ return (type_class == clang::Type::Enum);
+}
+
+bool
+ClangASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type)
{
if (type)
{
@@ -3539,6 +3629,14 @@ ClangASTContext::IsPossibleDynamicType (lldb::opaque_compiler_type_t type, Compi
case clang::Type::ObjCObjectPointer:
if (check_objc)
{
+ if (auto objc_pointee_type = qual_type->getPointeeType().getTypePtrOrNull())
+ {
+ if (auto objc_object_type = llvm::dyn_cast_or_null<clang::ObjCObjectType>(objc_pointee_type))
+ {
+ if (objc_object_type->isObjCClass())
+ return false;
+ }
+ }
if (dynamic_pointee_type)
dynamic_pointee_type->SetCompilerType(getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
return true;
@@ -3696,7 +3794,7 @@ ClangASTContext::GetCXXClassName (const CompilerType& type, std::string &class_n
{
if (type)
{
- clang::QualType qual_type (GetCanonicalQualType(type));
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
if (!qual_type.isNull())
{
clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
@@ -3717,8 +3815,8 @@ ClangASTContext::IsCXXClassType (const CompilerType& type)
{
if (!type)
return false;
-
- clang::QualType qual_type (GetCanonicalQualType(type));
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
if (!qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr)
return true;
return false;
@@ -3742,7 +3840,7 @@ ClangASTContext::IsObjCObjectPointerType (const CompilerType& type, CompilerType
if (!type)
return false;
- clang::QualType qual_type (GetCanonicalQualType(type));
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
if (!qual_type.isNull() && qual_type->isObjCObjectPointerType())
{
@@ -3770,9 +3868,9 @@ ClangASTContext::GetObjCClassName (const CompilerType& type, std::string &class_
{
if (!type)
return false;
-
- clang::QualType qual_type (GetCanonicalQualType(type));
-
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+
const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
if (object_type)
{
@@ -3809,7 +3907,6 @@ ClangASTContext::GetTypeName (lldb::opaque_compiler_type_t type)
clang::PrintingPolicy printing_policy (getASTContext()->getPrintingPolicy());
clang::QualType qual_type(GetQualType(type));
printing_policy.SuppressTagKeyword = true;
- printing_policy.LangOpts.WChar = true;
const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
if (typedef_type)
{
@@ -4491,7 +4588,7 @@ ClangASTContext::CreateTypedefType (const CompilerType& type,
if (!ast)
return CompilerType();
clang::ASTContext* clang_ast = ast->getASTContext();
- clang::QualType qual_type (GetQualType(type));
+ clang::QualType qual_type(ClangUtil::GetQualType(type));
clang::DeclContext *decl_ctx = ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
if (decl_ctx == nullptr)
@@ -4621,6 +4718,20 @@ ClangASTContext::CreateTypedef (lldb::opaque_compiler_type_t type, const char *t
&clang_ast->Idents.get(typedef_name),
clang_ast->getTrivialTypeSourceInfo(qual_type));
+ clang::TagDecl *tdecl = nullptr;
+ if (!qual_type.isNull())
+ {
+ if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>())
+ tdecl = rt->getDecl();
+ if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
+ tdecl = et->getDecl();
+ }
+
+ // Check whether this declaration is an anonymous struct, union, or enum, hidden behind a typedef. If so, we
+ // try to check whether we have a typedef tag to attach to the original record declaration
+ if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl())
+ tdecl->setTypedefNameForAnonDecl(decl);
+
decl->setAccess(clang::AS_public); // TODO respect proper access specifier
// Get a uniqued clang::QualType for the typedef decl type
@@ -4643,18 +4754,6 @@ ClangASTContext::GetTypedefedType (lldb::opaque_compiler_type_t type)
return CompilerType();
}
-CompilerType
-ClangASTContext::RemoveFastQualifiers (const CompilerType& type)
-{
- if (IsClangType(type))
- {
- clang::QualType qual_type(GetQualType(type));
- qual_type.getQualifiers().removeFastQualifiers();
- return CompilerType (type.GetTypeSystem(), qual_type.getAsOpaquePtr());
- }
- return type;
-}
-
//----------------------------------------------------------------------
// Create related types using the current type's AST
@@ -4675,8 +4774,16 @@ ClangASTContext::GetBitSize (lldb::opaque_compiler_type_t type, ExecutionContext
if (GetCompleteType (type))
{
clang::QualType qual_type(GetCanonicalQualType(type));
- switch (qual_type->getTypeClass())
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
{
+ case clang::Type::Record:
+ if (GetCompleteType(type))
+ return getASTContext()->getTypeSize(qual_type);
+ else
+ return 0;
+ break;
+
case clang::Type::ObjCInterface:
case clang::Type::ObjCObject:
{
@@ -4710,7 +4817,7 @@ ClangASTContext::GetBitSize (lldb::opaque_compiler_type_t type, ExecutionContext
}
}
}
- // fallthrough
+ LLVM_FALLTHROUGH;
default:
const uint32_t bit_size = getASTContext()->getTypeSize (qual_type);
if (bit_size == 0)
@@ -4740,97 +4847,127 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count
{
if (!type)
return lldb::eEncodingInvalid;
-
+
count = 1;
clang::QualType qual_type(GetCanonicalQualType(type));
-
+
switch (qual_type->getTypeClass())
{
case clang::Type::UnaryTransform:
break;
-
+
case clang::Type::FunctionNoProto:
case clang::Type::FunctionProto:
break;
-
+
case clang::Type::IncompleteArray:
case clang::Type::VariableArray:
break;
-
+
case clang::Type::ConstantArray:
break;
-
+
case clang::Type::ExtVector:
case clang::Type::Vector:
// TODO: Set this to more than one???
break;
-
+
case clang::Type::Builtin:
switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
- {
- case clang::BuiltinType::Void:
- break;
-
- case clang::BuiltinType::Bool:
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
- case clang::BuiltinType::Short:
- case clang::BuiltinType::Int:
- case clang::BuiltinType::Long:
- case clang::BuiltinType::LongLong:
- case clang::BuiltinType::Int128: return lldb::eEncodingSint;
-
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U:
- case clang::BuiltinType::UShort:
- case clang::BuiltinType::UInt:
- case clang::BuiltinType::ULong:
- case clang::BuiltinType::ULongLong:
- case clang::BuiltinType::UInt128: return lldb::eEncodingUint;
-
- case clang::BuiltinType::Half:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble: return lldb::eEncodingIEEE754;
-
- case clang::BuiltinType::ObjCClass:
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCSel: return lldb::eEncodingUint;
-
- case clang::BuiltinType::NullPtr: return lldb::eEncodingUint;
-
- case clang::BuiltinType::Kind::ARCUnbridgedCast:
- case clang::BuiltinType::Kind::BoundMember:
- case clang::BuiltinType::Kind::BuiltinFn:
- case clang::BuiltinType::Kind::Dependent:
- case clang::BuiltinType::Kind::OCLClkEvent:
- case clang::BuiltinType::Kind::OCLEvent:
- case clang::BuiltinType::Kind::OCLImage1d:
- case clang::BuiltinType::Kind::OCLImage1dArray:
- case clang::BuiltinType::Kind::OCLImage1dBuffer:
- case clang::BuiltinType::Kind::OCLImage2d:
- case clang::BuiltinType::Kind::OCLImage2dArray:
- case clang::BuiltinType::Kind::OCLImage2dArrayDepth:
- case clang::BuiltinType::Kind::OCLImage2dArrayMSAA:
- case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepth:
- case clang::BuiltinType::Kind::OCLImage2dDepth:
- case clang::BuiltinType::Kind::OCLImage2dMSAA:
- case clang::BuiltinType::Kind::OCLImage2dMSAADepth:
- case clang::BuiltinType::Kind::OCLImage3d:
- case clang::BuiltinType::Kind::OCLQueue:
- case clang::BuiltinType::Kind::OCLNDRange:
- case clang::BuiltinType::Kind::OCLReserveID:
- case clang::BuiltinType::Kind::OCLSampler:
- case clang::BuiltinType::Kind::OMPArraySection:
- case clang::BuiltinType::Kind::Overload:
- case clang::BuiltinType::Kind::PseudoObject:
- case clang::BuiltinType::Kind::UnknownAny:
- break;
- }
+ {
+ case clang::BuiltinType::Void:
+ break;
+
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ return lldb::eEncodingSint;
+
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ return lldb::eEncodingUint;
+
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Float128:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ return lldb::eEncodingIEEE754;
+
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCSel:
+ return lldb::eEncodingUint;
+
+ case clang::BuiltinType::NullPtr:
+ return lldb::eEncodingUint;
+
+ case clang::BuiltinType::Kind::ARCUnbridgedCast:
+ case clang::BuiltinType::Kind::BoundMember:
+ case clang::BuiltinType::Kind::BuiltinFn:
+ case clang::BuiltinType::Kind::Dependent:
+ case clang::BuiltinType::Kind::OCLClkEvent:
+ case clang::BuiltinType::Kind::OCLEvent:
+ case clang::BuiltinType::Kind::OCLImage1dRO:
+ case clang::BuiltinType::Kind::OCLImage1dWO:
+ case clang::BuiltinType::Kind::OCLImage1dRW:
+ case clang::BuiltinType::Kind::OCLImage1dArrayRO:
+ case clang::BuiltinType::Kind::OCLImage1dArrayWO:
+ case clang::BuiltinType::Kind::OCLImage1dArrayRW:
+ case clang::BuiltinType::Kind::OCLImage1dBufferRO:
+ case clang::BuiltinType::Kind::OCLImage1dBufferWO:
+ case clang::BuiltinType::Kind::OCLImage1dBufferRW:
+ case clang::BuiltinType::Kind::OCLImage2dRO:
+ case clang::BuiltinType::Kind::OCLImage2dWO:
+ case clang::BuiltinType::Kind::OCLImage2dRW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayRO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayRW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW:
+ case clang::BuiltinType::Kind::OCLImage2dDepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dDepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dDepthRW:
+ case clang::BuiltinType::Kind::OCLImage2dMSAARO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAAWO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAARW:
+ case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW:
+ case clang::BuiltinType::Kind::OCLImage3dRO:
+ case clang::BuiltinType::Kind::OCLImage3dWO:
+ case clang::BuiltinType::Kind::OCLImage3dRW:
+ case clang::BuiltinType::Kind::OCLQueue:
+ case clang::BuiltinType::Kind::OCLNDRange:
+ case clang::BuiltinType::Kind::OCLReserveID:
+ case clang::BuiltinType::Kind::OCLSampler:
+ case clang::BuiltinType::Kind::OMPArraySection:
+ case clang::BuiltinType::Kind::Overload:
+ case clang::BuiltinType::Kind::PseudoObject:
+ case clang::BuiltinType::Kind::UnknownAny:
+ break;
+ }
break;
// All pointer types are represented as unsigned integer encodings.
// We may nee to add a eEncodingPointer if we ever need to know the
@@ -4857,7 +4994,7 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count
count = 2;
return encoding;
}
-
+
case clang::Type::ObjCInterface: break;
case clang::Type::Record: break;
case clang::Type::Enum: return lldb::eEncodingSint;
@@ -4866,13 +5003,13 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count
case clang::Type::Auto:
return CompilerType(getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()).GetEncoding(count);
-
+
case clang::Type::Elaborated:
return CompilerType(getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetEncoding(count);
-
+
case clang::Type::Paren:
return CompilerType(getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetEncoding(count);
-
+
case clang::Type::DependentSizedArray:
case clang::Type::DependentSizedExtVector:
case clang::Type::UnresolvedUsing:
@@ -4885,7 +5022,7 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count
case clang::Type::DependentTemplateSpecialization:
case clang::Type::PackExpansion:
case clang::Type::ObjCObject:
-
+
case clang::Type::TypeOfExpr:
case clang::Type::TypeOf:
case clang::Type::Decltype:
@@ -4894,7 +5031,7 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count
case clang::Type::Adjusted:
case clang::Type::Pipe:
break;
-
+
// pointer type decayed from an array or function type.
case clang::Type::Decayed:
break;
@@ -5213,7 +5350,7 @@ ClangASTContext::GetNumChildren (lldb::opaque_compiler_type_t type, bool omit_em
CompilerType
ClangASTContext::GetBuiltinTypeByName (const ConstString &name)
{
- return GetBasicType (GetBasicTypeEnumeration (name));
+ return GetBasicType(GetBasicTypeEnumeration(name));
}
lldb::BasicType
@@ -5817,7 +5954,8 @@ ClangASTContext::GetVirtualBaseClassAtIndex (lldb::opaque_compiler_type_t type,
return GetVirtualBaseClassAtIndex (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), idx, bit_offset_ptr);
case clang::Type::Paren:
- return GetVirtualBaseClassAtIndex (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx, bit_offset_ptr);
+ return GetVirtualBaseClassAtIndex(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx,
+ bit_offset_ptr);
default:
break;
@@ -5848,12 +5986,24 @@ ClangASTContext::GetNumPointeeChildren (clang::QualType type)
case clang::BuiltinType::Void:
case clang::BuiltinType::NullPtr:
case clang::BuiltinType::OCLEvent:
- case clang::BuiltinType::OCLImage1d:
- case clang::BuiltinType::OCLImage1dArray:
- case clang::BuiltinType::OCLImage1dBuffer:
- case clang::BuiltinType::OCLImage2d:
- case clang::BuiltinType::OCLImage2dArray:
- case clang::BuiltinType::OCLImage3d:
+ case clang::BuiltinType::OCLImage1dRO:
+ case clang::BuiltinType::OCLImage1dWO:
+ case clang::BuiltinType::OCLImage1dRW:
+ case clang::BuiltinType::OCLImage1dArrayRO:
+ case clang::BuiltinType::OCLImage1dArrayWO:
+ case clang::BuiltinType::OCLImage1dArrayRW:
+ case clang::BuiltinType::OCLImage1dBufferRO:
+ case clang::BuiltinType::OCLImage1dBufferWO:
+ case clang::BuiltinType::OCLImage1dBufferRW:
+ case clang::BuiltinType::OCLImage2dRO:
+ case clang::BuiltinType::OCLImage2dWO:
+ case clang::BuiltinType::OCLImage2dRW:
+ case clang::BuiltinType::OCLImage2dArrayRO:
+ case clang::BuiltinType::OCLImage2dArrayWO:
+ case clang::BuiltinType::OCLImage2dArrayRW:
+ case clang::BuiltinType::OCLImage3dRO:
+ case clang::BuiltinType::OCLImage3dWO:
+ case clang::BuiltinType::OCLImage3dRW:
case clang::BuiltinType::OCLSampler:
return 0;
case clang::BuiltinType::Bool:
@@ -6070,8 +6220,9 @@ ClangASTContext::GetChildCompilerTypeAtIndex (lldb::opaque_compiler_type_t type,
{
clang::CharUnits base_offset_offset = itanium_vtable_ctx->getVirtualBaseOffsetOffset(cxx_record_decl, base_class_decl);
const lldb::addr_t base_offset_addr = vtable_ptr + base_offset_offset.getQuantity();
- const uint32_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, 4, UINT32_MAX, err);
- if (base_offset != UINT32_MAX)
+ const uint32_t base_offset_size = process->GetAddressByteSize();
+ const uint64_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, base_offset_size, UINT32_MAX, err);
+ if (base_offset < UINT32_MAX)
{
handled = true;
bit_offset = base_offset * 8;
@@ -6123,12 +6274,20 @@ ClangASTContext::GetChildCompilerTypeAtIndex (lldb::opaque_compiler_type_t type,
CompilerType field_clang_type (getASTContext(), field->getType());
assert(field_idx < record_layout.getFieldCount());
child_byte_size = field_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+ const uint32_t child_bit_size = child_byte_size * 8;
// Figure out the field offset within the current struct/union/class type
bit_offset = record_layout.getFieldOffset (field_idx);
- child_byte_offset = bit_offset / 8;
if (ClangASTContext::FieldIsBitfield (getASTContext(), *field, child_bitfield_bit_size))
- child_bitfield_bit_offset = bit_offset % 8;
+ {
+ child_bitfield_bit_offset = bit_offset % child_bit_size;
+ const uint32_t child_bit_offset = bit_offset - child_bitfield_bit_offset;
+ child_byte_offset = child_bit_offset / 8;
+ }
+ else
+ {
+ child_byte_offset = bit_offset / 8;
+ }
return field_clang_type;
}
@@ -7216,7 +7375,7 @@ CompilerType
ClangASTContext::GetTypeForFormatters (void* type)
{
if (type)
- return RemoveFastQualifiers(CompilerType(this, type));
+ return ClangUtil::RemoveFastQualifiers(CompilerType(this, type));
return CompilerType();
}
@@ -7439,7 +7598,7 @@ IsOperator (const char *name, clang::OverloadedOperatorKind &op_kind)
clang::EnumDecl *
ClangASTContext::GetAsEnumDecl (const CompilerType& type)
{
- const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type));
+ const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type));
if (enutype)
return enutype->getDecl();
return NULL;
@@ -7448,7 +7607,7 @@ ClangASTContext::GetAsEnumDecl (const CompilerType& type)
clang::RecordDecl *
ClangASTContext::GetAsRecordDecl (const CompilerType& type)
{
- const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(GetCanonicalQualType(type));
+ const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(ClangUtil::GetCanonicalQualType(type));
if (record_type)
return record_type->getDecl();
return nullptr;
@@ -7457,7 +7616,7 @@ ClangASTContext::GetAsRecordDecl (const CompilerType& type)
clang::TagDecl *
ClangASTContext::GetAsTagDecl (const CompilerType& type)
{
- clang::QualType qual_type = GetCanonicalQualType(type);
+ clang::QualType qual_type = ClangUtil::GetCanonicalQualType(type);
if (qual_type.isNull())
return nullptr;
else
@@ -7473,7 +7632,8 @@ ClangASTContext::GetAsCXXRecordDecl (lldb::opaque_compiler_type_t type)
clang::ObjCInterfaceDecl *
ClangASTContext::GetAsObjCInterfaceDecl (const CompilerType& type)
{
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(GetCanonicalQualType(type));
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(ClangUtil::GetCanonicalQualType(type));
if (objc_class_type)
return objc_class_type->getInterface();
return nullptr;
@@ -7504,17 +7664,14 @@ ClangASTContext::AddFieldToRecordType (const CompilerType& type, const char *nam
clang::RecordDecl *record_decl = ast->GetAsRecordDecl (type);
if (record_decl)
{
- field = clang::FieldDecl::Create (*clang_ast,
- record_decl,
- clang::SourceLocation(),
- clang::SourceLocation(),
- name ? &clang_ast->Idents.get(name) : nullptr, // Identifier
- GetQualType(field_clang_type), // Field type
- nullptr, // TInfo *
- bit_width, // BitWidth
- false, // Mutable
- clang::ICIS_NoInit); // HasInit
-
+ field = clang::FieldDecl::Create(*clang_ast, record_decl, clang::SourceLocation(), clang::SourceLocation(),
+ name ? &clang_ast->Idents.get(name) : nullptr, // Identifier
+ ClangUtil::GetQualType(field_clang_type), // Field type
+ nullptr, // TInfo *
+ bit_width, // BitWidth
+ false, // Mutable
+ clang::ICIS_NoInit); // HasInit
+
if (!name)
{
// Determine whether this field corresponds to an anonymous
@@ -7549,18 +7706,14 @@ ClangASTContext::AddFieldToRecordType (const CompilerType& type, const char *nam
const bool is_synthesized = false;
field_clang_type.GetCompleteType();
-
- field = clang::ObjCIvarDecl::Create (*clang_ast,
- class_interface_decl,
- clang::SourceLocation(),
- clang::SourceLocation(),
- name ? &clang_ast->Idents.get(name) : nullptr, // Identifier
- GetQualType(field_clang_type), // Field type
- nullptr, // TypeSourceInfo *
- ConvertAccessTypeToObjCIvarAccessControl (access),
- bit_width,
- is_synthesized);
-
+
+ field = clang::ObjCIvarDecl::Create(
+ *clang_ast, class_interface_decl, clang::SourceLocation(), clang::SourceLocation(),
+ name ? &clang_ast->Idents.get(name) : nullptr, // Identifier
+ ClangUtil::GetQualType(field_clang_type), // Field type
+ nullptr, // TypeSourceInfo *
+ ConvertAccessTypeToObjCIvarAccessControl(access), bit_width, is_synthesized);
+
if (field)
{
class_interface_decl->addDecl(field);
@@ -7625,8 +7778,7 @@ ClangASTContext::BuildIndirectFields (const CompilerType& type)
clang::SourceLocation(),
nested_field_decl->getIdentifier(),
nested_field_decl->getType(),
- chain,
- 2);
+ {chain, 2});
indirect_field->setImplicit();
@@ -7637,7 +7789,7 @@ ClangASTContext::BuildIndirectFields (const CompilerType& type)
}
else if (clang::IndirectFieldDecl *nested_indirect_field_decl = llvm::dyn_cast<clang::IndirectFieldDecl>(*di))
{
- int nested_chain_size = nested_indirect_field_decl->getChainingSize();
+ size_t nested_chain_size = nested_indirect_field_decl->getChainingSize();
clang::NamedDecl **chain = new (*ast->getASTContext()) clang::NamedDecl*[nested_chain_size + 1];
chain[0] = *field_pos;
@@ -7656,8 +7808,7 @@ ClangASTContext::BuildIndirectFields (const CompilerType& type)
clang::SourceLocation(),
nested_indirect_field_decl->getIdentifier(),
nested_indirect_field_decl->getType(),
- chain,
- nested_chain_size + 1);
+ {chain, nested_chain_size + 1});
indirect_field->setImplicit();
@@ -7720,14 +7871,15 @@ ClangASTContext::AddVariableToRecordType (const CompilerType& type, const char *
clang::RecordDecl *record_decl = ast->GetAsRecordDecl (type);
if (record_decl)
{
- var_decl = clang::VarDecl::Create (*ast->getASTContext(), // ASTContext &
- record_decl, // DeclContext *
- clang::SourceLocation(), // clang::SourceLocation StartLoc
- clang::SourceLocation(), // clang::SourceLocation IdLoc
- name ? &ast->getASTContext()->Idents.get(name) : nullptr, // clang::IdentifierInfo *
- GetQualType(var_type), // Variable clang::QualType
- nullptr, // TypeSourceInfo *
- clang::SC_Static); // StorageClass
+ var_decl =
+ clang::VarDecl::Create(*ast->getASTContext(), // ASTContext &
+ record_decl, // DeclContext *
+ clang::SourceLocation(), // clang::SourceLocation StartLoc
+ clang::SourceLocation(), // clang::SourceLocation IdLoc
+ name ? &ast->getASTContext()->Idents.get(name) : nullptr, // clang::IdentifierInfo *
+ ClangUtil::GetQualType(var_type), // Variable clang::QualType
+ nullptr, // TypeSourceInfo *
+ clang::SC_Static); // StorageClass
if (var_decl)
{
var_decl->setAccess(ClangASTContext::ConvertAccessTypeToAccessSpecifier (access));
@@ -7762,9 +7914,9 @@ ClangASTContext::AddMethodToCXXRecordType (lldb::opaque_compiler_type_t type, co
if (cxx_record_decl == nullptr)
return nullptr;
-
- clang::QualType method_qual_type (GetQualType(method_clang_type));
-
+
+ clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
+
clang::CXXMethodDecl *cxx_method_decl = nullptr;
clang::DeclarationName decl_name (&getASTContext()->Idents.get(name));
@@ -8048,17 +8200,16 @@ ClangASTContext::AddObjCClassProperty (const CompilerType& type,
if (ivar_decl)
prop_type_source = clang_ast->getTrivialTypeSourceInfo (ivar_decl->getType());
else
- prop_type_source = clang_ast->getTrivialTypeSourceInfo (GetQualType(property_clang_type));
-
- clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create (*clang_ast,
- class_interface_decl,
- clang::SourceLocation(), // Source Location
- &clang_ast->Idents.get(property_name),
- clang::SourceLocation(), //Source Location for AT
- clang::SourceLocation(), //Source location for (
- ivar_decl ? ivar_decl->getType() : ClangASTContext::GetQualType(property_clang_type),
- prop_type_source);
-
+ prop_type_source = clang_ast->getTrivialTypeSourceInfo(ClangUtil::GetQualType(property_clang_type));
+
+ clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create(
+ *clang_ast, class_interface_decl,
+ clang::SourceLocation(), // Source Location
+ &clang_ast->Idents.get(property_name),
+ clang::SourceLocation(), // Source Location for AT
+ clang::SourceLocation(), // Source location for (
+ ivar_decl ? ivar_decl->getType() : ClangUtil::GetQualType(property_clang_type), prop_type_source);
+
if (property_decl)
{
if (metadata)
@@ -8113,32 +8264,32 @@ ClangASTContext::AddObjCClassProperty (const CompilerType& type,
property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_copy);
if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_nonatomic);
-
- if (!getter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(getter_sel))
+ if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_nullability)
+ property_decl->setPropertyAttributes(clang::ObjCPropertyDecl::OBJC_PR_nullability);
+ if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_null_resettable)
+ property_decl->setPropertyAttributes(clang::ObjCPropertyDecl::OBJC_PR_null_resettable);
+ if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class)
+ property_decl->setPropertyAttributes(clang::ObjCPropertyDecl::OBJC_PR_class);
+
+ const bool isInstance = (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class) == 0;
+
+ if (!getter_sel.isNull() &&
+ !(isInstance ? class_interface_decl->lookupInstanceMethod(getter_sel)
+ : class_interface_decl->lookupClassMethod(getter_sel)))
{
- const bool isInstance = true;
const bool isVariadic = false;
const bool isSynthesized = false;
const bool isImplicitlyDeclared = true;
const bool isDefined = false;
const clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None;
const bool HasRelatedResultType = false;
-
- clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create (*clang_ast,
- clang::SourceLocation(),
- clang::SourceLocation(),
- getter_sel,
- GetQualType(property_clang_type_to_access),
- nullptr,
- class_interface_decl,
- isInstance,
- isVariadic,
- isSynthesized,
- isImplicitlyDeclared,
- isDefined,
- impControl,
- HasRelatedResultType);
-
+
+ clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create(
+ *clang_ast, clang::SourceLocation(), clang::SourceLocation(), getter_sel,
+ ClangUtil::GetQualType(property_clang_type_to_access), nullptr, class_interface_decl,
+ isInstance, isVariadic, isSynthesized, isImplicitlyDeclared, isDefined, impControl,
+ HasRelatedResultType);
+
if (getter && metadata)
ClangASTContext::SetMetadata(clang_ast, getter, *metadata);
@@ -8149,12 +8300,12 @@ ClangASTContext::AddObjCClassProperty (const CompilerType& type,
class_interface_decl->addDecl(getter);
}
}
-
- if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel))
+
+ if (!setter_sel.isNull() &&
+ !(isInstance ? class_interface_decl->lookupInstanceMethod(setter_sel)
+ : class_interface_decl->lookupClassMethod(setter_sel)))
{
clang::QualType result_type = clang_ast->VoidTy;
-
- const bool isInstance = true;
const bool isVariadic = false;
const bool isSynthesized = false;
const bool isImplicitlyDeclared = true;
@@ -8181,17 +8332,12 @@ ClangASTContext::AddObjCClassProperty (const CompilerType& type,
ClangASTContext::SetMetadata(clang_ast, setter, *metadata);
llvm::SmallVector<clang::ParmVarDecl *, 1> params;
-
- params.push_back (clang::ParmVarDecl::Create (*clang_ast,
- setter,
- clang::SourceLocation(),
- clang::SourceLocation(),
- nullptr, // anonymous
- GetQualType(property_clang_type_to_access),
- nullptr,
- clang::SC_Auto,
- nullptr));
-
+
+ params.push_back(clang::ParmVarDecl::Create(
+ *clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(),
+ nullptr, // anonymous
+ ClangUtil::GetQualType(property_clang_type_to_access), nullptr, clang::SC_Auto, nullptr));
+
if (setter)
{
setter->setMethodParams(*clang_ast, llvm::ArrayRef<clang::ParmVarDecl*>(params), llvm::ArrayRef<clang::SourceLocation>());
@@ -8222,7 +8368,8 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type,
const char *name, // the full symbol name as seen in the symbol table (lldb::opaque_compiler_type_t type, "-[NString stringWithCString:]")
const CompilerType &method_clang_type,
lldb::AccessType access,
- bool is_artificial)
+ bool is_artificial,
+ bool is_variadic)
{
if (!type || !method_clang_type.IsValid())
return nullptr;
@@ -8267,9 +8414,9 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type,
clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
selector_idents.data());
-
- clang::QualType method_qual_type (GetQualType(method_clang_type));
-
+
+ clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
+
// Populate the method decl with parameter decls
const clang::Type *method_type(method_qual_type.getTypePtr());
@@ -8282,7 +8429,6 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type,
return nullptr;
- bool is_variadic = false;
bool is_synthesized = false;
bool is_defined = false;
clang::ObjCMethodDecl::ImplementationControl imp_control = clang::ObjCMethodDecl::None;
@@ -8291,23 +8437,18 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type,
if (num_args != num_selectors_with_args)
return nullptr; // some debug information is corrupt. We are not going to deal with it.
-
- clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create (*ast,
- clang::SourceLocation(), // beginLoc,
- clang::SourceLocation(), // endLoc,
- method_selector,
- method_function_prototype->getReturnType(),
- nullptr, // TypeSourceInfo *ResultTInfo,
- ClangASTContext::GetASTContext(ast)->GetDeclContextForType(GetQualType(type)),
- name[0] == '-',
- is_variadic,
- is_synthesized,
- true, // is_implicitly_declared; we force this to true because we don't have source locations
- is_defined,
- imp_control,
- false /*has_related_result_type*/);
-
-
+
+ clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create(
+ *ast,
+ clang::SourceLocation(), // beginLoc,
+ clang::SourceLocation(), // endLoc,
+ method_selector, method_function_prototype->getReturnType(),
+ nullptr, // TypeSourceInfo *ResultTInfo,
+ ClangASTContext::GetASTContext(ast)->GetDeclContextForType(ClangUtil::GetQualType(type)), name[0] == '-',
+ is_variadic, is_synthesized,
+ true, // is_implicitly_declared; we force this to true because we don't have source locations
+ is_defined, imp_control, false /*has_related_result_type*/);
+
if (objc_method_decl == nullptr)
return nullptr;
@@ -8343,10 +8484,10 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type,
bool
ClangASTContext::GetHasExternalStorage (const CompilerType &type)
{
- if (IsClangType(type))
+ if (ClangUtil::IsClangType(type))
return false;
- clang::QualType qual_type (GetCanonicalQualType(type));
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
switch (type_class)
@@ -8474,158 +8615,12 @@ ClangASTContext::SetHasExternalStorage (lldb::opaque_compiler_type_t type, bool
}
-bool
-ClangASTContext::CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer)
-{
- if (IsClangType(type))
- {
- // TODO: remove external completion BOOL
- // CompleteAndFetchChildren should get the Decl out and check for the
-
- clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type)));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- {
- const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL))
- return true;
- }
- }
- break;
-
- case clang::Type::Enum:
- {
- clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
- if (enum_decl)
- {
- if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL))
- return true;
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- {
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- // We currently can't complete objective C types through the newly added ASTContext
- // because it only supports TagDecl objects right now...
- if (class_interface_decl)
- {
- if (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL))
- return true;
- }
- }
- }
- break;
-
-
- case clang::Type::Typedef:
- return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer);
-
- case clang::Type::Auto:
- return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()), importer);
-
- case clang::Type::Elaborated:
- return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer);
-
- case clang::Type::Paren:
- return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer);
-
- default:
- break;
- }
- }
- return false;
-}
-bool
-ClangASTContext::Import (const CompilerType &type, lldb_private::ClangASTImporter &importer)
-{
- if (IsClangType(type))
- {
- // TODO: remove external completion BOOL
- // CompleteAndFetchChildren should get the Decl out and check for the
-
- clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type)));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- {
- const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL))
- return importer.CompleteAndFetchChildren(qual_type);
- }
- }
- break;
-
- case clang::Type::Enum:
- {
- clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
- if (enum_decl)
- {
- if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL))
- return importer.CompleteAndFetchChildren(qual_type);
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- {
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- // We currently can't complete objective C types through the newly added ASTContext
- // because it only supports TagDecl objects right now...
- if (class_interface_decl)
- {
- if (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL))
- return importer.CompleteAndFetchChildren(qual_type);
- }
- }
- }
- break;
-
-
- case clang::Type::Typedef:
- return Import (CompilerType(type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer);
-
- case clang::Type::Auto:
- return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()), importer);
-
- case clang::Type::Elaborated:
- return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer);
-
- case clang::Type::Paren:
- return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer);
-
- default:
- break;
- }
- }
- return false;
-}
-
-
#pragma mark TagDecl
bool
ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type)
{
- clang::QualType qual_type (ClangASTContext::GetQualType(type));
+ clang::QualType qual_type(ClangUtil::GetQualType(type));
if (!qual_type.isNull())
{
const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
@@ -8656,21 +8651,31 @@ ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type)
bool
ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type)
{
- clang::QualType qual_type (ClangASTContext::GetQualType(type));
+ clang::QualType qual_type(ClangUtil::GetQualType(type));
if (!qual_type.isNull())
{
- clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-
- if (cxx_record_decl)
+ // Make sure we use the same methodology as ClangASTContext::StartTagDeclarationDefinition()
+ // as to how we start/end the definition. Previously we were calling
+ const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
+ if (tag_type)
{
- if (!cxx_record_decl->isCompleteDefinition())
- cxx_record_decl->completeDefinition();
- cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
- cxx_record_decl->setHasExternalLexicalStorage (false);
- cxx_record_decl->setHasExternalVisibleStorage (false);
- return true;
+ clang::TagDecl *tag_decl = tag_type->getDecl();
+ if (tag_decl)
+ {
+ clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(tag_decl);
+
+ if (cxx_record_decl)
+ {
+ if (!cxx_record_decl->isCompleteDefinition())
+ cxx_record_decl->completeDefinition();
+ cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
+ cxx_record_decl->setHasExternalLexicalStorage (false);
+ cxx_record_decl->setHasExternalVisibleStorage (false);
+ return true;
+ }
+ }
}
-
+
const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>();
if (enutype)
@@ -8687,24 +8692,28 @@ ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type)
clang::ASTContext *ast = lldb_ast->getASTContext();
/// TODO This really needs to be fixed.
-
- unsigned NumPositiveBits = 1;
- unsigned NumNegativeBits = 0;
-
- clang::QualType promotion_qual_type;
- // If the enum integer type is less than an integer in bit width,
- // then we must promote it to an integer size.
- if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
+
+ QualType integer_type(enum_decl->getIntegerType());
+ if (!integer_type.isNull())
{
- if (enum_decl->getIntegerType()->isSignedIntegerType())
- promotion_qual_type = ast->IntTy;
+ unsigned NumPositiveBits = 1;
+ unsigned NumNegativeBits = 0;
+
+ clang::QualType promotion_qual_type;
+ // If the enum integer type is less than an integer in bit width,
+ // then we must promote it to an integer size.
+ if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
+ {
+ if (enum_decl->getIntegerType()->isSignedIntegerType())
+ promotion_qual_type = ast->IntTy;
+ else
+ promotion_qual_type = ast->UnsignedIntTy;
+ }
else
- promotion_qual_type = ast->UnsignedIntTy;
+ promotion_qual_type = enum_decl->getIntegerType();
+
+ enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
}
- else
- promotion_qual_type = enum_decl->getIntegerType();
-
- enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
}
return true;
}
@@ -8736,15 +8745,11 @@ ClangASTContext::AddEnumerationValueToEnumerationType (lldb::opaque_compiler_typ
{
llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed);
enum_llvm_apsint = enum_value;
- clang::EnumConstantDecl *enumerator_decl =
- clang::EnumConstantDecl::Create (*getASTContext(),
- enutype->getDecl(),
- clang::SourceLocation(),
- name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier
- GetQualType(enumerator_clang_type),
- nullptr,
- enum_llvm_apsint);
-
+ clang::EnumConstantDecl *enumerator_decl = clang::EnumConstantDecl::Create(
+ *getASTContext(), enutype->getDecl(), clang::SourceLocation(),
+ name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier
+ ClangUtil::GetQualType(enumerator_clang_type), nullptr, enum_llvm_apsint);
+
if (enumerator_decl)
{
enutype->getDecl()->addDecl(enumerator_decl);
@@ -8787,9 +8792,9 @@ ClangASTContext::CreateMemberPointerType (const CompilerType& type, const Compil
ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
if (!ast)
return CompilerType();
- return CompilerType (ast->getASTContext(),
- ast->getASTContext()->getMemberPointerType (GetQualType(pointee_type),
- GetQualType(type).getTypePtr()));
+ return CompilerType(ast->getASTContext(),
+ ast->getASTContext()->getMemberPointerType(ClangUtil::GetQualType(pointee_type),
+ ClangUtil::GetQualType(type).getTypePtr()));
}
return CompilerType();
}
@@ -8816,18 +8821,10 @@ ClangASTContext::ConvertStringToFloatValue (lldb::opaque_compiler_type_t type, c
const uint64_t byte_size = bit_size / 8;
if (dst_size >= byte_size)
{
- if (bit_size == sizeof(float)*8)
- {
- float float32 = ap_float.convertToFloat();
- ::memcpy (dst, &float32, byte_size);
- return byte_size;
- }
- else if (bit_size >= 64)
- {
- llvm::APInt ap_int(ap_float.bitcastToAPInt());
- ::memcpy (dst, ap_int.getRawData(), byte_size);
+ Scalar scalar = ap_float.bitcastToAPInt().zextOrTrunc(llvm::NextPowerOf2(byte_size) * 8);
+ lldb_private::Error get_data_error;
+ if (scalar.GetAsMemoryData(dst, byte_size, lldb_private::endian::InlHostByteOrder(), get_data_error))
return byte_size;
- }
}
}
}
@@ -9281,6 +9278,7 @@ ClangASTContext::DumpTypeValue (lldb::opaque_compiler_type_t type, Stream *s,
return true;
}
// format was not enum, just fall through and dump the value as requested....
+ LLVM_FALLTHROUGH;
default:
// We are down to a scalar type that we just need to display.
@@ -9519,9 +9517,9 @@ ClangASTContext::DumpTypeDescription (lldb::opaque_compiler_type_t type, Stream
void
ClangASTContext::DumpTypeName (const CompilerType &type)
{
- if (IsClangType(type))
+ if (ClangUtil::IsClangType(type))
{
- clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type)));
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
switch (type_class)
@@ -9633,15 +9631,21 @@ ClangASTContext::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDec
}
}
-
DWARFASTParser *
-ClangASTContext::GetDWARFParser ()
+ClangASTContext::GetDWARFParser()
{
if (!m_dwarf_ast_parser_ap)
m_dwarf_ast_parser_ap.reset(new DWARFASTParserClang(*this));
return m_dwarf_ast_parser_ap.get();
}
+PDBASTParser *
+ClangASTContext::GetPDBParser()
+{
+ if (!m_pdb_ast_parser_ap)
+ m_pdb_ast_parser_ap.reset(new PDBASTParser(*this));
+ return m_pdb_ast_parser_ap.get();
+}
bool
ClangASTContext::LayoutRecordType(void *baton,
@@ -9654,30 +9658,13 @@ ClangASTContext::LayoutRecordType(void *baton,
{
ClangASTContext *ast = (ClangASTContext *)baton;
DWARFASTParserClang *dwarf_ast_parser = (DWARFASTParserClang *)ast->GetDWARFParser();
- return dwarf_ast_parser->LayoutRecordType(record_decl, bit_size, alignment, field_offsets, base_offsets, vbase_offsets);
+ return dwarf_ast_parser->GetClangASTImporter().LayoutRecordType(record_decl, bit_size, alignment, field_offsets,
+ base_offsets, vbase_offsets);
}
//----------------------------------------------------------------------
// CompilerDecl override functions
//----------------------------------------------------------------------
-lldb::VariableSP
-ClangASTContext::DeclGetVariable (void *opaque_decl)
-{
- if (llvm::dyn_cast<clang::VarDecl>((clang::Decl *)opaque_decl))
- {
- auto decl_search_it = m_decl_objects.find(opaque_decl);
- if (decl_search_it != m_decl_objects.end())
- return std::static_pointer_cast<Variable>(decl_search_it->second);
- }
- return VariableSP();
-}
-
-void
-ClangASTContext::DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object)
-{
- if (m_decl_objects.find(opaque_decl) == m_decl_objects.end())
- m_decl_objects.insert(std::make_pair(opaque_decl, object));
-}
ConstString
ClangASTContext::DeclGetName (void *opaque_decl)
@@ -9750,7 +9737,7 @@ ClangASTContext::DeclGetFunctionNumArguments(void *opaque_decl)
if (clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>((clang::Decl*)opaque_decl))
return func_decl->param_size();
if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl*)opaque_decl))
- return objc_method->param_size();
+ return objc_method->param_size();
else
return 0;
}
@@ -9764,7 +9751,7 @@ ClangASTContext::DeclGetFunctionArgumentType (void *opaque_decl, size_t idx)
{
ParmVarDecl *var_decl = func_decl->getParamDecl(idx);
if (var_decl)
- return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr());
+ return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr());
}
}
else if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl*)opaque_decl))
@@ -9780,7 +9767,9 @@ ClangASTContext::DeclGetFunctionArgumentType (void *opaque_decl, size_t idx)
//----------------------------------------------------------------------
std::vector<CompilerDecl>
-ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name)
+ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx,
+ ConstString name,
+ const bool ignore_using_decls)
{
std::vector<CompilerDecl> found_decls;
if (opaque_decl_ctx)
@@ -9804,12 +9793,16 @@ ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString na
{
if (clang::UsingDirectiveDecl *ud = llvm::dyn_cast<clang::UsingDirectiveDecl>(child))
{
+ if (ignore_using_decls)
+ continue;
clang::DeclContext *from = ud->getCommonAncestor();
if (searched.find(ud->getNominatedNamespace()) == searched.end())
search_queue.insert(std::make_pair(from, ud->getNominatedNamespace()));
}
else if (clang::UsingDecl *ud = llvm::dyn_cast<clang::UsingDecl>(child))
{
+ if (ignore_using_decls)
+ continue;
for (clang::UsingShadowDecl *usd : ud->shadows())
{
clang::Decl *target = usd->getTargetDecl();
@@ -9902,6 +9895,15 @@ ClangASTContext::CountDeclLevels (clang::DeclContext *frame_decl_ctx,
{
if (searched.find(it->second) != searched.end())
continue;
+
+ // Currently DWARF has one shared translation unit for all Decls at top level, so this
+ // would erroneously find using statements anywhere. So don't look at the top-level
+ // translation unit.
+ // TODO fix this and add a testcase that depends on it.
+
+ if (llvm::isa<clang::TranslationUnitDecl>(it->second))
+ continue;
+
searched.insert(it->second);
symbol_file->ParseDeclsForContext(CompilerDeclContext(this, it->second));
diff --git a/source/Symbol/ClangASTImporter.cpp b/source/Symbol/ClangASTImporter.cpp
index 141937072c73..6be10602d998 100644
--- a/source/Symbol/ClangASTImporter.cpp
+++ b/source/Symbol/ClangASTImporter.cpp
@@ -7,16 +7,17 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "llvm/Support/raw_ostream.h"
+#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "llvm/Support/raw_ostream.h"
using namespace lldb_private;
using namespace clang;
@@ -347,6 +348,211 @@ ClangASTImporter::DeportDecl (clang::ASTContext *dst_ctx,
return result;
}
+bool
+ClangASTImporter::CanImport(const CompilerType &type)
+{
+ if (!ClangUtil::IsClangType(type))
+ return false;
+
+ // TODO: remove external completion BOOL
+ // CompleteAndFetchChildren should get the Decl out and check for the
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ {
+ const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL))
+ return true;
+ }
+ }
+ break;
+
+ case clang::Type::Enum:
+ {
+ clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ if (enum_decl)
+ {
+ if (ResolveDeclOrigin(enum_decl, NULL, NULL))
+ return true;
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ {
+ const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type)
+ {
+ clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly added ASTContext
+ // because it only supports TagDecl objects right now...
+ if (class_interface_decl)
+ {
+ if (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
+ return true;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return CanImport(CompilerType(
+ type.GetTypeSystem(),
+ llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
+
+ case clang::Type::Auto:
+ return CanImport(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()));
+
+ case clang::Type::Elaborated:
+ return CanImport(CompilerType(
+ type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
+
+ case clang::Type::Paren:
+ return CanImport(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool
+ClangASTImporter::Import(const CompilerType &type)
+{
+ if (!ClangUtil::IsClangType(type))
+ return false;
+ // TODO: remove external completion BOOL
+ // CompleteAndFetchChildren should get the Decl out and check for the
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ {
+ const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL))
+ return CompleteAndFetchChildren(qual_type);
+ }
+ }
+ break;
+
+ case clang::Type::Enum:
+ {
+ clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ if (enum_decl)
+ {
+ if (ResolveDeclOrigin(enum_decl, NULL, NULL))
+ return CompleteAndFetchChildren(qual_type);
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ {
+ const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type)
+ {
+ clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly added ASTContext
+ // because it only supports TagDecl objects right now...
+ if (class_interface_decl)
+ {
+ if (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
+ return CompleteAndFetchChildren(qual_type);
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return Import(CompilerType(
+ type.GetTypeSystem(),
+ llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
+
+ case clang::Type::Auto:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()));
+
+ case clang::Type::Elaborated:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
+
+ case clang::Type::Paren:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+ default:
+ break;
+ }
+ return false;
+}
+
+bool
+ClangASTImporter::CompleteType(const CompilerType &compiler_type)
+{
+ if (!CanImport(compiler_type))
+ return false;
+
+ if (Import(compiler_type))
+ {
+ ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
+ return true;
+ }
+
+ ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), false);
+ return false;
+}
+
+bool
+ClangASTImporter::LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
+{
+ RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find(record_decl);
+ bool success = false;
+ base_offsets.clear();
+ vbase_offsets.clear();
+ if (pos != m_record_decl_to_layout_map.end())
+ {
+ bit_size = pos->second.bit_size;
+ alignment = pos->second.alignment;
+ field_offsets.swap(pos->second.field_offsets);
+ base_offsets.swap(pos->second.base_offsets);
+ vbase_offsets.swap(pos->second.vbase_offsets);
+ m_record_decl_to_layout_map.erase(pos);
+ success = true;
+ }
+ else
+ {
+ bit_size = 0;
+ alignment = 0;
+ field_offsets.clear();
+ }
+ return success;
+}
+
+void
+ClangASTImporter::InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout)
+{
+ m_record_decl_to_layout_map.insert(std::make_pair(decl, layout));
+}
+
void
ClangASTImporter::CompleteDecl (clang::Decl *decl)
{
@@ -729,16 +935,21 @@ ClangASTImporter::Minion::ExecuteDeportWorkQueues ()
if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl))
{
if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
+ {
if (original_tag_decl->isCompleteDefinition())
+ {
ImportDefinitionTo(tag_decl, original_tag_decl);
+ tag_decl->setCompleteDefinition(true);
+ }
+ }
tag_decl->setHasExternalLexicalStorage(false);
tag_decl->setHasExternalVisibleStorage(false);
}
- else if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl))
+ else if (ObjCContainerDecl *container_decl = dyn_cast<ObjCContainerDecl>(decl))
{
- interface_decl->setHasExternalLexicalStorage(false);
- interface_decl->setHasExternalVisibleStorage(false);
+ container_decl->setHasExternalLexicalStorage(false);
+ container_decl->setHasExternalVisibleStorage(false);
}
to_context_md->m_origins.erase(decl);
@@ -753,8 +964,6 @@ ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from
{
ASTImporter::Imported(from, to);
- ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to);
-
/*
if (to_objc_interface)
to_objc_interface->startDefinition();
@@ -766,12 +975,20 @@ ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from
*/
ImportDefinition(from);
+
+ if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to))
+ {
+ if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from))
+ {
+ to_tag->setCompleteDefinition(from_tag->isCompleteDefinition());
+ }
+ }
// If we're dealing with an Objective-C class, ensure that the inheritance has
// been set up correctly. The ASTImporter may not do this correctly if the
// class was originally sourced from symbols.
- if (to_objc_interface)
+ if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to))
{
do
{
@@ -949,20 +1166,32 @@ ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
to_namespace_decl->setHasExternalVisibleStorage();
}
- if (isa<ObjCInterfaceDecl>(from))
+ if (isa<ObjCContainerDecl>(from))
{
- ObjCInterfaceDecl *to_interface_decl = dyn_cast<ObjCInterfaceDecl>(to);
+ ObjCContainerDecl *to_container_decl = dyn_cast<ObjCContainerDecl>(to);
- to_interface_decl->setHasExternalLexicalStorage();
- to_interface_decl->setHasExternalVisibleStorage();
+ to_container_decl->setHasExternalLexicalStorage();
+ to_container_decl->setHasExternalVisibleStorage();
/*to_interface_decl->setExternallyCompleted();*/
if (log)
- log->Printf(" [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s",
- (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
- (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
- (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
+ {
+ if (ObjCInterfaceDecl *to_interface_decl = llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl))
+ {
+ log->Printf(" [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s",
+ (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
+ (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
+ }
+ else
+ {
+ log->Printf(" [ClangASTImporter] To is an %sDecl - attributes %s%s",
+ ((Decl*)to_container_decl)->getDeclKindName(),
+ (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_container_decl->hasExternalVisibleStorage() ? " Visible" : ""));
+ }
+ }
}
return clang::ASTImporter::Imported(from, to);
diff --git a/source/Symbol/ClangExternalASTSourceCommon.cpp b/source/Symbol/ClangExternalASTSourceCommon.cpp
index 79cc9a91355a..77aea1eafc4f 100644
--- a/source/Symbol/ClangExternalASTSourceCommon.cpp
+++ b/source/Symbol/ClangExternalASTSourceCommon.cpp
@@ -9,7 +9,6 @@
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Core/Stream.h"
-#include "lldb/Host/Mutex.h"
using namespace lldb_private;
@@ -19,8 +18,9 @@ typedef llvm::DenseMap<clang::ExternalASTSource *, ClangExternalASTSourceCommon
static ASTSourceMap &GetSourceMap()
{
- static ASTSourceMap s_source_map;
- return s_source_map;
+ // Intentionally leaked to avoid problems with global destructors.
+ static ASTSourceMap *s_source_map = new ASTSourceMap;
+ return *s_source_map;
}
ClangExternalASTSourceCommon *
diff --git a/source/Symbol/ClangUtil.cpp b/source/Symbol/ClangUtil.cpp
new file mode 100644
index 000000000000..76d621e9ce44
--- /dev/null
+++ b/source/Symbol/ClangUtil.cpp
@@ -0,0 +1,58 @@
+//===-- ClangUtil.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+// A collection of helper methods and data structures for manipulating clang
+// types and decls.
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/ClangUtil.h"
+#include "lldb/Symbol/ClangASTContext.h"
+
+using namespace clang;
+using namespace lldb_private;
+
+bool
+ClangUtil::IsClangType(const CompilerType &ct)
+{
+ if (llvm::dyn_cast_or_null<ClangASTContext>(ct.GetTypeSystem()) == nullptr)
+ return false;
+
+ if (!ct.GetOpaqueQualType())
+ return false;
+
+ return true;
+}
+
+QualType
+ClangUtil::GetQualType(const CompilerType &ct)
+{
+ // Make sure we have a clang type before making a clang::QualType
+ if (!IsClangType(ct))
+ return QualType();
+
+ return QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
+}
+
+QualType
+ClangUtil::GetCanonicalQualType(const CompilerType &ct)
+{
+ if (!IsClangType(ct))
+ return QualType();
+
+ return GetQualType(ct).getCanonicalType();
+}
+
+CompilerType
+ClangUtil::RemoveFastQualifiers(const CompilerType &ct)
+{
+ if (!IsClangType(ct))
+ return ct;
+
+ QualType qual_type(GetQualType(ct));
+ qual_type.removeLocalFastQualifiers();
+ return CompilerType(ct.GetTypeSystem(), qual_type.getAsOpaquePtr());
+}
diff --git a/source/Symbol/CompactUnwindInfo.cpp b/source/Symbol/CompactUnwindInfo.cpp
index 233ca91ec8d8..105c3c242c0f 100644
--- a/source/Symbol/CompactUnwindInfo.cpp
+++ b/source/Symbol/CompactUnwindInfo.cpp
@@ -101,6 +101,52 @@ namespace lldb_private {
UNWIND_X86_64_REG_R15 = 5,
UNWIND_X86_64_REG_RBP = 6,
};
+
+ FLAGS_ANONYMOUS_ENUM()
+ {
+ UNWIND_ARM64_MODE_MASK = 0x0F000000,
+ UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
+ UNWIND_ARM64_MODE_DWARF = 0x03000000,
+ UNWIND_ARM64_MODE_FRAME = 0x04000000,
+
+ UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
+ UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
+ UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
+ UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
+ UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
+ UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
+ UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
+ UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
+ UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,
+
+ UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,
+ UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
+ };
+
+ FLAGS_ANONYMOUS_ENUM()
+ {
+ UNWIND_ARM_MODE_MASK = 0x0F000000,
+ UNWIND_ARM_MODE_FRAME = 0x01000000,
+ UNWIND_ARM_MODE_FRAME_D = 0x02000000,
+ UNWIND_ARM_MODE_DWARF = 0x04000000,
+
+ UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000,
+
+ UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001,
+ UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002,
+ UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004,
+
+ UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080,
+
+ UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700,
+
+ UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF,
+ };
+
}
@@ -127,22 +173,20 @@ namespace lldb_private {
//----------------------
-// constructor
+// constructor
//----------------------
-
-CompactUnwindInfo::CompactUnwindInfo(ObjectFile& objfile, SectionSP& section_sp) :
- m_objfile (objfile),
- m_section_sp (section_sp),
- m_section_contents_if_encrypted (),
- m_mutex (),
- m_indexes (),
- m_indexes_computed (eLazyBoolCalculate),
- m_unwindinfo_data (),
- m_unwindinfo_data_computed (false),
- m_unwind_header ()
+CompactUnwindInfo::CompactUnwindInfo(ObjectFile &objfile, SectionSP &section_sp)
+ : m_objfile(objfile),
+ m_section_sp(section_sp),
+ m_section_contents_if_encrypted(),
+ m_mutex(),
+ m_indexes(),
+ m_indexes_computed(eLazyBoolCalculate),
+ m_unwindinfo_data(),
+ m_unwindinfo_data_computed(false),
+ m_unwind_header()
{
-
}
//----------------------
@@ -175,7 +219,7 @@ CompactUnwindInfo::GetUnwindPlan (Target &target, Address addr, UnwindPlan& unwi
if (log && log->GetVerbose())
{
StreamString strm;
- addr.Dump (&strm, NULL, Address::DumpStyle::DumpStyleResolvedDescriptionNoFunctionArguments, Address::DumpStyle::DumpStyleFileAddress, arch.GetAddressByteSize());
+ addr.Dump (&strm, NULL, Address::DumpStyle::DumpStyleResolvedDescriptionNoFunctionArguments, Address::DumpStyle::DumpStyleFileAddress, arch.GetAddressByteSize());
log->Printf ("Got compact unwind encoding 0x%x for function %s", function_info.encoding, strm.GetData());
}
@@ -184,7 +228,7 @@ CompactUnwindInfo::GetUnwindPlan (Target &target, Address addr, UnwindPlan& unwi
SectionList *sl = m_objfile.GetSectionList ();
if (sl)
{
- addr_t func_range_start_file_addr =
+ addr_t func_range_start_file_addr =
function_info.valid_range_offset_start + m_objfile.GetHeaderAddress().GetFileAddress();
AddressRange func_range (func_range_start_file_addr,
function_info.valid_range_offset_end - function_info.valid_range_offset_start,
@@ -197,10 +241,18 @@ CompactUnwindInfo::GetUnwindPlan (Target &target, Address addr, UnwindPlan& unwi
{
return CreateUnwindPlan_x86_64 (target, function_info, unwind_plan, addr);
}
+ if (arch.GetTriple().getArch() == llvm::Triple::aarch64)
+ {
+ return CreateUnwindPlan_arm64 (target, function_info, unwind_plan, addr);
+ }
if (arch.GetTriple().getArch() == llvm::Triple::x86)
{
return CreateUnwindPlan_i386 (target, function_info, unwind_plan, addr);
}
+ if (arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb)
+ {
+ return CreateUnwindPlan_armv7 (target, function_info, unwind_plan, addr);
+ }
}
}
return false;
@@ -223,7 +275,7 @@ CompactUnwindInfo::IsValid (const ProcessSP &process_sp)
void
CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
if (m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed)
return;
@@ -248,8 +300,8 @@ CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp)
m_section_contents_if_encrypted.reset (new DataBufferHeap (m_section_sp->GetByteSize(), 0));
Error error;
if (process_sp->ReadMemory (
- m_section_sp->GetLoadBaseAddress (&process_sp->GetTarget()),
- m_section_contents_if_encrypted->GetBytes(),
+ m_section_sp->GetLoadBaseAddress (&process_sp->GetTarget()),
+ m_section_contents_if_encrypted->GetBytes(),
m_section_sp->GetByteSize(), error) == m_section_sp->GetByteSize() && error.Success())
{
m_unwindinfo_data.SetAddressByteSize (process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
@@ -279,7 +331,7 @@ CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp)
// uint32_t personalityArrayCount;
// uint32_t indexSectionOffset;
// uint32_t indexCount;
-
+
m_unwind_header.version = m_unwindinfo_data.GetU32(&offset);
m_unwind_header.common_encodings_array_offset = m_unwindinfo_data.GetU32(&offset);
m_unwind_header.common_encodings_array_count = m_unwindinfo_data.GetU32(&offset);
@@ -305,13 +357,21 @@ CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp)
// Parse the basic information from the indexes
// We wait to scan the second level page info until it's needed
- // struct unwind_info_section_header_index_entry
+ // struct unwind_info_section_header_index_entry
// {
// uint32_t functionOffset;
// uint32_t secondLevelPagesSectionOffset;
// uint32_t lsdaIndexArraySectionOffset;
// };
+ bool clear_address_zeroth_bit = false;
+ ArchSpec arch;
+ if (m_objfile.GetArchitecture (arch))
+ {
+ if (arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb)
+ clear_address_zeroth_bit = true;
+ }
+
offset = indexSectionOffset;
for (uint32_t idx = 0; idx < indexCount; idx++)
{
@@ -324,8 +384,11 @@ CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp)
m_indexes_computed = eLazyBoolNo;
}
+ if (clear_address_zeroth_bit)
+ function_offset &= ~1ull;
+
UnwindIndex this_index;
- this_index.function_offset = function_offset; //
+ this_index.function_offset = function_offset;
this_index.second_level = second_level_offset;
this_index.lsda_array_start = lsda_offset;
@@ -352,7 +415,7 @@ CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp)
uint32_t
CompactUnwindInfo::GetLSDAForFunctionOffset (uint32_t lsda_offset, uint32_t lsda_count, uint32_t function_offset)
{
- // struct unwind_info_section_header_lsda_index_entry
+ // struct unwind_info_section_header_lsda_index_entry
// {
// uint32_t functionOffset;
// uint32_t lsdaOffset;
@@ -387,7 +450,7 @@ lldb::offset_t
CompactUnwindInfo::BinarySearchRegularSecondPage (uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset, uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset)
{
// typedef uint32_t compact_unwind_encoding_t;
- // struct unwind_info_regular_second_level_entry
+ // struct unwind_info_regular_second_level_entry
// {
// uint32_t functionOffset;
// compact_unwind_encoding_t encoding;
@@ -502,10 +565,10 @@ CompactUnwindInfo::GetCompactUnwindInfoForFunction (Target &target, Address addr
return false;
addr_t function_offset = address.GetFileAddress() - m_objfile.GetHeaderAddress().GetFileAddress();
-
+
UnwindIndex key;
key.function_offset = function_offset;
-
+
std::vector<UnwindIndex>::const_iterator it;
it = std::lower_bound (m_indexes.begin(), m_indexes.end(), key);
if (it == m_indexes.end())
@@ -527,7 +590,7 @@ CompactUnwindInfo::GetCompactUnwindInfoForFunction (Target &target, Address addr
auto next_it = it + 1;
if (next_it != m_indexes.end())
{
- // initialize the function offset end range to be the start of the
+ // initialize the function offset end range to be the start of the
// next index offset. If we find an entry which is at the end of
// the index table, this will establish the range end.
unwind_info.valid_range_offset_end = next_it->function_offset;
@@ -549,7 +612,7 @@ CompactUnwindInfo::GetCompactUnwindInfoForFunction (Target &target, Address addr
// uint16_t entryCount;
// typedef uint32_t compact_unwind_encoding_t;
- // struct unwind_info_regular_second_level_entry
+ // struct unwind_info_regular_second_level_entry
// {
// uint32_t functionOffset;
// compact_unwind_encoding_t encoding;
@@ -604,9 +667,9 @@ CompactUnwindInfo::GetCompactUnwindInfoForFunction (Target &target, Address addr
// uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED
// uint16_t entryPageOffset; // offset from this 2nd lvl page idx to array of entries
// // (an entry has a function offset and index into the encodings)
- // // NB function offset from the entry in the compressed page
+ // // NB function offset from the entry in the compressed page
// // must be added to the index's functionOffset value.
- // uint16_t entryCount;
+ // uint16_t entryCount;
// uint16_t encodingsPageOffset; // offset from this 2nd lvl page idx to array of encodings
// uint16_t encodingsCount;
@@ -626,7 +689,7 @@ CompactUnwindInfo::GetCompactUnwindInfoForFunction (Target &target, Address addr
offset = m_unwind_header.common_encodings_array_offset + (encoding_index * sizeof (uint32_t));
encoding = m_unwindinfo_data.GetU32(&offset); // encoding entry from the commonEncodingsArray
}
- else
+ else
{
uint32_t page_specific_entry_index = encoding_index - m_unwind_header.common_encodings_array_count;
offset = second_page_offset + encodings_page_offset + (page_specific_entry_index * sizeof (uint32_t));
@@ -742,7 +805,7 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi
row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rbp, wordsize * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rip, wordsize * -1, true);
row->SetRegisterLocationToIsCFAPlusOffset (x86_64_eh_regnum::rsp, 0, true);
-
+
uint32_t saved_registers_offset = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_RBP_FRAME_OFFSET);
uint32_t saved_registers_locations = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_RBP_FRAME_REGISTERS);
@@ -775,7 +838,7 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi
case UNWIND_X86_64_MODE_STACK_IND:
{
// The clang in Xcode 6 is emitting incorrect compact unwind encodings for this
- // style of unwind. It was fixed in llvm r217020.
+ // style of unwind. It was fixed in llvm r217020.
// The clang in Xcode 7 has this fixed.
return false;
}
@@ -838,7 +901,7 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi
// We need to include (up to) 6 registers in 10 bits.
// That would be 18 bits if we just used 3 bits per reg to indicate
- // the order they're saved on the stack.
+ // the order they're saved on the stack.
//
// This is done with Lehmer code permutation, e.g. see
// http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms
@@ -848,7 +911,7 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi
// and gives us the Lehmer code sequence which can then
// be decoded.
- switch (register_count)
+ switch (register_count)
{
case 6:
permunreg[0] = permutation/120; // 120 == 5!
@@ -898,7 +961,7 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi
permunreg[0] = permutation;
break;
}
-
+
// Decode the Lehmer code for this permutation of
// the registers v. http://en.wikipedia.org/wiki/Lehmer_code
@@ -1025,7 +1088,7 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function
row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::ebp, wordsize * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true);
row->SetRegisterLocationToIsCFAPlusOffset (i386_eh_regnum::esp, 0, true);
-
+
uint32_t saved_registers_offset = EXTRACT_BITS (function_info.encoding, UNWIND_X86_EBP_FRAME_OFFSET);
uint32_t saved_registers_locations = EXTRACT_BITS (function_info.encoding, UNWIND_X86_EBP_FRAME_REGISTERS);
@@ -1106,13 +1169,13 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function
row->SetOffset (0);
row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true);
row->SetRegisterLocationToIsCFAPlusOffset (i386_eh_regnum::esp, 0, true);
-
+
if (register_count > 0)
{
// We need to include (up to) 6 registers in 10 bits.
// That would be 18 bits if we just used 3 bits per reg to indicate
- // the order they're saved on the stack.
+ // the order they're saved on the stack.
//
// This is done with Lehmer code permutation, e.g. see
// http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms
@@ -1122,7 +1185,7 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function
// and gives us the Lehmer code sequence which can then
// be decoded.
- switch (register_count)
+ switch (register_count)
{
case 6:
permunreg[0] = permutation/120; // 120 == 5!
@@ -1172,7 +1235,7 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function
permunreg[0] = permutation;
break;
}
-
+
// Decode the Lehmer code for this permutation of
// the registers v. http://en.wikipedia.org/wiki/Lehmer_code
@@ -1231,3 +1294,380 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function
}
return false;
}
+
+
+
+// DWARF register numbers from "DWARF for the ARM 64-bit Architecture (AArch64)" doc by ARM
+
+enum arm64_eh_regnum {
+ x19 = 19,
+ x20 = 20,
+ x21 = 21,
+ x22 = 22,
+ x23 = 23,
+ x24 = 24,
+ x25 = 25,
+ x26 = 26,
+ x27 = 27,
+ x28 = 28,
+
+ fp = 29,
+ ra = 30,
+ sp = 31,
+ pc = 32,
+
+ // Compact unwind encodes d8-d15 but we don't have eh_frame / dwarf reg #'s for the 64-bit
+ // fp regs. Normally in DWARF it's context sensitive - so it knows it is fetching a
+ // 32- or 64-bit quantity from reg v8 to indicate s0 or d0 - but the unwinder is operating
+ // at a lower level and we'd try to fetch 128 bits if we were told that v8 were stored on
+ // the stack...
+ v8 = 72,
+ v9 = 73,
+ v10 = 74,
+ v11 = 75,
+ v12 = 76,
+ v13 = 77,
+ v14 = 78,
+ v15 = 79,
+};
+
+enum arm_eh_regnum {
+ arm_r0 = 0,
+ arm_r1 = 1,
+ arm_r2 = 2,
+ arm_r3 = 3,
+ arm_r4 = 4,
+ arm_r5 = 5,
+ arm_r6 = 6,
+ arm_r7 = 7,
+ arm_r8 = 8,
+ arm_r9 = 9,
+ arm_r10 = 10,
+ arm_r11 = 11,
+ arm_r12 = 12,
+
+ arm_sp = 13,
+ arm_lr = 14,
+ arm_pc = 15,
+
+ arm_d0 = 256,
+ arm_d1 = 257,
+ arm_d2 = 258,
+ arm_d3 = 259,
+ arm_d4 = 260,
+ arm_d5 = 261,
+ arm_d6 = 262,
+ arm_d7 = 263,
+ arm_d8 = 264,
+ arm_d9 = 265,
+ arm_d10 = 266,
+ arm_d11 = 267,
+ arm_d12 = 268,
+ arm_d13 = 269,
+ arm_d14 = 270,
+};
+
+
+
+bool
+CompactUnwindInfo::CreateUnwindPlan_arm64 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
+{
+ unwind_plan.SetSourceName ("compact unwind info");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolYes);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
+ unwind_plan.SetRegisterKind (eRegisterKindEHFrame);
+
+ unwind_plan.SetLSDAAddress (function_info.lsda_address);
+ unwind_plan.SetPersonalityFunctionPtr (function_info.personality_ptr_address);
+
+ UnwindPlan::RowSP row (new UnwindPlan::Row);
+
+ const int wordsize = 8;
+ int mode = function_info.encoding & UNWIND_ARM64_MODE_MASK;
+
+ if (mode == UNWIND_ARM64_MODE_DWARF)
+ return false;
+
+ if (mode == UNWIND_ARM64_MODE_FRAMELESS)
+ {
+ row->SetOffset (0);
+
+ uint32_t stack_size = (EXTRACT_BITS (function_info.encoding, UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK)) * 16;
+
+ // Our previous Call Frame Address is the stack pointer plus the stack size
+ row->GetCFAValue().SetIsRegisterPlusOffset (arm64_eh_regnum::sp, stack_size);
+
+ // Our previous PC is in the LR
+ row->SetRegisterLocationToRegister(arm64_eh_regnum::pc, arm64_eh_regnum::ra, true);
+
+ unwind_plan.AppendRow (row);
+ return true;
+ }
+
+ // Should not be possible
+ if (mode != UNWIND_ARM64_MODE_FRAME)
+ return false;
+
+
+ // mode == UNWIND_ARM64_MODE_FRAME
+
+ row->GetCFAValue().SetIsRegisterPlusOffset (arm64_eh_regnum::fp , 2 * wordsize);
+ row->SetOffset (0);
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::fp, wordsize * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::pc, wordsize * -1, true);
+ row->SetRegisterLocationToIsCFAPlusOffset (arm64_eh_regnum::sp, 0, true);
+
+ int reg_pairs_saved_count = 1;
+
+ uint32_t saved_register_bits = function_info.encoding & 0xfff;
+
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X19_X20_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x19, cfa_offset, true);
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x20, cfa_offset, true);
+ reg_pairs_saved_count++;
+ }
+
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X21_X22_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x21, cfa_offset, true);
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x22, cfa_offset, true);
+ reg_pairs_saved_count++;
+ }
+
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X23_X24_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x23, cfa_offset, true);
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x24, cfa_offset, true);
+ reg_pairs_saved_count++;
+ }
+
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X25_X26_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x25, cfa_offset, true);
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x26, cfa_offset, true);
+ reg_pairs_saved_count++;
+ }
+
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X27_X28_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x27, cfa_offset, true);
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x28, cfa_offset, true);
+ reg_pairs_saved_count++;
+ }
+
+ // If we use the v8-v15 regnums here, the unwinder will try to grab 128 bits off the stack;
+ // not sure if we have a good way to represent the 64-bitness of these saves.
+
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D8_D9_PAIR)
+ {
+ reg_pairs_saved_count++;
+ }
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D10_D11_PAIR)
+ {
+ reg_pairs_saved_count++;
+ }
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D12_D13_PAIR)
+ {
+ reg_pairs_saved_count++;
+ }
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D14_D15_PAIR)
+ {
+ reg_pairs_saved_count++;
+ }
+
+ unwind_plan.AppendRow (row);
+ return true;
+}
+
+bool
+CompactUnwindInfo::CreateUnwindPlan_armv7 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
+{
+ unwind_plan.SetSourceName ("compact unwind info");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolYes);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
+ unwind_plan.SetRegisterKind (eRegisterKindEHFrame);
+
+ unwind_plan.SetLSDAAddress (function_info.lsda_address);
+ unwind_plan.SetPersonalityFunctionPtr (function_info.personality_ptr_address);
+
+ UnwindPlan::RowSP row (new UnwindPlan::Row);
+
+ const int wordsize = 4;
+ int mode = function_info.encoding & UNWIND_ARM_MODE_MASK;
+
+ if (mode == UNWIND_ARM_MODE_DWARF)
+ return false;
+
+ uint32_t stack_adjust = (EXTRACT_BITS (function_info.encoding, UNWIND_ARM_FRAME_STACK_ADJUST_MASK)) * wordsize;
+
+ row->GetCFAValue().SetIsRegisterPlusOffset (arm_r7 , (2 * wordsize) + stack_adjust);
+ row->SetOffset (0);
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r7, (wordsize * -2) - stack_adjust, true);
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_pc, (wordsize * -1) - stack_adjust, true);
+ row->SetRegisterLocationToIsCFAPlusOffset (arm_sp, 0, true);
+
+ int cfa_offset = -stack_adjust - (2 * wordsize);
+
+ uint32_t saved_register_bits = function_info.encoding & 0xff;
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R6)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r6, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R5)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r5, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R4)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r4, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R12)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r12, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R11)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r11, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R10)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r10, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R9)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r9, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R8)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r8, cfa_offset, true);
+ }
+
+
+ if (mode == UNWIND_ARM_MODE_FRAME_D)
+ {
+ uint32_t d_reg_bits = EXTRACT_BITS (function_info.encoding, UNWIND_ARM_FRAME_D_REG_COUNT_MASK);
+ switch (d_reg_bits)
+ {
+ case 0:
+ // vpush {d8}
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d8, cfa_offset, true);
+ break;
+ case 1:
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d10, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d8, cfa_offset, true);
+ break;
+ case 2:
+ // vpush {d12}
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d12, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d10, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d8, cfa_offset, true);
+ break;
+ case 3:
+ // vpush {d14}
+ // vpush {d12}
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d14, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d12, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d10, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d8, cfa_offset, true);
+ break;
+ case 4:
+ // vpush {d14}
+ // vpush {d12}
+ // sp = (sp - 24) & (-16);
+ // vst {d8, d9, d10}
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d14, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d12, cfa_offset, true);
+
+ // FIXME we don't have a way to represent reg saves at an specific alignment short of
+ // coming up with some DWARF location description.
+
+ break;
+ case 5:
+ // vpush {d14}
+ // sp = (sp - 40) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12}
+
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d14, cfa_offset, true);
+
+ // FIXME we don't have a way to represent reg saves at an specific alignment short of
+ // coming up with some DWARF location description.
+
+ break;
+ case 6:
+ // sp = (sp - 56) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12, d13, d14}
+
+ // FIXME we don't have a way to represent reg saves at an specific alignment short of
+ // coming up with some DWARF location description.
+
+ break;
+ case 7:
+ // sp = (sp - 64) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12, d13, d14, d15}
+
+ // FIXME we don't have a way to represent reg saves at an specific alignment short of
+ // coming up with some DWARF location description.
+
+ break;
+ }
+ }
+
+ unwind_plan.AppendRow (row);
+ return true;
+}
+
+
diff --git a/source/Symbol/CompileUnit.cpp b/source/Symbol/CompileUnit.cpp
index 50eda8806375..259a450b7165 100644
--- a/source/Symbol/CompileUnit.cpp
+++ b/source/Symbol/CompileUnit.cpp
@@ -17,36 +17,40 @@
using namespace lldb;
using namespace lldb_private;
-CompileUnit::CompileUnit (const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, const lldb::user_id_t cu_sym_id, lldb::LanguageType language, bool is_optimized) :
- ModuleChild(module_sp),
- FileSpec (pathname, false),
- UserID(cu_sym_id),
- m_user_data (user_data),
- m_language (language),
- m_flags (0),
- m_functions (),
- m_support_files (),
- m_line_table_ap (),
- m_variables(),
- m_is_optimized (is_optimized)
+CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname,
+ const lldb::user_id_t cu_sym_id, lldb::LanguageType language,
+ lldb_private::LazyBool is_optimized)
+ : ModuleChild(module_sp),
+ FileSpec(pathname, false),
+ UserID(cu_sym_id),
+ m_user_data(user_data),
+ m_language(language),
+ m_flags(0),
+ m_functions(),
+ m_support_files(),
+ m_line_table_ap(),
+ m_variables(),
+ m_is_optimized(is_optimized)
{
if (language != eLanguageTypeUnknown)
m_flags.Set(flagsParsedLanguage);
assert(module_sp);
}
-CompileUnit::CompileUnit (const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &fspec, const lldb::user_id_t cu_sym_id, lldb::LanguageType language, bool is_optimized) :
- ModuleChild(module_sp),
- FileSpec (fspec),
- UserID(cu_sym_id),
- m_user_data (user_data),
- m_language (language),
- m_flags (0),
- m_functions (),
- m_support_files (),
- m_line_table_ap (),
- m_variables(),
- m_is_optimized (is_optimized)
+CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &fspec,
+ const lldb::user_id_t cu_sym_id, lldb::LanguageType language,
+ lldb_private::LazyBool is_optimized)
+ : ModuleChild(module_sp),
+ FileSpec(fspec),
+ UserID(cu_sym_id),
+ m_user_data(user_data),
+ m_language(language),
+ m_flags(0),
+ m_functions(),
+ m_support_files(),
+ m_line_table_ap(),
+ m_variables(),
+ m_is_optimized(is_optimized)
{
if (language != eLanguageTypeUnknown)
m_flags.Set(flagsParsedLanguage);
@@ -468,6 +472,17 @@ CompileUnit::ResolveSymbolContext
bool
CompileUnit::GetIsOptimized ()
{
+ if (m_is_optimized == eLazyBoolCalculate)
+ {
+ m_is_optimized = eLazyBoolNo;
+ if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor())
+ {
+ SymbolContext sc;
+ CalculateSymbolContext(&sc);
+ if (symbol_vendor->ParseCompileUnitIsOptimized(sc))
+ m_is_optimized = eLazyBoolYes;
+ }
+ }
return m_is_optimized;
}
diff --git a/source/Symbol/CompilerDecl.cpp b/source/Symbol/CompilerDecl.cpp
index 42e5fb081071..98eef060df0e 100644
--- a/source/Symbol/CompilerDecl.cpp
+++ b/source/Symbol/CompilerDecl.cpp
@@ -31,12 +31,6 @@ CompilerDecl::GetMangledName () const
return m_type_system->DeclGetMangledName(m_opaque_decl);
}
-lldb::VariableSP
-CompilerDecl::GetAsVariable ()
-{
- return m_type_system->DeclGetVariable(m_opaque_decl);
-}
-
CompilerDeclContext
CompilerDecl::GetDeclContext() const
{
diff --git a/source/Symbol/CompilerDeclContext.cpp b/source/Symbol/CompilerDeclContext.cpp
index 8bee1b48753a..10a70d97f231 100644
--- a/source/Symbol/CompilerDeclContext.cpp
+++ b/source/Symbol/CompilerDeclContext.cpp
@@ -15,10 +15,11 @@
using namespace lldb_private;
std::vector<CompilerDecl>
-CompilerDeclContext::FindDeclByName (ConstString name)
+CompilerDeclContext::FindDeclByName (ConstString name, const bool ignore_using_decls)
{
if (IsValid())
- return m_type_system->DeclContextFindDeclByName(m_opaque_decl_ctx, name);
+ return m_type_system->DeclContextFindDeclByName(
+ m_opaque_decl_ctx, name, ignore_using_decls);
else
return std::vector<CompilerDecl>();
}
diff --git a/source/Symbol/CompilerType.cpp b/source/Symbol/CompilerType.cpp
index 000a949626c5..2b06c93c3f0d 100644
--- a/source/Symbol/CompilerType.cpp
+++ b/source/Symbol/CompilerType.cpp
@@ -177,7 +177,14 @@ CompilerType::IsFunctionPointerType () const
if (IsValid())
return m_type_system->IsFunctionPointerType(m_type);
return false;
+}
+bool
+CompilerType::IsBlockPointerType (CompilerType *function_pointer_type_ptr) const
+{
+ if (IsValid())
+ return m_type_system->IsBlockPointerType(m_type, function_pointer_type_ptr);
+ return 0;
}
bool
@@ -189,6 +196,20 @@ CompilerType::IsIntegerType (bool &is_signed) const
}
bool
+CompilerType::IsEnumerationType (bool &is_signed) const
+{
+ if (IsValid())
+ return m_type_system->IsEnumerationType(m_type, is_signed);
+ return false;
+}
+
+bool
+CompilerType::IsIntegerOrEnumerationType (bool &is_signed) const
+{
+ return IsIntegerType(is_signed) || IsEnumerationType(is_signed);
+}
+
+bool
CompilerType::IsPointerType (CompilerType *pointee_type) const
{
if (IsValid())
diff --git a/source/Symbol/DWARFCallFrameInfo.cpp b/source/Symbol/DWARFCallFrameInfo.cpp
index c357a5001690..6a4004bb7902 100644
--- a/source/Symbol/DWARFCallFrameInfo.cpp
+++ b/source/Symbol/DWARFCallFrameInfo.cpp
@@ -308,14 +308,22 @@ DWARFCallFrameInfo::GetFDEIndex ()
if (m_fde_index_initialized)
return;
-
- Mutex::Locker locker(m_fde_index_mutex);
-
+
+ std::lock_guard<std::mutex> guard(m_fde_index_mutex);
+
if (m_fde_index_initialized) // if two threads hit the locker
return;
Timer scoped_timer (__PRETTY_FUNCTION__, "%s - %s", __PRETTY_FUNCTION__, m_objfile.GetFileSpec().GetFilename().AsCString(""));
+ bool clear_address_zeroth_bit = false;
+ ArchSpec arch;
+ if (m_objfile.GetArchitecture (arch))
+ {
+ if (arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb)
+ clear_address_zeroth_bit = true;
+ }
+
lldb::offset_t offset = 0;
if (m_cfi_data_initialized == false)
GetCFIData();
@@ -376,6 +384,9 @@ DWARFCallFrameInfo::GetFDEIndex ()
const lldb::addr_t data_addr = LLDB_INVALID_ADDRESS;
lldb::addr_t addr = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding, pc_rel_addr, text_addr, data_addr);
+ if (clear_address_zeroth_bit)
+ addr &= ~1ull;
+
lldb::addr_t length = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding & DW_EH_PE_MASK_ENCODING, pc_rel_addr, text_addr, data_addr);
FDEEntryMap::Entry fde (addr, length, current_entry);
m_fde_index.Append(fde);
@@ -397,6 +408,7 @@ DWARFCallFrameInfo::GetFDEIndex ()
bool
DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr, UnwindPlan& unwind_plan)
{
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND);
lldb::offset_t offset = dwarf_offset;
lldb::offset_t current_entry = offset;
@@ -637,6 +649,15 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr
// the stack and place them in the current row. (This operation is
// useful for compilers that move epilogue code into the body of a
// function.)
+ if (stack.empty())
+ {
+ if (log)
+ log->Printf(
+ "DWARFCallFrameInfo::%s(dwarf_offset: %" PRIx32 ", startaddr: %" PRIx64
+ " encountered DW_CFA_restore_state but state stack is empty. Corrupt unwind info?",
+ __FUNCTION__, dwarf_offset, startaddr.GetFileAddress());
+ break;
+ }
lldb::addr_t offset = row->GetOffset ();
row = stack.back ();
stack.pop_back ();
@@ -644,6 +665,17 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr
break;
}
+ case DW_CFA_GNU_args_size: // 0x2e
+ {
+ // The DW_CFA_GNU_args_size instruction takes an unsigned LEB128 operand
+ // representing an argument size. This instruction specifies the total of
+ // the size of the arguments which have been pushed onto the stack.
+
+ // TODO: Figure out how we should handle this.
+ m_cfi_data.GetULEB128(&offset);
+ break;
+ }
+
case DW_CFA_val_offset : // 0x14
case DW_CFA_val_offset_sf : // 0x15
default:
@@ -899,3 +931,17 @@ DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
}
return false;
}
+
+void
+DWARFCallFrameInfo::ForEachFDEEntries(
+ const std::function<bool(lldb::addr_t, uint32_t, dw_offset_t)>& callback)
+{
+ GetFDEIndex();
+
+ for (size_t i = 0, c = m_fde_index.GetSize(); i < c; ++i)
+ {
+ const FDEEntryMap::Entry& entry = m_fde_index.GetEntryRef(i);
+ if (!callback(entry.base, entry.size, entry.data))
+ break;
+ }
+}
diff --git a/source/Symbol/FuncUnwinders.cpp b/source/Symbol/FuncUnwinders.cpp
index 4c96b1a2bb1b..2fa41b84cb25 100644
--- a/source/Symbol/FuncUnwinders.cpp
+++ b/source/Symbol/FuncUnwinders.cpp
@@ -22,6 +22,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnwindAssembly.h"
+#include "lldb/Utility/RegisterNumber.h"
using namespace lldb;
using namespace lldb_private;
@@ -30,27 +31,27 @@ using namespace lldb_private;
/// constructor
//------------------------------------------------
-FuncUnwinders::FuncUnwinders (UnwindTable& unwind_table, AddressRange range) :
- m_unwind_table (unwind_table),
- m_range (range),
- m_mutex (Mutex::eMutexTypeRecursive),
- m_unwind_plan_assembly_sp (),
- m_unwind_plan_eh_frame_sp (),
- m_unwind_plan_eh_frame_augmented_sp (),
- m_unwind_plan_compact_unwind (),
- m_unwind_plan_arm_unwind_sp (),
- m_unwind_plan_fast_sp (),
- m_unwind_plan_arch_default_sp (),
- m_unwind_plan_arch_default_at_func_entry_sp (),
- m_tried_unwind_plan_assembly (false),
- m_tried_unwind_plan_eh_frame (false),
- m_tried_unwind_plan_eh_frame_augmented (false),
- m_tried_unwind_plan_compact_unwind (false),
- m_tried_unwind_plan_arm_unwind (false),
- m_tried_unwind_fast (false),
- m_tried_unwind_arch_default (false),
- m_tried_unwind_arch_default_at_func_entry (false),
- m_first_non_prologue_insn ()
+FuncUnwinders::FuncUnwinders(UnwindTable &unwind_table, AddressRange range)
+ : m_unwind_table(unwind_table),
+ m_range(range),
+ m_mutex(),
+ m_unwind_plan_assembly_sp(),
+ m_unwind_plan_eh_frame_sp(),
+ m_unwind_plan_eh_frame_augmented_sp(),
+ m_unwind_plan_compact_unwind(),
+ m_unwind_plan_arm_unwind_sp(),
+ m_unwind_plan_fast_sp(),
+ m_unwind_plan_arch_default_sp(),
+ m_unwind_plan_arch_default_at_func_entry_sp(),
+ m_tried_unwind_plan_assembly(false),
+ m_tried_unwind_plan_eh_frame(false),
+ m_tried_unwind_plan_eh_frame_augmented(false),
+ m_tried_unwind_plan_compact_unwind(false),
+ m_tried_unwind_plan_arm_unwind(false),
+ m_tried_unwind_fast(false),
+ m_tried_unwind_arch_default(false),
+ m_tried_unwind_arch_default_at_func_entry(false),
+ m_first_non_prologue_insn()
{
}
@@ -65,7 +66,7 @@ FuncUnwinders::~FuncUnwinders ()
UnwindPlanSP
FuncUnwinders::GetUnwindPlanAtCallSite (Target &target, int current_offset)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan (target, current_offset);
if (unwind_plan_sp)
@@ -90,7 +91,7 @@ FuncUnwinders::GetCompactUnwindUnwindPlan (Target &target, int current_offset)
if (m_tried_unwind_plan_compact_unwind)
return UnwindPlanSP();
- Mutex::Locker lock (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_plan_compact_unwind = true;
if (m_range.GetBaseAddress().IsValid())
{
@@ -117,7 +118,7 @@ FuncUnwinders::GetEHFrameUnwindPlan (Target &target, int current_offset)
if (m_unwind_plan_eh_frame_sp.get() || m_tried_unwind_plan_eh_frame)
return m_unwind_plan_eh_frame_sp;
- Mutex::Locker lock (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_plan_eh_frame = true;
if (m_range.GetBaseAddress().IsValid())
{
@@ -141,7 +142,7 @@ FuncUnwinders::GetArmUnwindUnwindPlan (Target &target, int current_offset)
if (m_unwind_plan_arm_unwind_sp.get() || m_tried_unwind_plan_arm_unwind)
return m_unwind_plan_arm_unwind_sp;
- Mutex::Locker lock (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_plan_arm_unwind = true;
if (m_range.GetBaseAddress().IsValid())
{
@@ -175,7 +176,7 @@ FuncUnwinders::GetEHFrameAugmentedUnwindPlan (Target &target, Thread &thread, in
return m_unwind_plan_eh_frame_augmented_sp;
}
- Mutex::Locker lock (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_plan_eh_frame_augmented = true;
UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan (target, current_offset);
@@ -206,10 +207,14 @@ FuncUnwinders::GetEHFrameAugmentedUnwindPlan (Target &target, Thread &thread, in
UnwindPlanSP
FuncUnwinders::GetAssemblyUnwindPlan (Target &target, Thread &thread, int current_offset)
{
- if (m_unwind_plan_assembly_sp.get() || m_tried_unwind_plan_assembly)
+ if (m_unwind_plan_assembly_sp.get()
+ || m_tried_unwind_plan_assembly
+ || m_unwind_table.GetAllowAssemblyEmulationUnwindPlans () == false)
+ {
return m_unwind_plan_assembly_sp;
+ }
- Mutex::Locker lock (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_plan_assembly = true;
UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
@@ -224,16 +229,81 @@ FuncUnwinders::GetAssemblyUnwindPlan (Target &target, Thread &thread, int curren
return m_unwind_plan_assembly_sp;
}
+// This method compares the pc unwind rule in the first row of two UnwindPlans.
+// If they have the same way of getting the pc value (e.g. "CFA - 8" + "CFA is sp"),
+// then it will return LazyBoolTrue.
+LazyBool
+FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation (Thread& thread, const UnwindPlanSP &a, const UnwindPlanSP &b)
+{
+ LazyBool plans_are_identical = eLazyBoolCalculate;
+
+ RegisterNumber pc_reg (thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ uint32_t pc_reg_lldb_regnum = pc_reg.GetAsKind (eRegisterKindLLDB);
+
+ if (a.get() && b.get())
+ {
+ UnwindPlan::RowSP a_first_row = a->GetRowAtIndex (0);
+ UnwindPlan::RowSP b_first_row = b->GetRowAtIndex (0);
+
+ if (a_first_row.get() && b_first_row.get())
+ {
+ UnwindPlan::Row::RegisterLocation a_pc_regloc;
+ UnwindPlan::Row::RegisterLocation b_pc_regloc;
+
+ a_first_row->GetRegisterInfo (pc_reg_lldb_regnum, a_pc_regloc);
+ b_first_row->GetRegisterInfo (pc_reg_lldb_regnum, b_pc_regloc);
+
+ plans_are_identical = eLazyBoolYes;
+
+ if (a_first_row->GetCFAValue() != b_first_row->GetCFAValue())
+ {
+ plans_are_identical = eLazyBoolNo;
+ }
+ if (a_pc_regloc != b_pc_regloc)
+ {
+ plans_are_identical = eLazyBoolNo;
+ }
+ }
+ }
+ return plans_are_identical;
+}
UnwindPlanSP
FuncUnwinders::GetUnwindPlanAtNonCallSite (Target& target, Thread& thread, int current_offset)
{
- UnwindPlanSP non_call_site_unwindplan_sp = GetEHFrameAugmentedUnwindPlan (target, thread, current_offset);
- if (non_call_site_unwindplan_sp.get() == nullptr)
+ UnwindPlanSP eh_frame_sp = GetEHFrameUnwindPlan (target, current_offset);
+ UnwindPlanSP arch_default_at_entry_sp = GetUnwindPlanArchitectureDefaultAtFunctionEntry (thread);
+ UnwindPlanSP arch_default_sp = GetUnwindPlanArchitectureDefault (thread);
+ UnwindPlanSP assembly_sp = GetAssemblyUnwindPlan (target, thread, current_offset);
+
+ // This point of this code is to detect when a function is using a non-standard ABI, and the eh_frame
+ // correctly describes that alternate ABI. This is addressing a specific situation on x86_64 linux
+ // systems where one function in a library pushes a value on the stack and jumps to another function.
+ // So using an assembly instruction based unwind will not work when you're in the second function -
+ // the stack has been modified in a non-ABI way. But we have eh_frame that correctly describes how to
+ // unwind from this location. So we're looking to see if the initial pc register save location from
+ // the eh_frame is different from the assembly unwind, the arch default unwind, and the arch default at
+ // initial function entry.
+ //
+ // We may have eh_frame that describes the entire function -- or we may have eh_frame that only describes
+ // the unwind after the prologue has executed -- so we need to check both the arch default (once the prologue
+ // has executed) and the arch default at initial function entry. And we may be running on a target where
+ // we have only some of the assembly/arch default unwind plans available.
+
+ if (CompareUnwindPlansForIdenticalInitialPCLocation (thread, eh_frame_sp, arch_default_at_entry_sp) == eLazyBoolNo
+ && CompareUnwindPlansForIdenticalInitialPCLocation (thread, eh_frame_sp, arch_default_sp) == eLazyBoolNo
+ && CompareUnwindPlansForIdenticalInitialPCLocation (thread, assembly_sp, arch_default_sp) == eLazyBoolNo)
{
- non_call_site_unwindplan_sp = GetAssemblyUnwindPlan (target, thread, current_offset);
+ return eh_frame_sp;
}
- return non_call_site_unwindplan_sp;
+
+ UnwindPlanSP eh_frame_augmented_sp = GetEHFrameAugmentedUnwindPlan (target, thread, current_offset);
+ if (eh_frame_augmented_sp)
+ {
+ return eh_frame_augmented_sp;
+ }
+
+ return assembly_sp;
}
UnwindPlanSP
@@ -242,7 +312,7 @@ FuncUnwinders::GetUnwindPlanFastUnwind (Target& target, Thread& thread)
if (m_unwind_plan_fast_sp.get() || m_tried_unwind_fast)
return m_unwind_plan_fast_sp;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_fast = true;
UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
@@ -263,7 +333,7 @@ FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread)
if (m_unwind_plan_arch_default_sp.get() || m_tried_unwind_arch_default)
return m_unwind_plan_arch_default_sp;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_arch_default = true;
Address current_pc;
@@ -290,7 +360,7 @@ FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry (Thread& thread)
if (m_unwind_plan_arch_default_at_func_entry_sp.get() || m_tried_unwind_arch_default_at_func_entry)
return m_unwind_plan_arch_default_at_func_entry_sp;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_arch_default_at_func_entry = true;
Address current_pc;
@@ -318,7 +388,7 @@ FuncUnwinders::GetFirstNonPrologueInsn (Target& target)
if (m_first_non_prologue_insn.IsValid())
return m_first_non_prologue_insn;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
ExecutionContext exe_ctx (target.shared_from_this(), false);
UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
if (assembly_profiler_sp)
diff --git a/source/Symbol/Function.cpp b/source/Symbol/Function.cpp
index 33cc0c4e264c..598af270bddf 100644
--- a/source/Symbol/Function.cpp
+++ b/source/Symbol/Function.cpp
@@ -570,6 +570,8 @@ Function::GetPrologueByteSize ()
{
m_flags.Set(flagsCalculatedPrologueSize);
LineTable* line_table = m_comp_unit->GetLineTable ();
+ uint32_t prologue_end_line_idx = 0;
+
if (line_table)
{
LineEntry first_line_entry;
@@ -578,9 +580,12 @@ Function::GetPrologueByteSize ()
{
// Make sure the first line entry isn't already the end of the prologue
addr_t prologue_end_file_addr = LLDB_INVALID_ADDRESS;
+ addr_t line_zero_end_file_addr = LLDB_INVALID_ADDRESS;
+
if (first_line_entry.is_prologue_end)
{
prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress();
+ prologue_end_line_idx = first_line_entry_idx;
}
else
{
@@ -595,6 +600,7 @@ Function::GetPrologueByteSize ()
if (line_entry.is_prologue_end)
{
prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress();
+ prologue_end_line_idx = idx;
break;
}
}
@@ -607,7 +613,7 @@ Function::GetPrologueByteSize ()
{
// Check the first few instructions and look for one that has
// a line number that's different than the first entry.
- const uint32_t last_line_entry_idx = first_line_entry_idx + 6;
+ uint32_t last_line_entry_idx = first_line_entry_idx + 6;
for (uint32_t idx = first_line_entry_idx + 1; idx < last_line_entry_idx; ++idx)
{
LineEntry line_entry;
@@ -616,6 +622,7 @@ Function::GetPrologueByteSize ()
if (line_entry.line != first_line_entry.line)
{
prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress();
+ prologue_end_line_idx = idx;
break;
}
}
@@ -624,10 +631,37 @@ Function::GetPrologueByteSize ()
if (prologue_end_file_addr == LLDB_INVALID_ADDRESS)
{
prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress() + first_line_entry.range.GetByteSize();
+ prologue_end_line_idx = first_line_entry_idx;
}
}
+
const addr_t func_start_file_addr = m_range.GetBaseAddress().GetFileAddress();
const addr_t func_end_file_addr = func_start_file_addr + m_range.GetByteSize();
+
+ // Now calculate the offset to pass the subsequent line 0 entries.
+ uint32_t first_non_zero_line = prologue_end_line_idx;
+ while (1)
+ {
+ LineEntry line_entry;
+ if (line_table->GetLineEntryAtIndex(first_non_zero_line, line_entry))
+ {
+ if (line_entry.line != 0)
+ break;
+ }
+ if (line_entry.range.GetBaseAddress().GetFileAddress() >= func_end_file_addr)
+ break;
+
+ first_non_zero_line++;
+ }
+
+ if (first_non_zero_line > prologue_end_line_idx)
+ {
+ LineEntry first_non_zero_entry;
+ if (line_table->GetLineEntryAtIndex(first_non_zero_line, first_non_zero_entry))
+ {
+ line_zero_end_file_addr = first_non_zero_entry.range.GetBaseAddress().GetFileAddress();
+ }
+ }
// Verify that this prologue end file address in the function's
// address range just to be sure
@@ -635,10 +669,16 @@ Function::GetPrologueByteSize ()
{
m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
}
+
+ if (prologue_end_file_addr < line_zero_end_file_addr && line_zero_end_file_addr < func_end_file_addr)
+ {
+ m_prologue_byte_size += line_zero_end_file_addr - prologue_end_file_addr;
+ }
}
}
}
- return m_prologue_byte_size;
+
+ return m_prologue_byte_size;
}
lldb::LanguageType
diff --git a/source/Symbol/GoASTContext.cpp b/source/Symbol/GoASTContext.cpp
index 1993f2331058..faca778f069c 100644
--- a/source/Symbol/GoASTContext.cpp
+++ b/source/Symbol/GoASTContext.cpp
@@ -538,6 +538,12 @@ GoASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type)
}
bool
+GoASTContext::IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr)
+{
+ return false;
+}
+
+bool
GoASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed)
{
is_signed = false;
diff --git a/source/Symbol/JavaASTContext.cpp b/source/Symbol/JavaASTContext.cpp
new file mode 100644
index 000000000000..45cda8d5112b
--- /dev/null
+++ b/source/Symbol/JavaASTContext.cpp
@@ -0,0 +1,1561 @@
+//===-- JavaASTContext.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <sstream>
+
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Symbol/JavaASTContext.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Target/Target.h"
+
+#include "Plugins/SymbolFile/DWARF/DWARFASTParserJava.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace lldb_private
+{
+
+class JavaASTContext::JavaType
+{
+public:
+ enum LLVMCastKind
+ {
+ eKindPrimitive,
+ eKindObject,
+ eKindReference,
+ eKindArray,
+ kNumKinds
+ };
+
+ JavaType(LLVMCastKind kind) : m_kind(kind) {}
+
+ virtual ~JavaType() = default;
+
+ virtual ConstString
+ GetName() = 0;
+
+ virtual void
+ Dump(Stream *s) = 0;
+
+ virtual bool
+ IsCompleteType() = 0;
+
+ LLVMCastKind
+ getKind() const
+ {
+ return m_kind;
+ }
+
+private:
+ LLVMCastKind m_kind;
+};
+
+} // end of namespace lldb_private
+
+namespace
+{
+
+class JavaPrimitiveType : public JavaASTContext::JavaType
+{
+public:
+ enum TypeKind
+ {
+ eTypeByte,
+ eTypeShort,
+ eTypeInt,
+ eTypeLong,
+ eTypeFloat,
+ eTypeDouble,
+ eTypeBoolean,
+ eTypeChar,
+ };
+
+ JavaPrimitiveType(TypeKind type_kind) : JavaType(JavaType::eKindPrimitive), m_type_kind(type_kind) {}
+
+ ConstString
+ GetName() override
+ {
+ switch (m_type_kind)
+ {
+ case eTypeByte:
+ return ConstString("byte");
+ case eTypeShort:
+ return ConstString("short");
+ case eTypeInt:
+ return ConstString("int");
+ case eTypeLong:
+ return ConstString("long");
+ case eTypeFloat:
+ return ConstString("float");
+ case eTypeDouble:
+ return ConstString("double");
+ case eTypeBoolean:
+ return ConstString("boolean");
+ case eTypeChar:
+ return ConstString("char");
+ }
+ return ConstString();
+ }
+
+ TypeKind
+ GetTypeKind()
+ {
+ return m_type_kind;
+ }
+
+ void
+ Dump(Stream *s) override
+ {
+ s->Printf("%s\n", GetName().GetCString());
+ }
+
+ bool
+ IsCompleteType() override
+ {
+ return true;
+ }
+
+ static bool
+ classof(const JavaType *jt)
+ {
+ return jt->getKind() == JavaType::eKindPrimitive;
+ }
+
+private:
+ const TypeKind m_type_kind;
+};
+
+class JavaDynamicType : public JavaASTContext::JavaType
+{
+public:
+ JavaDynamicType(LLVMCastKind kind, const ConstString &linkage_name) :
+ JavaType(kind),
+ m_linkage_name(linkage_name),
+ m_dynamic_type_id(nullptr)
+ {
+ }
+
+ ConstString
+ GetLinkageName() const
+ {
+ return m_linkage_name;
+ }
+
+ void
+ SetDynamicTypeId(const DWARFExpression &type_id)
+ {
+ m_dynamic_type_id = type_id;
+ }
+
+ uint64_t
+ CalculateDynamicTypeId(ExecutionContext *exe_ctx, ValueObject &value_obj)
+ {
+ if (!m_dynamic_type_id.IsValid())
+ return UINT64_MAX;
+
+ Value obj_load_address = value_obj.GetValue();
+ obj_load_address.ResolveValue(exe_ctx);
+ obj_load_address.SetValueType(Value::eValueTypeLoadAddress);
+
+ Value result;
+ if (m_dynamic_type_id.Evaluate(exe_ctx->GetBestExecutionContextScope(), nullptr, nullptr, 0, &obj_load_address,
+ nullptr, result, nullptr))
+ {
+ Error error;
+
+ lldb::addr_t type_id_addr = result.GetScalar().UInt();
+ lldb::ProcessSP process_sp = exe_ctx->GetProcessSP();
+ if (process_sp)
+ return process_sp->ReadUnsignedIntegerFromMemory(type_id_addr, process_sp->GetAddressByteSize(),
+ UINT64_MAX, error);
+ }
+
+ return UINT64_MAX;
+ }
+
+public:
+ ConstString m_linkage_name;
+ DWARFExpression m_dynamic_type_id;
+};
+
+class JavaObjectType : public JavaDynamicType
+{
+public:
+ struct Field
+ {
+ ConstString m_name;
+ CompilerType m_type;
+ uint32_t m_offset;
+ };
+
+ JavaObjectType(const ConstString &name, const ConstString &linkage_name, uint32_t byte_size)
+ : JavaDynamicType(JavaType::eKindObject, linkage_name),
+ m_name(name),
+ m_byte_size(byte_size),
+ m_base_class_offset(0),
+ m_is_complete(false)
+ {
+ }
+
+ ConstString
+ GetName() override
+ {
+ return m_name;
+ }
+
+ uint32_t
+ GetByteSize() const
+ {
+ return m_byte_size;
+ }
+
+ uint32_t
+ GetNumFields()
+ {
+ return m_fields.size();
+ }
+
+ void
+ Dump(Stream *s) override
+ {
+ if (m_base_class.IsValid())
+ s->Printf("%s : %s\n", GetName().GetCString(), m_base_class.GetTypeName().GetCString());
+ else
+ s->Printf("%s\n", GetName().GetCString());
+
+ s->IndentMore();
+ for (const Field &f : m_fields)
+ s->Printf("%s %s\n", f.m_type.GetTypeName().GetCString(), f.m_name.GetCString());
+ s->IndentLess();
+ }
+
+ Field *
+ GetFieldAtIndex(size_t idx)
+ {
+ if (idx < m_fields.size())
+ return &m_fields[idx];
+ return nullptr;
+ }
+
+ CompilerType
+ GetBaseClass()
+ {
+ return m_base_class;
+ }
+
+ uint32_t
+ GetBaseClassOffset()
+ {
+ return m_base_class_offset;
+ }
+
+ uint32_t
+ GetNumInterfaces()
+ {
+ return m_interfaces.size();
+ }
+
+ CompilerType
+ GetInterfaceAtIndex(uint32_t idx)
+ {
+ if (m_interfaces.size() < idx)
+ return m_interfaces[idx];
+ return CompilerType();
+ }
+
+ bool
+ IsCompleteType() override
+ {
+ return m_is_complete;
+ }
+
+ void
+ SetCompleteType(bool is_complete)
+ {
+ m_is_complete = is_complete;
+ if (m_byte_size == 0)
+ {
+ // Try to calcualte the size of the object based on it's values
+ for (const Field &field : m_fields)
+ {
+ uint32_t field_end = field.m_offset + field.m_type.GetByteSize(nullptr);
+ if (field_end > m_byte_size)
+ m_byte_size = field_end;
+ }
+ }
+ }
+
+ void
+ AddBaseClass(const CompilerType &type, uint32_t offset)
+ {
+ // TODO: Check if type is an interface and add it to the interface list in that case
+ m_base_class = type;
+ m_base_class_offset = offset;
+ }
+
+ void
+ AddField(const ConstString &name, const CompilerType &type, uint32_t offset)
+ {
+ m_fields.push_back({name, type, offset});
+ }
+
+ static bool
+ classof(const JavaType *jt)
+ {
+ return jt->getKind() == JavaType::eKindObject;
+ }
+
+private:
+ ConstString m_name;
+ uint32_t m_byte_size;
+ CompilerType m_base_class;
+ uint32_t m_base_class_offset;
+ std::vector<CompilerType> m_interfaces;
+ std::vector<Field> m_fields;
+ bool m_is_complete;
+};
+
+class JavaReferenceType : public JavaASTContext::JavaType
+{
+public:
+ JavaReferenceType(CompilerType pointee_type) : JavaType(JavaType::eKindReference), m_pointee_type(pointee_type) {}
+
+ static bool
+ classof(const JavaType *jt)
+ {
+ return jt->getKind() == JavaType::eKindReference;
+ }
+
+ CompilerType
+ GetPointeeType()
+ {
+ return m_pointee_type;
+ }
+
+ ConstString
+ GetName() override
+ {
+ ConstString pointee_type_name = static_cast<JavaType *>(GetPointeeType().GetOpaqueQualType())->GetName();
+ return ConstString(std::string(pointee_type_name.AsCString()) + "&");
+ }
+
+ void
+ Dump(Stream *s) override
+ {
+ static_cast<JavaType *>(m_pointee_type.GetOpaqueQualType())->Dump(s);
+ }
+
+ bool
+ IsCompleteType() override
+ {
+ return m_pointee_type.IsCompleteType();
+ }
+
+private:
+ CompilerType m_pointee_type;
+};
+
+class JavaArrayType : public JavaDynamicType
+{
+public:
+ JavaArrayType(const ConstString& linkage_name, CompilerType element_type, const DWARFExpression &length_expression,
+ lldb::addr_t data_offset)
+ : JavaDynamicType(JavaType::eKindArray, linkage_name),
+ m_element_type(element_type),
+ m_length_expression(length_expression),
+ m_data_offset(data_offset)
+ {
+ }
+
+ static bool
+ classof(const JavaType *jt)
+ {
+ return jt->getKind() == JavaType::eKindArray;
+ }
+
+ CompilerType
+ GetElementType()
+ {
+ return m_element_type;
+ }
+
+ ConstString
+ GetName() override
+ {
+ ConstString element_type_name = static_cast<JavaType *>(GetElementType().GetOpaqueQualType())->GetName();
+ return ConstString(std::string(element_type_name.AsCString()) + "[]");
+ }
+
+ void
+ Dump(Stream *s) override
+ {
+ s->Printf("%s\n", GetName().GetCString());
+ }
+
+ bool
+ IsCompleteType() override
+ {
+ return m_length_expression.IsValid();
+ }
+
+ uint32_t
+ GetNumElements(ValueObject *value_obj)
+ {
+ if (!m_length_expression.IsValid())
+ return UINT32_MAX;
+
+ Error error;
+ ValueObjectSP address_obj = value_obj->AddressOf(error);
+ if (error.Fail())
+ return UINT32_MAX;
+
+ Value obj_load_address = address_obj->GetValue();
+ obj_load_address.SetValueType(Value::eValueTypeLoadAddress);
+
+ Value result;
+ ExecutionContextScope* exec_ctx_scope = value_obj->GetExecutionContextRef().Lock(true).GetBestExecutionContextScope();
+ if (m_length_expression.Evaluate(exec_ctx_scope, nullptr, nullptr, 0, nullptr, &obj_load_address, result, nullptr))
+ return result.GetScalar().UInt();
+
+ return UINT32_MAX;
+ }
+
+ uint64_t
+ GetElementOffset(size_t idx)
+ {
+ return m_data_offset + idx * m_element_type.GetByteSize(nullptr);
+ }
+
+private:
+ CompilerType m_element_type;
+ DWARFExpression m_length_expression;
+ lldb::addr_t m_data_offset;
+};
+
+} // end of anonymous namespace
+
+ConstString
+JavaASTContext::GetPluginNameStatic()
+{
+ return ConstString("java");
+}
+
+ConstString
+JavaASTContext::GetPluginName()
+{
+ return JavaASTContext::GetPluginNameStatic();
+}
+
+uint32_t
+JavaASTContext::GetPluginVersion()
+{
+ return 1;
+}
+
+lldb::TypeSystemSP
+JavaASTContext::CreateInstance(lldb::LanguageType language, Module *module, Target *target)
+{
+ if (language == eLanguageTypeJava)
+ {
+ if (module)
+ return std::make_shared<JavaASTContext>(module->GetArchitecture());
+ if (target)
+ return std::make_shared<JavaASTContext>(target->GetArchitecture());
+ assert(false && "Either a module or a target has to be specifed to create a JavaASTContext");
+ }
+ return lldb::TypeSystemSP();
+}
+
+void
+JavaASTContext::EnumerateSupportedLanguages(std::set<lldb::LanguageType> &languages_for_types,
+ std::set<lldb::LanguageType> &languages_for_expressions)
+{
+ static std::vector<lldb::LanguageType> s_languages_for_types({lldb::eLanguageTypeJava});
+ static std::vector<lldb::LanguageType> s_languages_for_expressions({});
+
+ languages_for_types.insert(s_languages_for_types.begin(), s_languages_for_types.end());
+ languages_for_expressions.insert(s_languages_for_expressions.begin(), s_languages_for_expressions.end());
+}
+
+void
+JavaASTContext::Initialize()
+{
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "AST context plug-in", CreateInstance,
+ EnumerateSupportedLanguages);
+}
+
+void
+JavaASTContext::Terminate()
+{
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+JavaASTContext::JavaASTContext(const ArchSpec &arch)
+ : TypeSystem(eKindJava), m_pointer_byte_size(arch.GetAddressByteSize())
+{
+}
+
+JavaASTContext::~JavaASTContext()
+{
+}
+
+uint32_t
+JavaASTContext::GetPointerByteSize()
+{
+ return m_pointer_byte_size;
+}
+
+DWARFASTParser *
+JavaASTContext::GetDWARFParser()
+{
+ if (!m_dwarf_ast_parser_ap)
+ m_dwarf_ast_parser_ap.reset(new DWARFASTParserJava(*this));
+ return m_dwarf_ast_parser_ap.get();
+}
+
+ConstString
+JavaASTContext::DeclGetName(void *opaque_decl)
+{
+ return ConstString();
+}
+
+std::vector<CompilerDecl>
+JavaASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, const bool ignore_imported_decls)
+{
+ return std::vector<CompilerDecl>();
+}
+
+bool
+JavaASTContext::DeclContextIsStructUnionOrClass(void *opaque_decl_ctx)
+{
+ return false;
+}
+
+ConstString
+JavaASTContext::DeclContextGetName(void *opaque_decl_ctx)
+{
+ return ConstString();
+}
+
+bool
+JavaASTContext::DeclContextIsClassMethod(void *opaque_decl_ctx, lldb::LanguageType *language_ptr,
+ bool *is_instance_method_ptr, ConstString *language_object_name_ptr)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsArrayType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size,
+ bool *is_incomplete)
+{
+ if (element_type)
+ element_type->Clear();
+ if (size)
+ *size = 0;
+ if (is_incomplete)
+ *is_incomplete = false;
+
+ if (JavaArrayType *array = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type)))
+ {
+ if (element_type)
+ *element_type = array->GetElementType();
+ return true;
+ }
+ return false;
+}
+
+bool
+JavaASTContext::IsAggregateType(lldb::opaque_compiler_type_t type)
+{
+ return llvm::isa<JavaObjectType>(static_cast<JavaType *>(type));
+}
+
+bool
+JavaASTContext::IsCharType(lldb::opaque_compiler_type_t type)
+{
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ return ptype->GetTypeKind() == JavaPrimitiveType::eTypeChar;
+ return false;
+}
+
+bool
+JavaASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex)
+{
+ is_complex = true;
+
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeFloat:
+ case JavaPrimitiveType::eTypeDouble:
+ count = 1;
+ return true;
+ default:
+ break;
+ }
+ }
+
+ count = 0;
+ return false;
+}
+
+bool
+JavaASTContext::IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr)
+{
+ if (is_variadic_ptr)
+ *is_variadic_ptr = false;
+ return false;
+}
+
+size_t
+JavaASTContext::GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type)
+{
+ return 0;
+}
+
+CompilerType
+JavaASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index)
+{
+ return CompilerType();
+}
+
+bool
+JavaASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed)
+{
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeByte:
+ case JavaPrimitiveType::eTypeShort:
+ case JavaPrimitiveType::eTypeInt:
+ case JavaPrimitiveType::eTypeLong:
+ is_signed = true;
+ return true;
+ default:
+ break;
+ }
+ }
+
+ is_signed = false;
+ return false;
+}
+
+bool
+JavaASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type, CompilerType *target_type,
+ bool check_cplusplus, bool check_objc)
+{
+ return llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type));
+}
+
+bool
+JavaASTContext::IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
+{
+ if (pointee_type)
+ pointee_type->Clear();
+ return false;
+}
+
+bool
+JavaASTContext::IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool *is_rvalue)
+{
+ if (is_rvalue)
+ *is_rvalue = false;
+
+ if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
+ {
+ if (pointee_type)
+ *pointee_type = ref->GetPointeeType();
+ return true;
+ }
+
+ if (pointee_type)
+ pointee_type->Clear();
+ return false;
+}
+
+bool
+JavaASTContext::IsScalarType(lldb::opaque_compiler_type_t type)
+{
+ return llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type)) ||
+ llvm::isa<JavaPrimitiveType>(static_cast<JavaType *>(type));
+}
+
+bool
+JavaASTContext::IsVoidType(lldb::opaque_compiler_type_t type)
+{
+ return false; // TODO: Implement if we introduce the void type
+}
+
+bool
+JavaASTContext::SupportsLanguage(lldb::LanguageType language)
+{
+ return language == lldb::eLanguageTypeJava;
+}
+
+bool
+JavaASTContext::IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type)
+{
+ return true;
+}
+
+bool
+JavaASTContext::IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
+{
+ return IsPointerType(type, pointee_type) || IsReferenceType(type, pointee_type);
+}
+
+bool
+JavaASTContext::IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length)
+{
+ return false; // TODO: Implement it if we need it for string literals
+}
+
+bool
+JavaASTContext::IsTypedefType(lldb::opaque_compiler_type_t type)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsVectorType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size)
+{
+ if (element_type)
+ element_type->Clear();
+ if (size)
+ *size = 0;
+ return false;
+}
+
+bool
+JavaASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type)
+{
+ return llvm::isa<JavaObjectType>(static_cast<JavaType *>(type));
+}
+
+uint32_t
+JavaASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, CompilerType *base_type_ptr)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsCompleteType(lldb::opaque_compiler_type_t type)
+{
+ return static_cast<JavaType *>(type)->IsCompleteType();
+}
+
+bool
+JavaASTContext::IsConst(lldb::opaque_compiler_type_t type)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsDefined(lldb::opaque_compiler_type_t type)
+{
+ return type != nullptr;
+}
+
+bool
+JavaASTContext::GetCompleteType(lldb::opaque_compiler_type_t type)
+{
+ if (IsCompleteType(type))
+ return true;
+
+ if (JavaArrayType *array = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type)))
+ return GetCompleteType(array->GetElementType().GetOpaqueQualType());
+
+ if (JavaReferenceType *reference = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
+ return GetCompleteType(reference->GetPointeeType().GetOpaqueQualType());
+
+ if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ SymbolFile *symbol_file = GetSymbolFile();
+ if (!symbol_file)
+ return false;
+
+ CompilerType object_type(this, type);
+ return symbol_file->CompleteType(object_type);
+ }
+ return false;
+}
+
+ConstString
+JavaASTContext::GetTypeName(lldb::opaque_compiler_type_t type)
+{
+ if (type)
+ return static_cast<JavaType *>(type)->GetName();
+ return ConstString();
+}
+
+uint32_t
+JavaASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_compiler_type)
+{
+ if (pointee_or_element_compiler_type)
+ pointee_or_element_compiler_type->Clear();
+ if (!type)
+ return 0;
+
+ if (IsReferenceType(type, pointee_or_element_compiler_type))
+ return eTypeHasChildren | eTypeHasValue | eTypeIsReference;
+ if (IsArrayType(type, pointee_or_element_compiler_type, nullptr, nullptr))
+ return eTypeHasChildren | eTypeIsArray;
+ if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
+ return eTypeHasChildren | eTypeIsClass;
+
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeByte:
+ case JavaPrimitiveType::eTypeShort:
+ case JavaPrimitiveType::eTypeInt:
+ case JavaPrimitiveType::eTypeLong:
+ return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsInteger | eTypeIsSigned;
+ case JavaPrimitiveType::eTypeFloat:
+ case JavaPrimitiveType::eTypeDouble:
+ return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsFloat | eTypeIsSigned;
+ case JavaPrimitiveType::eTypeBoolean:
+ return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar;
+ case JavaPrimitiveType::eTypeChar:
+ return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar;
+ }
+ }
+ return 0;
+}
+
+lldb::TypeClass
+JavaASTContext::GetTypeClass(lldb::opaque_compiler_type_t type)
+{
+ if (!type)
+ return eTypeClassInvalid;
+ if (llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type)))
+ return eTypeClassReference;
+ if (llvm::isa<JavaArrayType>(static_cast<JavaType *>(type)))
+ return eTypeClassArray;
+ if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
+ return eTypeClassClass;
+ if (llvm::isa<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ return eTypeClassBuiltin;
+ assert(false && "Java type with unhandled type class");
+ return eTypeClassInvalid;
+}
+
+lldb::LanguageType
+JavaASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type)
+{
+ return lldb::eLanguageTypeJava;
+}
+
+CompilerType
+JavaASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride)
+{
+ if (stride)
+ *stride = 0;
+
+ CompilerType element_type;
+ if (IsArrayType(type, &element_type, nullptr, nullptr))
+ return element_type;
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::GetPointeeType(lldb::opaque_compiler_type_t type)
+{
+ CompilerType pointee_type;
+ if (IsPointerType(type, &pointee_type))
+ return pointee_type;
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::GetPointerType(lldb::opaque_compiler_type_t type)
+{
+ return CompilerType(); // No pointer types in java
+}
+
+CompilerType
+JavaASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type)
+{
+ return CompilerType(this, type);
+}
+
+CompilerType
+JavaASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type)
+{
+ return CompilerType(this, type);
+}
+
+CompilerType
+JavaASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type)
+{
+ CompilerType pointee_type;
+ if (IsReferenceType(type, &pointee_type))
+ return pointee_type;
+ return CompilerType(this, type);
+}
+
+CompilerType
+JavaASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type)
+{
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type)
+{
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size)
+{
+ return CompilerType();
+}
+
+size_t
+JavaASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type)
+{
+ return 0;
+}
+
+lldb::BasicType
+JavaASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type)
+{
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeByte:
+ return eBasicTypeOther;
+ case JavaPrimitiveType::eTypeShort:
+ return eBasicTypeShort;
+ case JavaPrimitiveType::eTypeInt:
+ return eBasicTypeInt;
+ case JavaPrimitiveType::eTypeLong:
+ return eBasicTypeLong;
+ case JavaPrimitiveType::eTypeFloat:
+ return eBasicTypeFloat;
+ case JavaPrimitiveType::eTypeDouble:
+ return eBasicTypeDouble;
+ case JavaPrimitiveType::eTypeBoolean:
+ return eBasicTypeBool;
+ case JavaPrimitiveType::eTypeChar:
+ return eBasicTypeChar;
+ }
+ }
+ return eBasicTypeInvalid;
+}
+
+uint64_t
+JavaASTContext::GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope)
+{
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeByte:
+ return 8;
+ case JavaPrimitiveType::eTypeShort:
+ return 16;
+ case JavaPrimitiveType::eTypeInt:
+ return 32;
+ case JavaPrimitiveType::eTypeLong:
+ return 64;
+ case JavaPrimitiveType::eTypeFloat:
+ return 32;
+ case JavaPrimitiveType::eTypeDouble:
+ return 64;
+ case JavaPrimitiveType::eTypeBoolean:
+ return 1;
+ case JavaPrimitiveType::eTypeChar:
+ return 16;
+ }
+ }
+ else if (llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type)))
+ {
+ return 32; // References are always 4 byte long in java
+ }
+ else if (llvm::isa<JavaArrayType>(static_cast<JavaType *>(type)))
+ {
+ return 64;
+ }
+ else if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ return obj->GetByteSize() * 8;
+ }
+ return 0;
+}
+
+lldb::Encoding
+JavaASTContext::GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count)
+{
+ count = 1;
+
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeByte:
+ case JavaPrimitiveType::eTypeShort:
+ case JavaPrimitiveType::eTypeInt:
+ case JavaPrimitiveType::eTypeLong:
+ return eEncodingSint;
+ case JavaPrimitiveType::eTypeFloat:
+ case JavaPrimitiveType::eTypeDouble:
+ return eEncodingIEEE754;
+ case JavaPrimitiveType::eTypeBoolean:
+ case JavaPrimitiveType::eTypeChar:
+ return eEncodingUint;
+ }
+ }
+ if (IsReferenceType(type))
+ return eEncodingUint;
+ return eEncodingInvalid;
+}
+
+lldb::Format
+JavaASTContext::GetFormat(lldb::opaque_compiler_type_t type)
+{
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeByte:
+ case JavaPrimitiveType::eTypeShort:
+ case JavaPrimitiveType::eTypeInt:
+ case JavaPrimitiveType::eTypeLong:
+ return eFormatDecimal;
+ case JavaPrimitiveType::eTypeFloat:
+ case JavaPrimitiveType::eTypeDouble:
+ return eFormatFloat;
+ case JavaPrimitiveType::eTypeBoolean:
+ return eFormatBoolean;
+ case JavaPrimitiveType::eTypeChar:
+ return eFormatUnicode16;
+ }
+ }
+ if (IsReferenceType(type))
+ return eFormatHex;
+ return eFormatDefault;
+}
+
+unsigned
+JavaASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type)
+{
+ return 0;
+}
+
+size_t
+JavaASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst,
+ size_t dst_size)
+{
+ assert(false && "Not implemented");
+ return 0;
+}
+
+size_t
+JavaASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type)
+{
+ return 0;
+}
+
+CompilerType
+JavaASTContext::GetTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, lldb::TemplateArgumentKind &kind)
+{
+ return CompilerType();
+}
+
+uint32_t
+JavaASTContext::GetNumFields(lldb::opaque_compiler_type_t type)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+ return obj->GetNumFields();
+ }
+ return 0;
+}
+
+CompilerType
+JavaASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, std::string &name,
+ uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr)
+{
+ if (bit_offset_ptr)
+ *bit_offset_ptr = 0;
+ if (bitfield_bit_size_ptr)
+ *bitfield_bit_size_ptr = 0;
+ if (is_bitfield_ptr)
+ *is_bitfield_ptr = false;
+
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+
+ JavaObjectType::Field *field = obj->GetFieldAtIndex(idx);
+ if (!field)
+ return CompilerType();
+ name = field->m_name.AsCString();
+ if (bit_offset_ptr)
+ *bit_offset_ptr = field->m_offset * 8;
+ return field->m_type;
+ }
+ return CompilerType();
+}
+
+uint32_t
+JavaASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes)
+{
+ GetCompleteType(type);
+
+ if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
+ return ref->GetPointeeType().GetNumChildren(omit_empty_base_classes);
+
+ if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
+ return GetNumFields(type) + GetNumDirectBaseClasses(type);
+
+ return 0;
+}
+
+uint32_t
+JavaASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+ return obj->GetNumInterfaces() + (obj->GetBaseClass() ? 1 : 0);
+ }
+ return 0;
+}
+
+uint32_t
+JavaASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+ return obj->GetNumInterfaces();
+ }
+ return 0;
+}
+
+CompilerType
+JavaASTContext::GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+
+ if (CompilerType base_class = obj->GetBaseClass())
+ {
+ if (idx == 0)
+ return base_class;
+ else
+ --idx;
+ }
+ return obj->GetInterfaceAtIndex(idx);
+ }
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+ return obj->GetInterfaceAtIndex(idx);
+ }
+ return CompilerType();
+}
+
+void
+JavaASTContext::DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format,
+ const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size,
+ uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, bool show_summary,
+ bool verbose, uint32_t depth)
+{
+ assert(false && "Not implemented");
+}
+
+bool
+JavaASTContext::DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
+ const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size,
+ uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
+ ExecutionContextScope *exe_scope)
+{
+ if (IsScalarType(type))
+ {
+ return data.Dump(s, data_offset, format, data_byte_size,
+ 1, // count
+ UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset, exe_scope);
+ }
+ return false;
+}
+
+void
+JavaASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type)
+{
+ StreamFile s(stdout, false);
+ DumpTypeDescription(type, &s);
+}
+
+void
+JavaASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s)
+{
+ static_cast<JavaType *>(type)->Dump(s);
+}
+
+void
+JavaASTContext::DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
+ const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size)
+{
+ assert(false && "Not implemented");
+}
+
+int
+JavaASTContext::GetFunctionArgumentCount(lldb::opaque_compiler_type_t type)
+{
+ return 0;
+}
+
+CompilerType
+JavaASTContext::GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, size_t idx)
+{
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type)
+{
+ return CompilerType();
+}
+
+size_t
+JavaASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type)
+{
+ return 0;
+}
+
+TypeMemberFunctionImpl
+JavaASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx)
+{
+ return TypeMemberFunctionImpl();
+}
+
+CompilerType
+JavaASTContext::GetChildCompilerTypeAtIndex(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
+ bool transparent_pointers, bool omit_empty_base_classes,
+ bool ignore_array_bounds, std::string &child_name,
+ uint32_t &child_byte_size, int32_t &child_byte_offset,
+ uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
+ bool &child_is_base_class, bool &child_is_deref_of_parent,
+ ValueObject *valobj, uint64_t &language_flags)
+{
+ child_name.clear();
+ child_byte_size = 0;
+ child_byte_offset = 0;
+ child_bitfield_bit_size = 0;
+ child_bitfield_bit_offset = 0;
+ child_is_base_class = false;
+ child_is_deref_of_parent = false;
+ language_flags = 0;
+
+ ExecutionContextScope *exec_ctx_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
+
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+
+ if (CompilerType base_class = obj->GetBaseClass())
+ {
+ if (idx == 0)
+ {
+ JavaType *base_class_type = static_cast<JavaType *>(base_class.GetOpaqueQualType());
+ child_name = base_class_type->GetName().GetCString();
+ child_byte_size = base_class.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
+ child_byte_offset = obj->GetBaseClassOffset();
+ child_is_base_class = true;
+ return base_class;
+ }
+ idx -= 1;
+ }
+
+ JavaObjectType::Field *field = obj->GetFieldAtIndex(idx);
+ if (!field)
+ return CompilerType();
+
+ child_name = field->m_name.AsCString();
+ child_byte_size = field->m_type.GetByteSize(exec_ctx_scope);
+ child_byte_offset = field->m_offset;
+ return field->m_type;
+ }
+ else if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
+ {
+ CompilerType pointee_type = ref->GetPointeeType();
+
+ if (transparent_pointers)
+ return pointee_type.GetChildCompilerTypeAtIndex(
+ exe_ctx, idx, transparent_pointers, omit_empty_base_classes, ignore_array_bounds, child_name,
+ child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
+ child_is_base_class, child_is_deref_of_parent, valobj, language_flags);
+
+ if (idx != 0)
+ return CompilerType();
+
+ if (valobj && valobj->GetName())
+ child_name = valobj->GetName().GetCString();
+ child_is_deref_of_parent = true;
+ child_byte_offset = 0;
+ child_byte_size = pointee_type.GetByteSize(exec_ctx_scope);
+ return pointee_type;
+ }
+ return CompilerType();
+}
+
+uint32_t
+JavaASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name,
+ bool omit_empty_base_classes)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+
+ uint32_t index_offset = 0;
+ if (CompilerType base_class = obj->GetBaseClass())
+ {
+ if (base_class.GetTypeName() == ConstString(name))
+ return 0;
+ index_offset = 1;
+ }
+ for (uint32_t i = 0; i < obj->GetNumFields(); ++i)
+ {
+ if (obj->GetFieldAtIndex(i)->m_name == ConstString(name))
+ return i + index_offset;
+ }
+ }
+ else if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
+ {
+ return GetIndexOfChildWithName(ref->GetPointeeType().GetOpaqueQualType(), name, omit_empty_base_classes);
+ }
+ return UINT_MAX;
+}
+
+size_t
+JavaASTContext::GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, const char *name,
+ bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes)
+{
+ child_indexes.clear();
+
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+
+ uint32_t index_offset = 0;
+ if (CompilerType base_class = obj->GetBaseClass())
+ {
+ if (GetIndexOfChildMemberWithName(base_class.GetOpaqueQualType(), name, omit_empty_base_classes,
+ child_indexes) != 0)
+ {
+ child_indexes.insert(child_indexes.begin(), 0);
+ return child_indexes.size();
+ }
+ index_offset = 1;
+ }
+
+ for (uint32_t i = 0; i < obj->GetNumFields(); ++i)
+ {
+ if (obj->GetFieldAtIndex(i)->m_name == ConstString(name))
+ {
+ child_indexes.push_back(i + index_offset);
+ return child_indexes.size();
+ }
+ }
+ }
+ else if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
+ {
+ return GetIndexOfChildMemberWithName(ref->GetPointeeType().GetOpaqueQualType(), name, omit_empty_base_classes,
+ child_indexes);
+ }
+ return 0;
+}
+
+CompilerType
+JavaASTContext::GetLValueReferenceType(lldb::opaque_compiler_type_t type)
+{
+ return CreateReferenceType(CompilerType(this, type));
+}
+
+ConstString
+JavaASTContext::DeclContextGetScopeQualifiedName(lldb::opaque_compiler_type_t opaque_decl_ctx)
+{
+ return GetTypeName(opaque_decl_ctx);
+}
+
+static void
+AddPrimitiveType(JavaASTContext::JavaTypeMap &type_map, JavaPrimitiveType::TypeKind type_kind)
+{
+ JavaPrimitiveType *type = new JavaPrimitiveType(type_kind);
+ type_map.emplace(type->GetName(), std::unique_ptr<JavaASTContext::JavaType>(type));
+}
+
+CompilerType
+JavaASTContext::CreateBaseType(const ConstString &name)
+{
+ if (m_base_type_map.empty())
+ {
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeByte);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeShort);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeInt);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeLong);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeFloat);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeDouble);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeBoolean);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeChar);
+ }
+ auto it = m_base_type_map.find(name);
+ if (it != m_base_type_map.end())
+ return CompilerType(this, it->second.get());
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::CreateObjectType(const ConstString &name, const ConstString &linkage_name, uint32_t byte_size)
+{
+ auto it = m_object_type_map.find(name);
+ if (it == m_object_type_map.end())
+ {
+ std::unique_ptr<JavaType> object_type(new JavaObjectType(name, linkage_name, byte_size));
+ it = m_object_type_map.emplace(name, std::move(object_type)).first;
+ }
+ return CompilerType(this, it->second.get());
+}
+
+CompilerType
+JavaASTContext::CreateArrayType(const ConstString &linkage_name, const CompilerType &element_type,
+ const DWARFExpression &length_expression, const lldb::addr_t data_offset)
+{
+ ConstString name = element_type.GetTypeName();
+ auto it = m_array_type_map.find(name);
+ if (it == m_array_type_map.end())
+ {
+ std::unique_ptr<JavaType> array_type(new JavaArrayType(linkage_name, element_type, length_expression,
+ data_offset));
+ it = m_array_type_map.emplace(name, std::move(array_type)).first;
+ }
+ return CompilerType(this, it->second.get());
+}
+
+CompilerType
+JavaASTContext::CreateReferenceType(const CompilerType &pointee_type)
+{
+ ConstString name = pointee_type.GetTypeName();
+ auto it = m_reference_type_map.find(name);
+ if (it == m_reference_type_map.end())
+ it = m_reference_type_map.emplace(name, std::unique_ptr<JavaType>(new JavaReferenceType(pointee_type))).first;
+ return CompilerType(this, it->second.get());
+}
+
+void
+JavaASTContext::CompleteObjectType(const CompilerType &object_type)
+{
+ JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(object_type.GetOpaqueQualType()));
+ assert(obj && "JavaASTContext::CompleteObjectType called with not a JavaObjectType");
+ obj->SetCompleteType(true);
+}
+
+void
+JavaASTContext::AddBaseClassToObject(const CompilerType &object_type, const CompilerType &member_type,
+ uint32_t member_offset)
+{
+ JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(object_type.GetOpaqueQualType()));
+ assert(obj && "JavaASTContext::AddMemberToObject called with not a JavaObjectType");
+ obj->AddBaseClass(member_type, member_offset);
+}
+
+void
+JavaASTContext::AddMemberToObject(const CompilerType &object_type, const ConstString &name,
+ const CompilerType &member_type, uint32_t member_offset)
+{
+ JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(object_type.GetOpaqueQualType()));
+ assert(obj && "JavaASTContext::AddMemberToObject called with not a JavaObjectType");
+ obj->AddField(name, member_type, member_offset);
+}
+
+void
+JavaASTContext::SetDynamicTypeId(const CompilerType &type, const DWARFExpression &type_id)
+{
+ JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type.GetOpaqueQualType()));
+ assert(obj && "JavaASTContext::SetDynamicTypeId called with not a JavaObjectType");
+ obj->SetDynamicTypeId(type_id);
+}
+
+uint64_t
+JavaASTContext::CalculateDynamicTypeId(ExecutionContext *exe_ctx, const CompilerType &type, ValueObject &in_value)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+ return obj->CalculateDynamicTypeId(exe_ctx, in_value);
+ if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+ return arr->CalculateDynamicTypeId(exe_ctx, in_value);
+ return UINT64_MAX;
+}
+
+uint32_t
+JavaASTContext::CalculateArraySize(const CompilerType &type, ValueObject &in_value)
+{
+ if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+ return arr->GetNumElements(&in_value);
+ return UINT32_MAX;
+}
+
+uint64_t
+JavaASTContext::CalculateArrayElementOffset(const CompilerType &type, size_t index)
+{
+ if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+ return arr->GetElementOffset(index);
+ return UINT64_MAX;
+}
+
+ConstString
+JavaASTContext::GetLinkageName(const CompilerType &type)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+ return obj->GetLinkageName();
+ return ConstString();
+}
diff --git a/source/Symbol/LineEntry.cpp b/source/Symbol/LineEntry.cpp
index 815101368bd1..9b3a043f6cae 100644
--- a/source/Symbol/LineEntry.cpp
+++ b/source/Symbol/LineEntry.cpp
@@ -43,6 +43,7 @@ LineEntry::LineEntry
) :
range(section_sp, section_offset, byte_size),
file(_file),
+ original_file(_file),
line(_line),
column(_column),
is_start_of_statement(_is_start_of_statement),
@@ -58,6 +59,7 @@ LineEntry::Clear()
{
range.Clear();
file.Clear();
+ original_file.Clear();
line = LLDB_INVALID_LINE_NUMBER;
column = 0;
is_start_of_statement = 0;
@@ -260,7 +262,7 @@ LineEntry::GetSameLineContiguousAddressRange () const
if (next_line_sc.line_entry.IsValid()
&& next_line_sc.line_entry.range.GetByteSize() > 0
- && file == next_line_sc.line_entry.file)
+ && original_file == next_line_sc.line_entry.original_file)
{
// Include any line 0 entries - they indicate that this is compiler-generated code
// that does not correspond to user source code.
@@ -283,3 +285,15 @@ LineEntry::GetSameLineContiguousAddressRange () const
}
return complete_line_range;
}
+
+void
+LineEntry::ApplyFileMappings(lldb::TargetSP target_sp)
+{
+ if (target_sp)
+ {
+ // Apply any file remappings to our file
+ FileSpec new_file_spec;
+ if (target_sp->GetSourcePathMap().FindFile(original_file, new_file_spec))
+ file = new_file_spec;
+ }
+}
diff --git a/source/Symbol/LineTable.cpp b/source/Symbol/LineTable.cpp
index f9a42a7d14af..965dd689981b 100644
--- a/source/Symbol/LineTable.cpp
+++ b/source/Symbol/LineTable.cpp
@@ -299,6 +299,7 @@ LineTable::ConvertEntryAtIndexToLineEntry (uint32_t idx, LineEntry &line_entry)
line_entry.range.SetByteSize(0);
line_entry.file = m_comp_unit->GetSupportFiles().GetFileSpecAtIndex (entry.file_idx);
+ line_entry.original_file = m_comp_unit->GetSupportFiles().GetFileSpecAtIndex(entry.file_idx);
line_entry.line = entry.line;
line_entry.column = entry.column;
line_entry.is_start_of_statement = entry.is_start_of_statement;
@@ -462,9 +463,9 @@ LineTable::Dump (Stream *s, Target *target, Address::DumpStyle style, Address::D
for (size_t idx = 0; idx < count; ++idx)
{
ConvertEntryAtIndexToLineEntry (idx, line_entry);
- line_entry.Dump (s, target, prev_file != line_entry.file, style, fallback_style, show_line_ranges);
+ line_entry.Dump (s, target, prev_file != line_entry.original_file, style, fallback_style, show_line_ranges);
s->EOL();
- prev_file = line_entry.file;
+ prev_file = line_entry.original_file;
}
}
diff --git a/source/Symbol/Makefile b/source/Symbol/Makefile
deleted file mode 100644
index ae0cef0e242a..000000000000
--- a/source/Symbol/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Symbol/Makefile ------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LIBRARYNAME := lldbSymbol
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Symbol/ObjectFile.cpp b/source/Symbol/ObjectFile.cpp
index 99f9236a2cd9..62cde26c702f 100644
--- a/source/Symbol/ObjectFile.cpp
+++ b/source/Symbol/ObjectFile.cpp
@@ -241,8 +241,7 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
lldb::offset_t file_offset,
lldb::offset_t length,
const lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset
-) :
+ lldb::offset_t data_offset) :
ModuleChild (module_sp),
m_file (), // This file could be different from the original module's file
m_type (eTypeInvalid),
@@ -254,7 +253,8 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
m_process_wp(),
m_memory_addr (LLDB_INVALID_ADDRESS),
m_sections_ap(),
- m_symtab_ap ()
+ m_symtab_ap (),
+ m_synthetic_symbol_idx (0)
{
if (file_spec_ptr)
m_file = *file_spec_ptr;
@@ -286,7 +286,8 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
m_process_wp (process_sp),
m_memory_addr (header_addr),
m_sections_ap(),
- m_symtab_ap ()
+ m_symtab_ap (),
+ m_synthetic_symbol_idx (0)
{
if (header_data_sp)
m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize());
@@ -384,6 +385,11 @@ ObjectFile::GetAddressClass (addr_t file_addr)
case eSectionTypeELFDynamicLinkInfo:
case eSectionTypeOther:
return eAddressClassUnknown;
+ case eSectionTypeAbsoluteAddress:
+ // In case of absolute sections decide the address class based on the symbol
+ // type because the section type isn't specify if it is a code or a data
+ // section.
+ break;
}
}
}
@@ -545,8 +551,6 @@ ObjectFile::ReadSectionData (const Section *section, DataExtractor& section_data
// The object file now contains a full mmap'ed copy of the object file data, so just use this
return MemoryMapSectionData (section, section_data);
}
- section_data.Clear();
- return 0;
}
size_t
@@ -596,7 +600,7 @@ ObjectFile::ClearSymtab ()
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
log->Printf ("%p ObjectFile::ClearSymtab () symtab = %p",
@@ -616,7 +620,7 @@ ObjectFile::GetSectionList(bool update_module_section_list)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
CreateSections(*module_sp->GetUnifiedSectionList());
}
}
@@ -653,3 +657,13 @@ ObjectFile::GetSymbolTypeFromName (llvm::StringRef name,
}
return symbol_type_hint;
}
+
+ConstString
+ObjectFile::GetNextSyntheticSymbolName()
+{
+ StreamString ss;
+ ConstString file_name = GetModule()->GetFileSpec().GetFilename();
+ ss.Printf("___lldb_unnamed_symbol%u$$%s", ++m_synthetic_symbol_idx, file_name.GetCString());
+ return ConstString(ss.GetData());
+}
+
diff --git a/source/Symbol/Symbol.cpp b/source/Symbol/Symbol.cpp
index 5884fcaa551d..1fa792c9729d 100644
--- a/source/Symbol/Symbol.cpp
+++ b/source/Symbol/Symbol.cpp
@@ -737,3 +737,10 @@ Symbol::GetDisassembly (const ExecutionContext &exe_ctx,
}
return false;
}
+
+bool
+Symbol::ContainsFileAddress (lldb::addr_t file_addr) const
+{
+ return m_addr_range.ContainsFileAddress(file_addr);
+}
+
diff --git a/source/Symbol/SymbolContext.cpp b/source/Symbol/SymbolContext.cpp
index 54db5e090b80..1e55ce652e0d 100644
--- a/source/Symbol/SymbolContext.cpp
+++ b/source/Symbol/SymbolContext.cpp
@@ -365,6 +365,10 @@ SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *t
s->PutCString("kind = local, ");
break;
+ case eValueTypeVariableThreadLocal:
+ s->PutCString("kind = thread local, ");
+ break;
+
default:
break;
}
@@ -595,6 +599,7 @@ SymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc,
next_frame_pc = range.GetBaseAddress();
next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile();
+ next_frame_sc.line_entry.original_file = curr_inlined_block_inlined_info->GetCallSite().GetFile();
next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine();
next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn();
return true;
@@ -857,6 +862,73 @@ SymbolContext::GetFunctionStartLineEntry () const
return LineEntry();
}
+bool
+SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range, Error &error)
+{
+ if (!line_entry.IsValid())
+ {
+ error.SetErrorString("Symbol context has no line table.");
+ return false;
+ }
+
+ range = line_entry.range;
+ if (line_entry.line > end_line)
+ {
+ error.SetErrorStringWithFormat("end line option %d must be after the current line: %d",
+ end_line,
+ line_entry.line);
+ return false;
+ }
+
+ uint32_t line_index = 0;
+ bool found = false;
+ while (1)
+ {
+ LineEntry this_line;
+ line_index = comp_unit->FindLineEntry(line_index, line_entry.line, nullptr, false, &this_line);
+ if (line_index == UINT32_MAX)
+ break;
+ if (LineEntry::Compare(this_line, line_entry) == 0)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ LineEntry end_entry;
+ if (!found)
+ {
+ // Can't find the index of the SymbolContext's line entry in the SymbolContext's CompUnit.
+ error.SetErrorString("Can't find the current line entry in the CompUnit - can't process "
+ "the end-line option");
+ return false;
+ }
+
+ line_index = comp_unit->FindLineEntry(line_index, end_line, nullptr, false, &end_entry);
+ if (line_index == UINT32_MAX)
+ {
+ error.SetErrorStringWithFormat("could not find a line table entry corresponding "
+ "to end line number %d",
+ end_line);
+ return false;
+ }
+
+ Block *func_block = GetFunctionBlock();
+ if (func_block && func_block->GetRangeIndexContainingAddress(end_entry.range.GetBaseAddress()) == UINT32_MAX)
+ {
+ error.SetErrorStringWithFormat("end line number %d is not contained within the current function.",
+ end_line);
+ return false;
+ }
+
+ lldb::addr_t range_size = end_entry.range.GetBaseAddress().GetFileAddress()
+ - range.GetBaseAddress().GetFileAddress();
+ range.SetByteSize(range_size);
+ return true;
+}
+
+
+
//----------------------------------------------------------------------
//
// SymbolContextSpecifier
diff --git a/source/Symbol/SymbolFile.cpp b/source/Symbol/SymbolFile.cpp
index 82bbceb9610a..808dfd3d06d6 100644
--- a/source/Symbol/SymbolFile.cpp
+++ b/source/Symbol/SymbolFile.cpp
@@ -141,7 +141,7 @@ SymbolFile::GetMangledNamesForFunction(const std::string &scope_qualified_name,
}
uint32_t
-SymbolFile::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, TypeMap& types)
+SymbolFile::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap& types)
{
if (!append)
types.Clear();
diff --git a/source/Symbol/SymbolVendor.cpp b/source/Symbol/SymbolVendor.cpp
index b9ec9a1c8a79..c569943b3463 100644
--- a/source/Symbol/SymbolVendor.cpp
+++ b/source/Symbol/SymbolVendor.cpp
@@ -85,7 +85,7 @@ SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (objfile_sp)
{
m_objfile_sp = objfile_sp;
@@ -100,7 +100,7 @@ SymbolVendor::SetCompileUnitAtIndex (size_t idx, const CompUnitSP &cu_sp)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
const size_t num_compile_units = GetNumCompileUnits();
if (idx < num_compile_units)
{
@@ -129,7 +129,7 @@ SymbolVendor::GetNumCompileUnits()
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_compile_units.empty())
{
if (m_sym_file_ap.get())
@@ -151,7 +151,7 @@ SymbolVendor::ParseCompileUnitLanguage (const SymbolContext& sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseCompileUnitLanguage(sc);
}
@@ -165,7 +165,7 @@ SymbolVendor::ParseCompileUnitFunctions (const SymbolContext &sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseCompileUnitFunctions(sc);
}
@@ -178,7 +178,7 @@ SymbolVendor::ParseCompileUnitLineTable (const SymbolContext &sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseCompileUnitLineTable(sc);
}
@@ -191,7 +191,7 @@ SymbolVendor::ParseCompileUnitDebugMacros (const SymbolContext &sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseCompileUnitDebugMacros(sc);
}
@@ -203,7 +203,7 @@ SymbolVendor::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecLis
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseCompileUnitSupportFiles(sc, support_files);
}
@@ -211,13 +211,25 @@ SymbolVendor::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecLis
}
bool
-SymbolVendor::ParseImportedModules (const SymbolContext &sc,
- std::vector<ConstString> &imported_modules)
+SymbolVendor::ParseCompileUnitIsOptimized(const SymbolContext &sc)
{
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ if (m_sym_file_ap.get())
+ return m_sym_file_ap->ParseCompileUnitIsOptimized(sc);
+ }
+ return false;
+}
+
+bool
+SymbolVendor::ParseImportedModules(const SymbolContext &sc, std::vector<ConstString> &imported_modules)
+{
+ ModuleSP module_sp(GetModule());
+ if (module_sp)
+ {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseImportedModules(sc, imported_modules);
}
@@ -231,7 +243,7 @@ SymbolVendor::ParseFunctionBlocks (const SymbolContext &sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseFunctionBlocks(sc);
}
@@ -244,7 +256,7 @@ SymbolVendor::ParseTypes (const SymbolContext &sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseTypes(sc);
}
@@ -257,7 +269,7 @@ SymbolVendor::ParseVariablesForContext (const SymbolContext& sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseVariablesForContext(sc);
}
@@ -270,7 +282,7 @@ SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ResolveTypeUID(type_uid);
}
@@ -284,7 +296,7 @@ SymbolVendor::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_sco
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ResolveSymbolContext(so_addr, resolve_scope, sc);
}
@@ -297,7 +309,7 @@ SymbolVendor::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bo
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
}
@@ -310,7 +322,7 @@ SymbolVendor::FindGlobalVariables (const ConstString &name, const CompilerDeclCo
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->FindGlobalVariables(name, parent_decl_ctx, append, max_matches, variables);
}
@@ -323,7 +335,7 @@ SymbolVendor::FindGlobalVariables (const RegularExpression& regex, bool append,
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->FindGlobalVariables(regex, append, max_matches, variables);
}
@@ -336,7 +348,7 @@ SymbolVendor::FindFunctions(const ConstString &name, const CompilerDeclContext *
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->FindFunctions(name, parent_decl_ctx, name_type_mask, include_inlines, append, sc_list);
}
@@ -349,7 +361,7 @@ SymbolVendor::FindFunctions(const RegularExpression& regex, bool include_inlines
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->FindFunctions(regex, include_inlines, append, sc_list);
}
@@ -358,14 +370,14 @@ SymbolVendor::FindFunctions(const RegularExpression& regex, bool include_inlines
size_t
-SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, TypeMap& types)
+SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap& types)
{
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
- return m_sym_file_ap->FindTypes(sc, name, parent_decl_ctx, append, max_matches, types);
+ return m_sym_file_ap->FindTypes(sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
}
if (!append)
types.Clear();
@@ -378,7 +390,7 @@ SymbolVendor::FindTypes (const std::vector<CompilerContext> &context, bool appen
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->FindTypes(context, append, types);
}
@@ -395,7 +407,7 @@ SymbolVendor::GetTypes (SymbolContextScope *sc_scope,
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->GetTypes (sc_scope, type_mask, type_list);
}
@@ -409,7 +421,7 @@ SymbolVendor::FindNamespace(const SymbolContext& sc, const ConstString &name, co
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
namespace_decl_ctx = m_sym_file_ap->FindNamespace (sc, name, parent_decl_ctx);
}
@@ -422,7 +434,7 @@ SymbolVendor::Dump(Stream *s)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
bool show_context = false;
@@ -467,7 +479,7 @@ SymbolVendor::GetCompileUnitAtIndex(size_t idx)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
const size_t num_compile_units = GetNumCompileUnits();
if (idx < num_compile_units)
{
diff --git a/source/Symbol/Symtab.cpp b/source/Symbol/Symtab.cpp
index 709d899075a4..b11b731014d8 100644
--- a/source/Symbol/Symtab.cpp
+++ b/source/Symbol/Symtab.cpp
@@ -25,16 +25,14 @@
using namespace lldb;
using namespace lldb_private;
-
-
-Symtab::Symtab(ObjectFile *objfile) :
- m_objfile (objfile),
- m_symbols (),
- m_file_addr_to_index (),
- m_name_to_index (),
- m_mutex (Mutex::eMutexTypeRecursive),
- m_file_addr_to_index_computed (false),
- m_name_indexes_computed (false)
+Symtab::Symtab(ObjectFile *objfile)
+ : m_objfile(objfile),
+ m_symbols(),
+ m_file_addr_to_index(),
+ m_name_to_index(),
+ m_mutex(),
+ m_file_addr_to_index_computed(false),
+ m_name_indexes_computed(false)
{
}
@@ -56,7 +54,7 @@ Symtab::Resize(size_t count)
// Clients should grab the mutex from this symbol table and lock it manually
// when calling this function to avoid performance issues.
m_symbols.resize (count);
- return &m_symbols[0];
+ return m_symbols.empty() ? nullptr : &m_symbols[0];
}
uint32_t
@@ -76,7 +74,7 @@ Symtab::AddSymbol(const Symbol& symbol)
size_t
Symtab::GetNumSymbols() const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_symbols.size();
}
@@ -90,9 +88,9 @@ Symtab::SectionFileAddressesChanged ()
void
Symtab::Dump (Stream *s, Target *target, SortOrder sort_order)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
-// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
+ // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
s->Indent();
const FileSpec &file_spec = m_objfile->GetFileSpec();
const char * object_name = nullptr;
@@ -171,7 +169,7 @@ Symtab::Dump (Stream *s, Target *target, SortOrder sort_order)
void
Symtab::Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const size_t num_symbols = GetNumSymbols();
//s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
@@ -224,7 +222,7 @@ CompareSymbolID (const void *key, const void *p)
Symbol *
Symtab::FindSymbolByID (lldb::user_id_t symbol_uid) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Symbol *symbol = (Symbol*)::bsearch (&symbol_uid,
&m_symbols[0],
@@ -474,7 +472,7 @@ Symtab::AppendSymbolNamesToMap (const IndexCollection &indexes,
if (add_demangled || add_mangled)
{
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Create the name index vector to be able to quickly search by name
NameToIndexMap::Entry entry;
@@ -506,7 +504,7 @@ Symtab::AppendSymbolNamesToMap (const IndexCollection &indexes,
uint32_t
Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t prev_size = indexes.size();
@@ -524,7 +522,7 @@ Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, std::vector<uint32_
uint32_t
Symtab::AppendSymbolIndexesWithTypeAndFlagsValue (SymbolType symbol_type, uint32_t flags_value, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t prev_size = indexes.size();
@@ -542,7 +540,7 @@ Symtab::AppendSymbolIndexesWithTypeAndFlagsValue (SymbolType symbol_type, uint32
uint32_t
Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t prev_size = indexes.size();
@@ -632,7 +630,7 @@ namespace {
void
Symtab::SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer (__PRETTY_FUNCTION__,__PRETTY_FUNCTION__);
// No need to sort if we have zero or one items...
@@ -657,7 +655,7 @@ Symtab::SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_du
uint32_t
Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector<uint32_t>& indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
if (symbol_name)
@@ -674,7 +672,7 @@ Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector
uint32_t
Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
if (symbol_name)
@@ -700,7 +698,7 @@ Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbo
uint32_t
Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, std::vector<uint32_t>& indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (AppendSymbolIndexesWithName(symbol_name, indexes) > 0)
{
@@ -719,7 +717,7 @@ Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, Symb
uint32_t
Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (AppendSymbolIndexesWithName(symbol_name, symbol_debug_type, symbol_visibility, indexes) > 0)
{
@@ -739,7 +737,7 @@ Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, Symb
uint32_t
Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regexp, SymbolType symbol_type, std::vector<uint32_t>& indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t prev_size = indexes.size();
uint32_t sym_end = m_symbols.size();
@@ -763,7 +761,7 @@ Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regexp
uint32_t
Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regexp, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t prev_size = indexes.size();
uint32_t sym_end = m_symbols.size();
@@ -790,7 +788,7 @@ Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regexp
Symbol *
Symtab::FindSymbolWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t& start_idx)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const size_t count = m_symbols.size();
for (size_t idx = start_idx; idx < count; ++idx)
@@ -810,7 +808,7 @@ Symtab::FindSymbolWithType (SymbolType symbol_type, Debug symbol_debug_type, Vis
size_t
Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, std::vector<uint32_t>& symbol_indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
// Initialize all of the lookup by name indexes before converting NAME
@@ -830,7 +828,7 @@ Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbo
size_t
Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
// Initialize all of the lookup by name indexes before converting NAME
@@ -850,7 +848,7 @@ Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbo
size_t
Symtab::FindAllSymbolsMatchingRexExAndType (const RegularExpression &regex, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type, symbol_visibility, symbol_indexes);
return symbol_indexes.size();
@@ -859,7 +857,7 @@ Symtab::FindAllSymbolsMatchingRexExAndType (const RegularExpression &regex, Symb
Symbol *
Symtab::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
if (!m_name_indexes_computed)
@@ -894,33 +892,39 @@ typedef struct
addr_t match_offset;
} SymbolSearchInfo;
-static int
-SymbolWithClosestFileAddress (SymbolSearchInfo *info, const uint32_t *index_ptr)
+// Add all the section file start address & size to the RangeVector,
+// recusively adding any children sections.
+static void
+AddSectionsToRangeMap (SectionList *sectlist, RangeVector<addr_t, addr_t> &section_ranges)
{
- const Symbol *symbol = info->symtab->SymbolAtIndex (index_ptr[0]);
- if (symbol == nullptr)
- return -1;
-
- const addr_t info_file_addr = info->file_addr;
- if (symbol->ValueIsAddress())
+ const int num_sections = sectlist->GetNumSections (0);
+ for (int i = 0; i < num_sections; i++)
{
- const addr_t curr_file_addr = symbol->GetAddressRef().GetFileAddress();
- if (info_file_addr < curr_file_addr)
- return -1;
-
- // Since we are finding the closest symbol that is greater than or equal
- // to 'info->file_addr' we set the symbol here. This will get set
- // multiple times, but after the search is done it will contain the best
- // symbol match
- info->match_symbol = const_cast<Symbol *>(symbol);
- info->match_index_ptr = index_ptr;
- info->match_offset = info_file_addr - curr_file_addr;
-
- if (info_file_addr > curr_file_addr)
- return +1;
- return 0;
+ SectionSP sect_sp = sectlist->GetSectionAtIndex (i);
+ if (sect_sp)
+ {
+ SectionList &child_sectlist = sect_sp->GetChildren();
+
+ // If this section has children, add the children to the RangeVector.
+ // Else add this section to the RangeVector.
+ if (child_sectlist.GetNumSections (0) > 0)
+ {
+ AddSectionsToRangeMap (&child_sectlist, section_ranges);
+ }
+ else
+ {
+ size_t size = sect_sp->GetByteSize();
+ if (size > 0)
+ {
+ addr_t base_addr = sect_sp->GetFileAddress();
+ RangeVector<addr_t, addr_t>::Entry entry;
+ entry.SetRangeBase (base_addr);
+ entry.SetByteSize (size);
+ section_ranges.Append (entry);
+ }
+ }
+ }
}
- return -1;
}
void
@@ -948,35 +952,69 @@ Symtab::InitAddressIndexes()
if (num_entries > 0)
{
m_file_addr_to_index.Sort();
- m_file_addr_to_index.CalculateSizesOfZeroByteSizeRanges();
-
- // Now our last symbols might not have had sizes because there
- // was no subsequent symbol to calculate the size from. If this is
- // the case, then calculate the size by capping it at the end of the
- // section in which the symbol resides
- for (int i = num_entries - 1; i >= 0; --i)
+
+ // Create a RangeVector with the start & size of all the sections for
+ // this objfile. We'll need to check this for any FileRangeToIndexMap
+ // entries with an uninitialized size, which could potentially be a
+ // large number so reconstituting the weak pointer is busywork when it
+ // is invariant information.
+ SectionList *sectlist = m_objfile->GetSectionList();
+ RangeVector<addr_t, addr_t> section_ranges;
+ if (sectlist)
+ {
+ AddSectionsToRangeMap (sectlist, section_ranges);
+ section_ranges.Sort();
+ }
+
+ // Iterate through the FileRangeToIndexMap and fill in the size for any
+ // entries that didn't already have a size from the Symbol (e.g. if we
+ // have a plain linker symbol with an address only, instead of debug info
+ // where we get an address and a size and a type, etc.)
+ for (size_t i = 0; i < num_entries; i++)
{
- const FileRangeToIndexMap::Entry &entry = m_file_addr_to_index.GetEntryRef(i);
- // As we iterate backwards, as soon as we find a symbol with a valid
- // byte size, we are done
- if (entry.GetByteSize() > 0)
- break;
-
- // Cap the size to the end of the section in which the symbol resides
- SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (entry.GetRangeBase()));
- if (section_sp)
+ FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.GetMutableEntryAtIndex (i);
+ if (entry->GetByteSize() == 0)
{
- const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize();
- const lldb::addr_t symbol_file_addr = entry.GetRangeBase();
- if (end_section_file_addr > symbol_file_addr)
+ addr_t curr_base_addr = entry->GetRangeBase();
+ const RangeVector<addr_t, addr_t>::Entry *containing_section =
+ section_ranges.FindEntryThatContains (curr_base_addr);
+
+ // Use the end of the section as the default max size of the symbol
+ addr_t sym_size = 0;
+ if (containing_section)
{
- Symbol &symbol = m_symbols[entry.data];
+ sym_size = containing_section->GetByteSize() -
+ (entry->GetRangeBase() - containing_section->GetRangeBase());
+ }
+
+ for (size_t j = i; j < num_entries; j++)
+ {
+ FileRangeToIndexMap::Entry *next_entry = m_file_addr_to_index.GetMutableEntryAtIndex (j);
+ addr_t next_base_addr = next_entry->GetRangeBase();
+ if (next_base_addr > curr_base_addr)
+ {
+ addr_t size_to_next_symbol = next_base_addr - curr_base_addr;
- symbol.SetByteSize(end_section_file_addr - symbol_file_addr);
- symbol.SetSizeIsSynthesized(true);
+ // Take the difference between this symbol and the next one as its size,
+ // if it is less than the size of the section.
+ if (sym_size == 0 || size_to_next_symbol < sym_size)
+ {
+ sym_size = size_to_next_symbol;
+ }
+ break;
+ }
+ }
+
+ if (sym_size > 0)
+ {
+ entry->SetByteSize (sym_size);
+ Symbol &symbol = m_symbols[entry->data];
+ symbol.SetByteSize (sym_size);
+ symbol.SetSizeIsSynthesized (true);
}
}
}
+
// Sort again in case the range size changes the ordering
m_file_addr_to_index.Sort();
}
@@ -986,7 +1024,7 @@ Symtab::InitAddressIndexes()
void
Symtab::CalculateSymbolSizes ()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_symbols.empty())
{
@@ -1018,40 +1056,18 @@ Symtab::CalculateSymbolSizes ()
}
Symbol *
-Symtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes)
+Symtab::FindSymbolAtFileAddress (addr_t file_addr)
{
- Mutex::Locker locker (m_mutex);
-
-
- SymbolSearchInfo info = { this, file_addr, nullptr, nullptr, 0 };
-
- ::bsearch (&info,
- indexes,
- num_indexes,
- sizeof(uint32_t),
- (ComparisonFunction)SymbolWithClosestFileAddress);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (!m_file_addr_to_index_computed)
+ InitAddressIndexes();
- if (info.match_symbol)
+ const FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.FindEntryStartsAt(file_addr);
+ if (entry)
{
- if (info.match_offset == 0)
- {
- // We found an exact match!
- return info.match_symbol;
- }
-
- const size_t symbol_byte_size = info.match_symbol->GetByteSize();
-
- if (symbol_byte_size == 0)
- {
- // We weren't able to find the size of the symbol so lets just go
- // with that match we found in our search...
- return info.match_symbol;
- }
-
- // We were able to figure out a symbol size so lets make sure our
- // offset puts "file_addr" in the symbol's address range.
- if (info.match_offset < symbol_byte_size)
- return info.match_symbol;
+ Symbol* symbol = SymbolAtIndex(entry->data);
+ if (symbol->GetFileAddress() == file_addr)
+ return symbol;
}
return nullptr;
}
@@ -1059,21 +1075,25 @@ Symtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* index
Symbol *
Symtab::FindSymbolContainingFileAddress (addr_t file_addr)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_file_addr_to_index_computed)
InitAddressIndexes();
const FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.FindEntryThatContains(file_addr);
if (entry)
- return SymbolAtIndex(entry->data);
+ {
+ Symbol* symbol = SymbolAtIndex(entry->data);
+ if (symbol->ContainsFileAddress(file_addr))
+ return symbol;
+ }
return nullptr;
}
void
Symtab::ForEachSymbolContainingFileAddress(addr_t file_addr, std::function<bool(Symbol *)> const &callback)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_file_addr_to_index_computed)
InitAddressIndexes();
@@ -1085,8 +1105,12 @@ Symtab::ForEachSymbolContainingFileAddress(addr_t file_addr, std::function<bool(
for (size_t i = 0; i < addr_match_count; ++i)
{
- if (!callback(SymbolAtIndex(all_addr_indexes[i])))
- break;
+ Symbol* symbol = SymbolAtIndex(all_addr_indexes[i]);
+ if (symbol->ContainsFileAddress(file_addr))
+ {
+ if (!callback(symbol))
+ break;
+ }
}
}
@@ -1133,7 +1157,7 @@ Symtab::FindFunctionSymbols (const ConstString &name,
unsigned temp_symbol_indexes_size = temp_symbol_indexes.size();
if (temp_symbol_indexes_size > 0)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
for (unsigned i = 0; i < temp_symbol_indexes_size; i++)
{
SymbolContext sym_ctx;
diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp
index 8061e016ca59..8b51d99ece38 100644
--- a/source/Symbol/Type.cpp
+++ b/source/Symbol/Type.cpp
@@ -559,8 +559,8 @@ Type::ResolveClangType (ResolveState compiler_type_resolve_state)
break;
case eEncodingIsTypedefUID:
- m_compiler_type = encoding_type->GetForwardCompilerType ().CreateTypedef(GetName().AsCString(),
- GetSymbolFile()->GetDeclContextContainingUID(GetID()));
+ m_compiler_type = encoding_type->GetForwardCompilerType ().CreateTypedef(m_name.AsCString("__lldb_invalid_typedef_name"),
+ GetSymbolFile()->GetDeclContextContainingUID(GetID()));
m_name.Clear();
break;
@@ -605,8 +605,8 @@ Type::ResolveClangType (ResolveState compiler_type_resolve_state)
break;
case eEncodingIsTypedefUID:
- m_compiler_type = void_compiler_type.CreateTypedef(GetName().AsCString(),
- GetSymbolFile()->GetDeclContextContainingUID(GetID()));
+ m_compiler_type = void_compiler_type.CreateTypedef(m_name.AsCString("__lldb_invalid_typedef_name"),
+ GetSymbolFile()->GetDeclContextContainingUID(GetID()));
break;
case eEncodingIsPointerUID:
diff --git a/source/Symbol/TypeSystem.cpp b/source/Symbol/TypeSystem.cpp
index 5c2ab5cceab6..2cd82f221f91 100644
--- a/source/Symbol/TypeSystem.cpp
+++ b/source/Symbol/TypeSystem.cpp
@@ -153,7 +153,9 @@ TypeSystem::DeclGetFunctionArgumentType (void *opaque_decl, size_t arg_idx)
std::vector<CompilerDecl>
-TypeSystem::DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name)
+TypeSystem::DeclContextFindDeclByName (void *opaque_decl_ctx,
+ ConstString name,
+ bool ignore_imported_decls)
{
return std::vector<CompilerDecl>();
}
@@ -161,9 +163,7 @@ TypeSystem::DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name)
#pragma mark TypeSystemMap
-TypeSystemMap::TypeSystemMap() :
- m_mutex (),
- m_map ()
+TypeSystemMap::TypeSystemMap() : m_mutex(), m_map(), m_clear_in_progress(false)
{
}
@@ -174,15 +174,35 @@ TypeSystemMap::~TypeSystemMap()
void
TypeSystemMap::Clear ()
{
- Mutex::Locker locker (m_mutex);
- m_map.clear();
+ collection map;
+ {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ map = m_map;
+ m_clear_in_progress = true;
+ }
+ std::set<TypeSystem *> visited;
+ for (auto pair : map)
+ {
+ TypeSystem *type_system = pair.second.get();
+ if (type_system && !visited.count(type_system))
+ {
+ visited.insert(type_system);
+ type_system->Finalize();
+ }
+ }
+ map.clear();
+ {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ m_map.clear();
+ m_clear_in_progress = false;
+ }
}
void
TypeSystemMap::ForEach (std::function <bool(TypeSystem *)> const &callback)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
// Use a std::set so we only call the callback once for each unique
// TypeSystem instance
std::set<TypeSystem *> visited;
@@ -201,7 +221,7 @@ TypeSystemMap::ForEach (std::function <bool(TypeSystem *)> const &callback)
TypeSystem *
TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Module *module, bool can_create)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
collection::iterator pos = m_map.find(language);
if (pos != m_map.end())
return pos->second.get();
@@ -212,7 +232,7 @@ TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Module *mo
{
// Add a new mapping for "language" to point to an already existing
// TypeSystem that supports this language
- m_map[language] = pair.second;
+ AddToMap(language, pair.second);
return pair.second.get();
}
}
@@ -222,14 +242,14 @@ TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Module *mo
// Cache even if we get a shared pointer that contains null type system back
lldb::TypeSystemSP type_system_sp = TypeSystem::CreateInstance (language, module);
- m_map[language] = type_system_sp;
+ AddToMap (language, type_system_sp);
return type_system_sp.get();
}
TypeSystem *
TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Target *target, bool can_create)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
collection::iterator pos = m_map.find(language);
if (pos != m_map.end())
return pos->second.get();
@@ -240,7 +260,8 @@ TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Target *ta
{
// Add a new mapping for "language" to point to an already existing
// TypeSystem that supports this language
- m_map[language] = pair.second;
+
+ AddToMap(language, pair.second);
return pair.second.get();
}
}
@@ -249,7 +270,17 @@ TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Target *ta
return nullptr;
// Cache even if we get a shared pointer that contains null type system back
- lldb::TypeSystemSP type_system_sp = TypeSystem::CreateInstance (language, target);
- m_map[language] = type_system_sp;
+ lldb::TypeSystemSP type_system_sp;
+ if (!m_clear_in_progress)
+ type_system_sp = TypeSystem::CreateInstance (language, target);
+
+ AddToMap(language, type_system_sp);
return type_system_sp.get();
}
+
+void
+TypeSystemMap::AddToMap (lldb::LanguageType language, lldb::TypeSystemSP const &type_system_sp)
+{
+ if (!m_clear_in_progress)
+ m_map[language] = type_system_sp;
+}
diff --git a/source/Symbol/UnwindPlan.cpp b/source/Symbol/UnwindPlan.cpp
index 80c22c08ee4f..18f0cb7b9dbd 100644
--- a/source/Symbol/UnwindPlan.cpp
+++ b/source/Symbol/UnwindPlan.cpp
@@ -338,7 +338,7 @@ UnwindPlan::AppendRow (const UnwindPlan::RowSP &row_sp)
}
void
-UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp)
+UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp, bool replace_existing)
{
collection::iterator it = m_row_list.begin();
while (it != m_row_list.end()) {
@@ -349,6 +349,8 @@ UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp)
}
if (it == m_row_list.end() || (*it)->GetOffset() != row_sp->GetOffset())
m_row_list.insert(it, row_sp);
+ else if (replace_existing)
+ *it = row_sp;
}
UnwindPlan::RowSP
@@ -383,16 +385,27 @@ UnwindPlan::IsValidRowIndex (uint32_t idx) const
const UnwindPlan::RowSP
UnwindPlan::GetRowAtIndex (uint32_t idx) const
{
- // You must call IsValidRowIndex(idx) first before calling this!!!
- assert (idx < m_row_list.size());
- return m_row_list[idx];
+ if (idx < m_row_list.size())
+ return m_row_list[idx];
+ else
+ {
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ if (log)
+ log->Printf ("error: UnwindPlan::GetRowAtIndex(idx = %u) invalid index (number rows is %u)", idx, (uint32_t)m_row_list.size());
+ return UnwindPlan::RowSP();
+ }
}
const UnwindPlan::RowSP
UnwindPlan::GetLastRow () const
{
- // You must call GetRowCount() first to make sure there is at least one row
- assert (!m_row_list.empty());
+ if (m_row_list.empty())
+ {
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ if (log)
+ log->Printf ("UnwindPlan::GetLastRow() when rows are empty");
+ return UnwindPlan::RowSP();
+ }
return m_row_list.back();
}
diff --git a/source/Symbol/UnwindTable.cpp b/source/Symbol/UnwindTable.cpp
index ac7a9b0fda87..87c18d94b070 100644
--- a/source/Symbol/UnwindTable.cpp
+++ b/source/Symbol/UnwindTable.cpp
@@ -27,14 +27,14 @@
using namespace lldb;
using namespace lldb_private;
-UnwindTable::UnwindTable (ObjectFile& objfile) :
- m_object_file (objfile),
- m_unwinds (),
- m_initialized (false),
- m_mutex (),
- m_eh_frame_up (),
- m_compact_unwind_up (),
- m_arm_unwind_up ()
+UnwindTable::UnwindTable(ObjectFile &objfile)
+ : m_object_file(objfile),
+ m_unwinds(),
+ m_initialized(false),
+ m_mutex(),
+ m_eh_frame_up(),
+ m_compact_unwind_up(),
+ m_arm_unwind_up()
{
}
@@ -47,7 +47,7 @@ UnwindTable::Initialize ()
if (m_initialized)
return;
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
if (m_initialized) // check again once we've acquired the lock
return;
@@ -90,7 +90,7 @@ UnwindTable::GetFuncUnwindersContainingAddress (const Address& addr, SymbolConte
Initialize();
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
// There is an UnwindTable per object file, so we can safely use file handles
addr_t file_addr = addr.GetFileAddress();
@@ -152,7 +152,7 @@ UnwindTable::GetUncachedFuncUnwindersContainingAddress (const Address& addr, Sym
void
UnwindTable::Dump (Stream &s)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
s.Printf("UnwindTable for '%s':\n", m_object_file.GetFileSpec().GetPath().c_str());
const_iterator begin = m_unwinds.begin();
const_iterator end = m_unwinds.end();
@@ -189,3 +189,9 @@ UnwindTable::GetArchitecture (lldb_private::ArchSpec &arch)
{
return m_object_file.GetArchitecture (arch);
}
+
+bool
+UnwindTable::GetAllowAssemblyEmulationUnwindPlans ()
+{
+ return m_object_file.AllowAssemblyEmulationUnwindPlans ();
+}
diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp
index 51d11b7ca8e9..dd27b1b5d802 100644
--- a/source/Symbol/Variable.cpp
+++ b/source/Symbol/Variable.cpp
@@ -43,6 +43,7 @@ Variable::Variable (lldb::user_id_t uid,
const lldb::SymbolFileTypeSP &symfile_type_sp,
ValueType scope,
SymbolContextScope *context,
+ const RangeList& scope_range,
Declaration* decl_ptr,
const DWARFExpression& location,
bool external,
@@ -54,6 +55,7 @@ Variable::Variable (lldb::user_id_t uid,
m_symfile_type_sp(symfile_type_sp),
m_scope(scope),
m_owner_scope(context),
+ m_scope_range(scope_range),
m_declaration(decl_ptr),
m_location(location),
m_external(external),
@@ -155,8 +157,13 @@ Variable::Dump(Stream *s, bool show_context) const
switch (m_scope)
{
case eValueTypeVariableGlobal: s->PutCString(m_external ? "global" : "static"); break;
- case eValueTypeVariableArgument: s->PutCString("parameter"); break;
+ case eValueTypeVariableArgument:
+ s->PutCString("parameter");
+ break;
case eValueTypeVariableLocal: s->PutCString("local"); break;
+ case eValueTypeVariableThreadLocal:
+ s->PutCString("thread local");
+ break;
default: *s << "??? (" << m_scope << ')';
}
}
@@ -242,17 +249,16 @@ CompilerDeclContext
Variable::GetDeclContext ()
{
Type *type = GetType();
- return type->GetSymbolFile()->GetDeclContextContainingUID(GetID());
+ if (type)
+ return type->GetSymbolFile()->GetDeclContextContainingUID(GetID());
+ return CompilerDeclContext();
}
CompilerDecl
Variable::GetDecl ()
{
Type *type = GetType();
- CompilerDecl decl = type->GetSymbolFile()->GetDeclForUID(GetID());
- if (decl)
- decl.GetTypeSystem()->DeclLinkToObject(decl.GetOpaqueDecl(), shared_from_this());
- return decl;
+ return type ? type->GetSymbolFile()->GetDeclForUID(GetID()) : CompilerDecl();
}
void
@@ -343,6 +349,7 @@ Variable::IsInScope (StackFrame *frame)
case eValueTypeConstResult:
case eValueTypeVariableGlobal:
case eValueTypeVariableStatic:
+ case eValueTypeVariableThreadLocal:
return true;
case eValueTypeVariableArgument:
@@ -356,14 +363,24 @@ Variable::IsInScope (StackFrame *frame)
{
SymbolContext variable_sc;
CalculateSymbolContext (&variable_sc);
+
// Check for static or global variable defined at the compile unit
// level that wasn't defined in a block
if (variable_sc.block == nullptr)
- return true;
+ return true;
- if (variable_sc.block == deepest_frame_block)
+ // Check if the variable is valid in the current block
+ if (variable_sc.block != deepest_frame_block &&
+ !variable_sc.block->Contains(deepest_frame_block))
+ return false;
+
+ // If no scope range is specified then it means that the scope is the same as the
+ // scope of the enclosing lexical block.
+ if (m_scope_range.IsEmpty())
return true;
- return variable_sc.block->Contains (deepest_frame_block);
+
+ addr_t file_address = frame->GetFrameCodeAddress().GetFileAddress();
+ return m_scope_range.FindEntryThatContains(file_address) != nullptr;
}
}
break;
@@ -816,6 +833,7 @@ PrivateAutoComplete (StackFrame *frame,
word_complete);
}
}
+ break;
default:
break;
}
@@ -852,6 +870,7 @@ PrivateAutoComplete (StackFrame *frame,
matches,
word_complete);
}
+ break;
default:
break;
}
diff --git a/source/Target/ABI.cpp b/source/Target/ABI.cpp
index 4d67cb46abe4..f5fd594877f1 100644
--- a/source/Target/ABI.cpp
+++ b/source/Target/ABI.cpp
@@ -7,6 +7,10 @@
//
//===----------------------------------------------------------------------===//
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Value.h"
@@ -27,7 +31,7 @@ ABI::FindPlugin (const ArchSpec &arch)
ABICreateInstance create_callback;
for (uint32_t idx = 0;
- (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != NULL;
+ (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != nullptr;
++idx)
{
abi_sp = create_callback(arch);
@@ -39,19 +43,9 @@ ABI::FindPlugin (const ArchSpec &arch)
return abi_sp;
}
-//----------------------------------------------------------------------
-// Constructor
-//----------------------------------------------------------------------
-ABI::ABI()
-{
-}
+ABI::ABI() = default;
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-ABI::~ABI()
-{
-}
+ABI::~ABI() = default;
bool
ABI::GetRegisterInfoByName (const ConstString &name, RegisterInfo &info)
@@ -62,7 +56,7 @@ ABI::GetRegisterInfoByName (const ConstString &name, RegisterInfo &info)
{
const char *unique_name_cstr = name.GetCString();
uint32_t i;
- for (i=0; i<count; ++i)
+ for (i = 0; i < count; ++i)
{
if (register_info_array[i].name == unique_name_cstr)
{
@@ -70,7 +64,7 @@ ABI::GetRegisterInfoByName (const ConstString &name, RegisterInfo &info)
return true;
}
}
- for (i=0; i<count; ++i)
+ for (i = 0; i < count; ++i)
{
if (register_info_array[i].alt_name == unique_name_cstr)
{
@@ -92,7 +86,7 @@ ABI::GetRegisterInfoByKind (RegisterKind reg_kind, uint32_t reg_num, RegisterInf
const RegisterInfo *register_info_array = GetRegisterInfoArray (count);
if (register_info_array)
{
- for (uint32_t i=0; i<count; ++i)
+ for (uint32_t i = 0; i < count; ++i)
{
if (register_info_array[i].kinds[reg_kind] == reg_num)
{
@@ -148,7 +142,7 @@ ABI::GetReturnValueObject (Thread &thread,
ExpressionVariableSP clang_expr_variable_sp(persistent_expression_state->CreatePersistentVariable(return_valobj_sp));
- assert (clang_expr_variable_sp.get());
+ assert (clang_expr_variable_sp);
// Set flags and live data as appropriate
@@ -211,3 +205,27 @@ ABI::PrepareTrivialCall (Thread &thread,
assert( !"Should never get here!" );
return false;
}
+
+bool
+ABI::GetFallbackRegisterLocation (const RegisterInfo *reg_info,
+ UnwindPlan::Row::RegisterLocation &unwind_regloc)
+{
+ // Did the UnwindPlan fail to give us the caller's stack pointer?
+ // The stack pointer is defined to be the same as THIS frame's CFA, so return the CFA value as
+ // the caller's stack pointer. This is true on x86-32/x86-64 at least.
+ if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP)
+ {
+ unwind_regloc.SetIsCFAPlusOffset(0);
+ return true;
+ }
+
+ // If a volatile register is being requested, we don't want to forward the next frame's register contents
+ // up the stack -- the register is not retrievable at this frame.
+ if (RegisterIsVolatile(reg_info))
+ {
+ unwind_regloc.SetUndefined();
+ return true;
+ }
+
+ return false;
+}
diff --git a/source/Target/ExecutionContext.cpp b/source/Target/ExecutionContext.cpp
index ff584361c296..41f076a205e9 100644
--- a/source/Target/ExecutionContext.cpp
+++ b/source/Target/ExecutionContext.cpp
@@ -7,8 +7,11 @@
//
//===----------------------------------------------------------------------===//
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
#include "lldb/Target/ExecutionContext.h"
-
#include "lldb/Core/State.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/StackFrame.h"
@@ -183,18 +186,17 @@ ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr,
}
}
-ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, Mutex::Locker &locker) :
- m_target_sp (),
- m_process_sp (),
- m_thread_sp (),
- m_frame_sp ()
+ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
+ std::unique_lock<std::recursive_mutex> &lock)
+ : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp()
{
if (exe_ctx_ref_ptr)
{
- m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
+ m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
if (m_target_sp)
{
- locker.Lock(m_target_sp->GetAPIMutex());
+ lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
+
m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
@@ -202,18 +204,16 @@ ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr,
}
}
-ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref, Mutex::Locker &locker) :
- m_target_sp (exe_ctx_ref.GetTargetSP()),
- m_process_sp (),
- m_thread_sp (),
- m_frame_sp ()
+ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref, std::unique_lock<std::recursive_mutex> &lock)
+ : m_target_sp(exe_ctx_ref.GetTargetSP()), m_process_sp(), m_thread_sp(), m_frame_sp()
{
if (m_target_sp)
{
- locker.Lock(m_target_sp->GetAPIMutex());
+ lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
+
m_process_sp = exe_ctx_ref.GetProcessSP();
- m_thread_sp = exe_ctx_ref.GetThreadSP();
- m_frame_sp = exe_ctx_ref.GetFrameSP();
+ m_thread_sp = exe_ctx_ref.GetThreadSP();
+ m_frame_sp = exe_ctx_ref.GetFrameSP();
}
}
@@ -241,9 +241,7 @@ ExecutionContext::Clear()
m_frame_sp.reset();
}
-ExecutionContext::~ExecutionContext()
-{
-}
+ExecutionContext::~ExecutionContext() = default;
uint32_t
ExecutionContext::GetAddressByteSize() const
@@ -272,7 +270,7 @@ ExecutionContext::GetRegisterContext () const
return m_frame_sp->GetRegisterContext().get();
else if (m_thread_sp)
return m_thread_sp->GetRegisterContext().get();
- return NULL;
+ return nullptr;
}
Target *
@@ -282,7 +280,7 @@ ExecutionContext::GetTargetPtr () const
return m_target_sp.get();
if (m_process_sp)
return &m_process_sp->GetTarget();
- return NULL;
+ return nullptr;
}
Process *
@@ -292,7 +290,7 @@ ExecutionContext::GetProcessPtr () const
return m_process_sp.get();
if (m_target_sp)
return m_target_sp->GetProcessSP().get();
- return NULL;
+ return nullptr;
}
ExecutionContextScope *
@@ -311,7 +309,7 @@ Target &
ExecutionContext::GetTargetRef () const
{
#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
- assert (m_target_sp.get());
+ assert (m_target_sp);
#endif
return *m_target_sp;
}
@@ -320,7 +318,7 @@ Process &
ExecutionContext::GetProcessRef () const
{
#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
- assert (m_process_sp.get());
+ assert (m_process_sp);
#endif
return *m_process_sp;
}
@@ -329,7 +327,7 @@ Thread &
ExecutionContext::GetThreadRef () const
{
#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
- assert (m_thread_sp.get());
+ assert (m_thread_sp);
#endif
return *m_thread_sp;
}
@@ -338,7 +336,7 @@ StackFrame &
ExecutionContext::GetFrameRef () const
{
#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
- assert (m_frame_sp.get());
+ assert (m_frame_sp);
#endif
return *m_frame_sp;
}
@@ -572,7 +570,6 @@ ExecutionContextRef::ExecutionContextRef (const ExecutionContext &exe_ctx) :
*this = exe_ctx;
}
-
ExecutionContextRef::ExecutionContextRef (Target *target, bool adopt_selected) :
m_target_wp(),
m_process_wp(),
@@ -583,9 +580,6 @@ ExecutionContextRef::ExecutionContextRef (Target *target, bool adopt_selected) :
SetTargetPtr (target, adopt_selected);
}
-
-
-
ExecutionContextRef::ExecutionContextRef (const ExecutionContextRef &rhs) :
m_target_wp (rhs.m_target_wp),
m_process_wp(rhs.m_process_wp),
@@ -637,9 +631,7 @@ ExecutionContextRef::Clear()
ClearFrame();
}
-ExecutionContextRef::~ExecutionContextRef()
-{
-}
+ExecutionContextRef::~ExecutionContextRef() = default;
void
ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp)
@@ -694,7 +686,6 @@ ExecutionContextRef::SetFrameSP (const lldb::StackFrameSP &frame_sp)
m_process_wp.reset();
m_target_wp.reset();
}
-
}
void
@@ -820,7 +811,7 @@ ExecutionContextRef::GetThreadSP () const
}
}
- // Check that we aren't about to return an invalid thread sp. We might return a NULL thread_sp,
+ // Check that we aren't about to return an invalid thread sp. We might return a nullptr thread_sp,
// but don't return an invalid one.
if (thread_sp && !thread_sp->IsValid())
@@ -846,5 +837,3 @@ ExecutionContextRef::Lock (bool thread_and_frame_only_if_stopped) const
{
return ExecutionContext(this, thread_and_frame_only_if_stopped);
}
-
-
diff --git a/source/Target/InstrumentationRuntime.cpp b/source/Target/InstrumentationRuntime.cpp
index b3b2393b0234..af7955f9c34b 100644
--- a/source/Target/InstrumentationRuntime.cpp
+++ b/source/Target/InstrumentationRuntime.cpp
@@ -5,8 +5,12 @@
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===----------------------------------------------------------------------===//
+//===---------------------------------------------------------------------===//
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Target/Process.h"
#include "lldb/Core/PluginManager.h"
@@ -18,12 +22,12 @@ using namespace lldb_private;
void
InstrumentationRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list, lldb_private::Process *process, InstrumentationRuntimeCollection &runtimes)
{
- InstrumentationRuntimeCreateInstance create_callback = NULL;
+ InstrumentationRuntimeCreateInstance create_callback = nullptr;
InstrumentationRuntimeGetType get_type_callback;
for (uint32_t idx = 0; ; ++idx)
{
create_callback = PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(idx);
- if (create_callback == NULL)
+ if (create_callback == nullptr)
break;
get_type_callback = PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(idx);
InstrumentationRuntimeType type = get_type_callback();
@@ -46,3 +50,9 @@ InstrumentationRuntime::IsActive()
{
return false;
}
+
+lldb::ThreadCollectionSP
+InstrumentationRuntime::GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info)
+{
+ return ThreadCollectionSP(new ThreadCollection());
+}
diff --git a/source/Target/JITLoader.cpp b/source/Target/JITLoader.cpp
index 8536d690ece0..2e37fb0ff4e6 100644
--- a/source/Target/JITLoader.cpp
+++ b/source/Target/JITLoader.cpp
@@ -7,6 +7,10 @@
//
//===----------------------------------------------------------------------===//
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Target/JITLoader.h"
#include "lldb/Target/JITLoaderList.h"
@@ -19,8 +23,8 @@ using namespace lldb_private;
void
JITLoader::LoadPlugins (Process *process, JITLoaderList &list)
{
- JITLoaderCreateInstance create_callback = NULL;
- for (uint32_t idx = 0; (create_callback = PluginManager::GetJITLoaderCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ JITLoaderCreateInstance create_callback = nullptr;
+ for (uint32_t idx = 0; (create_callback = PluginManager::GetJITLoaderCreateCallbackAtIndex(idx)) != nullptr; ++idx)
{
JITLoaderSP instance_sp(create_callback(process, false));
if (instance_sp)
@@ -33,6 +37,4 @@ JITLoader::JITLoader(Process *process) :
{
}
-JITLoader::~JITLoader()
-{
-}
+JITLoader::~JITLoader() = default;
diff --git a/source/Target/JITLoaderList.cpp b/source/Target/JITLoaderList.cpp
index 24a73b7fd516..76c9dd675355 100644
--- a/source/Target/JITLoaderList.cpp
+++ b/source/Target/JITLoaderList.cpp
@@ -14,8 +14,7 @@
using namespace lldb;
using namespace lldb_private;
-JITLoaderList::JITLoaderList()
- : m_jit_loaders_vec(), m_jit_loaders_mutex(Mutex::eMutexTypeRecursive)
+JITLoaderList::JITLoaderList() : m_jit_loaders_vec(), m_jit_loaders_mutex()
{
}
@@ -26,14 +25,14 @@ JITLoaderList::~JITLoaderList()
void
JITLoaderList::Append (const JITLoaderSP &jit_loader_sp)
{
- Mutex::Locker locker(m_jit_loaders_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex);
m_jit_loaders_vec.push_back(jit_loader_sp);
}
void
JITLoaderList::Remove (const JITLoaderSP &jit_loader_sp)
{
- Mutex::Locker locker(m_jit_loaders_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex);
m_jit_loaders_vec.erase(std::remove(m_jit_loaders_vec.begin(),
m_jit_loaders_vec.end(), jit_loader_sp),
m_jit_loaders_vec.end());
@@ -48,14 +47,14 @@ JITLoaderList::GetSize() const
JITLoaderSP
JITLoaderList::GetLoaderAtIndex (size_t idx)
{
- Mutex::Locker locker(m_jit_loaders_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex);
return m_jit_loaders_vec[idx];
}
void
JITLoaderList::DidLaunch()
{
- Mutex::Locker locker(m_jit_loaders_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex);
for (auto const &jit_loader : m_jit_loaders_vec)
jit_loader->DidLaunch();
}
@@ -63,7 +62,7 @@ JITLoaderList::DidLaunch()
void
JITLoaderList::DidAttach()
{
- Mutex::Locker locker(m_jit_loaders_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex);
for (auto const &jit_loader : m_jit_loaders_vec)
jit_loader->DidAttach();
}
@@ -71,7 +70,7 @@ JITLoaderList::DidAttach()
void
JITLoaderList::ModulesDidLoad(ModuleList &module_list)
{
- Mutex::Locker locker(m_jit_loaders_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_jit_loaders_mutex);
for (auto const &jit_loader : m_jit_loaders_vec)
jit_loader->ModulesDidLoad(module_list);
}
diff --git a/source/Target/Language.cpp b/source/Target/Language.cpp
index d6c7e0a4c4bb..20439b4dc552 100644
--- a/source/Target/Language.cpp
+++ b/source/Target/Language.cpp
@@ -13,7 +13,6 @@
#include "lldb/Target/Language.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Stream.h"
@@ -36,23 +35,23 @@ GetLanguagesMap ()
return *g_map;
}
-static Mutex&
-GetLanguagesMutex ()
+static std::mutex &
+GetLanguagesMutex()
{
- static Mutex *g_mutex = nullptr;
+ static std::mutex *g_mutex = nullptr;
static std::once_flag g_initialize;
-
+
std::call_once(g_initialize, [] {
- g_mutex = new Mutex(); // NOTE: INTENTIONAL LEAK due to global destructor chain
+ g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global destructor chain
});
-
+
return *g_mutex;
}
Language*
Language::FindPlugin (lldb::LanguageType language)
{
- Mutex::Locker locker(GetLanguagesMutex());
+ std::lock_guard<std::mutex> guard(GetLanguagesMutex());
LanguagesMap& map(GetLanguagesMap());
auto iter = map.find(language), end = map.end();
if (iter != end)
@@ -80,7 +79,7 @@ Language::FindPlugin (lldb::LanguageType language)
void
Language::ForEach (std::function<bool(Language*)> callback)
{
- Mutex::Locker locker(GetLanguagesMutex());
+ std::lock_guard<std::mutex> guard(GetLanguagesMutex());
LanguagesMap& map(GetLanguagesMap());
for (const auto& entry : map)
{
@@ -241,6 +240,7 @@ Language::LanguageIsCPlusPlus (LanguageType language)
case eLanguageTypeC_plus_plus_03:
case eLanguageTypeC_plus_plus_11:
case eLanguageTypeC_plus_plus_14:
+ case eLanguageTypeObjC_plus_plus:
return true;
default:
return false;
@@ -367,6 +367,12 @@ Language::GetTypeScavenger ()
return nullptr;
}
+const char*
+Language::GetLanguageSpecificTypeLookupHelp ()
+{
+ return nullptr;
+}
+
size_t
Language::TypeScavenger::Find (ExecutionContextScope *exe_scope,
const char *key,
diff --git a/source/Target/LanguageRuntime.cpp b/source/Target/LanguageRuntime.cpp
index b1e2b3eb04fc..f61af071e3e4 100644
--- a/source/Target/LanguageRuntime.cpp
+++ b/source/Target/LanguageRuntime.cpp
@@ -29,10 +29,10 @@ public:
ExceptionSearchFilter (const lldb::TargetSP &target_sp,
lldb::LanguageType language,
bool update_module_list = true) :
- SearchFilter (target_sp),
- m_language (language),
- m_language_runtime (NULL),
- m_filter_sp ()
+ SearchFilter(target_sp),
+ m_language(language),
+ m_language_runtime(nullptr),
+ m_filter_sp()
{
if (update_module_list)
UpdateModuleListIfNeeded ();
@@ -92,7 +92,7 @@ protected:
if (process_sp)
{
bool refreash_filter = !m_filter_sp;
- if (m_language_runtime == NULL)
+ if (m_language_runtime == nullptr)
{
m_language_runtime = process_sp->GetLanguageRuntime(m_language);
refreash_filter = true;
@@ -115,7 +115,7 @@ protected:
else
{
m_filter_sp.reset();
- m_language_runtime = NULL;
+ m_language_runtime = nullptr;
}
}
};
@@ -128,11 +128,11 @@ public:
ExceptionBreakpointResolver (lldb::LanguageType language,
bool catch_bp,
bool throw_bp) :
- BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver),
- m_language (language),
- m_language_runtime (NULL),
- m_catch_bp (catch_bp),
- m_throw_bp (throw_bp)
+ BreakpointResolver(nullptr, BreakpointResolver::ExceptionResolver),
+ m_language(language),
+ m_language_runtime(nullptr),
+ m_catch_bp(catch_bp),
+ m_throw_bp(throw_bp)
{
}
@@ -207,7 +207,7 @@ protected:
if (process_sp)
{
bool refreash_resolver = !m_actual_resolver_sp;
- if (m_language_runtime == NULL)
+ if (m_language_runtime == nullptr)
{
m_language_runtime = process_sp->GetLanguageRuntime(m_language);
refreash_resolver = true;
@@ -230,16 +230,17 @@ protected:
else
{
m_actual_resolver_sp.reset();
- m_language_runtime = NULL;
+ m_language_runtime = nullptr;
}
}
else
{
m_actual_resolver_sp.reset();
- m_language_runtime = NULL;
+ m_language_runtime = nullptr;
}
return (bool)m_actual_resolver_sp;
}
+
lldb::BreakpointResolverSP m_actual_resolver_sp;
lldb::LanguageType m_language;
LanguageRuntime *m_language_runtime;
@@ -254,16 +255,16 @@ LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language)
LanguageRuntimeCreateInstance create_callback;
for (uint32_t idx = 0;
- (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != NULL;
+ (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != nullptr;
++idx)
{
language_runtime_ap.reset (create_callback(process, language));
- if (language_runtime_ap.get())
+ if (language_runtime_ap)
return language_runtime_ap.release();
}
- return NULL;
+ return nullptr;
}
LanguageRuntime::LanguageRuntime(Process *process) :
@@ -336,6 +337,9 @@ LanguageRuntime::InitializeCommands (CommandObject* parent)
CommandObjectSP command = command_callback(parent->GetCommandInterpreter());
if (command)
{
+ // the CommandObject vended by a Language plugin cannot be created once and cached because
+ // we may create multiple debuggers and need one instance of the command each - the implementing function
+ // is meant to create a new instance of the command each time it is invoked
parent->LoadSubCommand(command->GetCommandName(), command);
}
}
@@ -345,5 +349,5 @@ LanguageRuntime::InitializeCommands (CommandObject* parent)
lldb::SearchFilterSP
LanguageRuntime::CreateExceptionSearchFilter ()
{
- return m_process->GetTarget().GetSearchFilterForModule(NULL);
+ return m_process->GetTarget().GetSearchFilterForModule(nullptr);
}
diff --git a/source/Target/Makefile b/source/Target/Makefile
deleted file mode 100644
index 0d4be5449ad3..000000000000
--- a/source/Target/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Target/Makefile ------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LIBRARYNAME := lldbTarget
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Target/Memory.cpp b/source/Target/Memory.cpp
index c89fd5101147..9f0114812125 100644
--- a/source/Target/Memory.cpp
+++ b/source/Target/Memory.cpp
@@ -25,13 +25,13 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// MemoryCache constructor
//----------------------------------------------------------------------
-MemoryCache::MemoryCache(Process &process) :
- m_mutex (Mutex::eMutexTypeRecursive),
- m_L1_cache (),
- m_L2_cache (),
- m_invalid_ranges (),
- m_process (process),
- m_L2_cache_line_byte_size (process.GetMemoryCacheLineSize())
+MemoryCache::MemoryCache(Process &process)
+ : m_mutex(),
+ m_L1_cache(),
+ m_L2_cache(),
+ m_invalid_ranges(),
+ m_process(process),
+ m_L2_cache_line_byte_size(process.GetMemoryCacheLineSize())
{
}
@@ -45,7 +45,7 @@ MemoryCache::~MemoryCache()
void
MemoryCache::Clear(bool clear_invalid_ranges)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_L1_cache.clear();
m_L2_cache.clear();
if (clear_invalid_ranges)
@@ -62,7 +62,7 @@ MemoryCache::AddL1CacheData(lldb::addr_t addr, const void *src, size_t src_len)
void
MemoryCache::AddL1CacheData(lldb::addr_t addr, const DataBufferSP &data_buffer_sp)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_L1_cache[addr] = data_buffer_sp;
}
@@ -72,13 +72,17 @@ MemoryCache::Flush (addr_t addr, size_t size)
if (size == 0)
return;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Erase any blocks from the L1 cache that intersect with the flush range
if (!m_L1_cache.empty())
{
AddrRange flush_range(addr, size);
- BlockMap::iterator pos = m_L1_cache.lower_bound(addr);
+ BlockMap::iterator pos = m_L1_cache.upper_bound(addr);
+ if (pos != m_L1_cache.begin())
+ {
+ --pos;
+ }
while (pos != m_L1_cache.end())
{
AddrRange chunk_range(pos->first, pos->second->GetByteSize());
@@ -119,7 +123,7 @@ MemoryCache::AddInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size)
{
if (byte_size > 0)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
InvalidRanges::Entry range (base_addr, byte_size);
m_invalid_ranges.Append(range);
m_invalid_ranges.Sort();
@@ -131,7 +135,7 @@ MemoryCache::RemoveInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size)
{
if (byte_size > 0)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const uint32_t idx = m_invalid_ranges.FindEntryIndexThatContains(base_addr);
if (idx != UINT32_MAX)
{
@@ -160,7 +164,7 @@ MemoryCache::Read (addr_t addr,
// m_L2_cache_line_byte_size bytes in size, so we don't try anything
// tricky when reading from them (no partial reads from the L1 cache).
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_L1_cache.empty())
{
AddrRange read_range(addr, dst_len);
@@ -432,11 +436,7 @@ AllocatedBlock::FreeBlock (addr_t addr)
return success;
}
-
-AllocatedMemoryCache::AllocatedMemoryCache (Process &process) :
- m_process (process),
- m_mutex (Mutex::eMutexTypeRecursive),
- m_memory_map()
+AllocatedMemoryCache::AllocatedMemoryCache(Process &process) : m_process(process), m_mutex(), m_memory_map()
{
}
@@ -448,7 +448,7 @@ AllocatedMemoryCache::~AllocatedMemoryCache ()
void
AllocatedMemoryCache::Clear()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_process.IsAlive())
{
PermissionsToBlockMap::iterator pos, end = m_memory_map.end();
@@ -494,8 +494,8 @@ AllocatedMemoryCache::AllocateMemory (size_t byte_size,
uint32_t permissions,
Error &error)
{
- Mutex::Locker locker (m_mutex);
-
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
addr_t addr = LLDB_INVALID_ADDRESS;
std::pair<PermissionsToBlockMap::iterator, PermissionsToBlockMap::iterator> range = m_memory_map.equal_range (permissions);
@@ -522,7 +522,7 @@ AllocatedMemoryCache::AllocateMemory (size_t byte_size,
bool
AllocatedMemoryCache::DeallocateMemory (lldb::addr_t addr)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
PermissionsToBlockMap::iterator pos, end = m_memory_map.end();
bool success = false;
diff --git a/source/Target/MemoryHistory.cpp b/source/Target/MemoryHistory.cpp
index b97096b06d76..33860f868ee5 100644
--- a/source/Target/MemoryHistory.cpp
+++ b/source/Target/MemoryHistory.cpp
@@ -1,4 +1,4 @@
-//===-- MemoryHistory.cpp -------------------------*- C++ -*-===//
+//===-- MemoryHistory.cpp ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,11 @@
//
//===----------------------------------------------------------------------===//
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
#include "lldb/Target/MemoryHistory.h"
-
#include "lldb/Core/PluginManager.h"
using namespace lldb;
@@ -17,12 +20,12 @@ using namespace lldb_private;
lldb::MemoryHistorySP
MemoryHistory::FindPlugin (const ProcessSP process)
{
- MemoryHistoryCreateInstance create_callback = NULL;
+ MemoryHistoryCreateInstance create_callback = nullptr;
- for (uint32_t idx = 0; (create_callback = PluginManager::GetMemoryHistoryCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (uint32_t idx = 0; (create_callback = PluginManager::GetMemoryHistoryCreateCallbackAtIndex(idx)) != nullptr; ++idx)
{
MemoryHistorySP memory_history_sp (create_callback (process));
- if (memory_history_sp.get())
+ if (memory_history_sp)
return memory_history_sp;
}
diff --git a/source/Target/ObjCLanguageRuntime.cpp b/source/Target/ObjCLanguageRuntime.cpp
index a18e4c69c571..8911d9dab35e 100644
--- a/source/Target/ObjCLanguageRuntime.cpp
+++ b/source/Target/ObjCLanguageRuntime.cpp
@@ -16,6 +16,7 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
@@ -122,11 +123,13 @@ ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name)
const bool exact_match = true;
const uint32_t max_matches = UINT32_MAX;
TypeList types;
-
+
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
const uint32_t num_types = module_sp->FindTypes (null_sc,
name,
exact_match,
max_matches,
+ searched_symbol_files,
types);
if (num_types)
diff --git a/source/Target/OperatingSystem.cpp b/source/Target/OperatingSystem.cpp
index 8ba526838777..9b4f2120befa 100644
--- a/source/Target/OperatingSystem.cpp
+++ b/source/Target/OperatingSystem.cpp
@@ -1,4 +1,4 @@
-//===-- OperatingSystem.cpp --------------------------------------------*- C++ -*-===//
+//===-- OperatingSystem.cpp -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,22 +7,21 @@
//
//===----------------------------------------------------------------------===//
-
-#include "lldb/Target/OperatingSystem.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/OperatingSystem.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
-
OperatingSystem*
OperatingSystem::FindPlugin (Process *process, const char *plugin_name)
{
- OperatingSystemCreateInstance create_callback = NULL;
+ OperatingSystemCreateInstance create_callback = nullptr;
if (plugin_name)
{
ConstString const_plugin_name(plugin_name);
@@ -30,20 +29,20 @@ OperatingSystem::FindPlugin (Process *process, const char *plugin_name)
if (create_callback)
{
std::unique_ptr<OperatingSystem> instance_ap(create_callback(process, true));
- if (instance_ap.get())
+ if (instance_ap)
return instance_ap.release();
}
}
else
{
- for (uint32_t idx = 0; (create_callback = PluginManager::GetOperatingSystemCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (uint32_t idx = 0; (create_callback = PluginManager::GetOperatingSystemCreateCallbackAtIndex(idx)) != nullptr; ++idx)
{
std::unique_ptr<OperatingSystem> instance_ap(create_callback(process, false));
- if (instance_ap.get())
+ if (instance_ap)
return instance_ap.release();
}
}
- return NULL;
+ return nullptr;
}
@@ -52,10 +51,7 @@ OperatingSystem::OperatingSystem (Process *process) :
{
}
-OperatingSystem::~OperatingSystem()
-{
-}
-
+OperatingSystem::~OperatingSystem() = default;
bool
OperatingSystem::IsOperatingSystemPluginThread (const lldb::ThreadSP &thread_sp)
@@ -64,4 +60,3 @@ OperatingSystem::IsOperatingSystemPluginThread (const lldb::ThreadSP &thread_sp)
return thread_sp->IsOperatingSystemPluginThread();
return false;
}
-
diff --git a/source/Target/PathMappingList.cpp b/source/Target/PathMappingList.cpp
index 2fd517829b8c..2372c2f9dd95 100644
--- a/source/Target/PathMappingList.cpp
+++ b/source/Target/PathMappingList.cpp
@@ -8,10 +8,10 @@
//===----------------------------------------------------------------------===//
// C Includes
-#include <limits.h>
-#include <string.h>
-
// C++ Includes
+#include <climits>
+#include <cstring>
+
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Error.h"
@@ -26,10 +26,10 @@ using namespace lldb_private;
// PathMappingList constructor
//----------------------------------------------------------------------
PathMappingList::PathMappingList () :
- m_pairs (),
- m_callback (NULL),
- m_callback_baton (NULL),
- m_mod_id (0)
+ m_pairs(),
+ m_callback(nullptr),
+ m_callback_baton(nullptr),
+ m_mod_id(0)
{
}
@@ -42,14 +42,12 @@ PathMappingList::PathMappingList (ChangedCallback callback,
{
}
-
PathMappingList::PathMappingList (const PathMappingList &rhs) :
- m_pairs (rhs.m_pairs),
- m_callback (NULL),
- m_callback_baton (NULL),
- m_mod_id (0)
+ m_pairs(rhs.m_pairs),
+ m_callback(nullptr),
+ m_callback_baton(nullptr),
+ m_mod_id(0)
{
-
}
const PathMappingList &
@@ -58,20 +56,14 @@ PathMappingList::operator =(const PathMappingList &rhs)
if (this != &rhs)
{
m_pairs = rhs.m_pairs;
- m_callback = NULL;
- m_callback_baton = NULL;
+ m_callback = nullptr;
+ m_callback_baton = nullptr;
m_mod_id = rhs.m_mod_id;
}
return *this;
}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-PathMappingList::~PathMappingList ()
-{
-}
+PathMappingList::~PathMappingList() = default;
void
PathMappingList::Append (const ConstString &path,
@@ -204,7 +196,7 @@ PathMappingList::RemapPath (const ConstString &path, ConstString &new_path) cons
bool
PathMappingList::RemapPath (const char *path, std::string &new_path) const
{
- if (m_pairs.empty() || path == NULL || path[0] == '\0')
+ if (m_pairs.empty() || path == nullptr || path[0] == '\0')
return false;
const_iterator pos, end = m_pairs.end();
@@ -223,6 +215,27 @@ PathMappingList::RemapPath (const char *path, std::string &new_path) const
}
bool
+PathMappingList::ReverseRemapPath (const ConstString &path, ConstString &new_path) const
+{
+ const char *path_cstr = path.GetCString();
+ if (!path_cstr)
+ return false;
+
+ for (const auto& it : m_pairs)
+ {
+ const size_t prefixLen = it.second.GetLength();
+ if (::strncmp (it.second.GetCString(), path_cstr, prefixLen) == 0)
+ {
+ std::string new_path_str (it.first.GetCString());
+ new_path_str.append(path.GetCString() + prefixLen);
+ new_path.SetCString(new_path_str.c_str());
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
PathMappingList::FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const
{
if (!m_pairs.empty())
@@ -329,8 +342,6 @@ PathMappingList::GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &
return false;
}
-
-
uint32_t
PathMappingList::FindIndexForPath (const ConstString &path) const
{
@@ -345,4 +356,3 @@ PathMappingList::FindIndexForPath (const ConstString &path) const
}
return UINT32_MAX;
}
-
diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp
index 5077ca23bf74..f537f70452f4 100644
--- a/source/Target/Platform.cpp
+++ b/source/Target/Platform.cpp
@@ -7,18 +7,20 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Target/Platform.h"
-
// C Includes
-
// C++ Includes
#include <algorithm>
#include <fstream>
#include <vector>
// Other libraries and framework includes
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
// Project includes
+#include "lldb/Target/Platform.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
@@ -39,12 +41,8 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/Utils.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-
#include "Utility/ModuleCache.h"
-
// Define these constants from POSIX mman.h rather than include the file
// so that they will be correct even when compiled on Linux.
#define MAP_PRIVATE 2
@@ -164,10 +162,10 @@ GetPlatformList()
return g_platform_list;
}
-static Mutex &
-GetPlatformListMutex ()
+static std::recursive_mutex &
+GetPlatformListMutex()
{
- static Mutex g_mutex(Mutex::eMutexTypeRecursive);
+ static std::recursive_mutex g_mutex;
return g_mutex;
}
@@ -184,7 +182,7 @@ Platform::Terminate ()
{
if (--g_initialize_count == 0)
{
- Mutex::Locker locker(GetPlatformListMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
GetPlatformList().clear();
}
}
@@ -206,7 +204,7 @@ Platform::SetHostPlatform (const lldb::PlatformSP &platform_sp)
if (platform_sp)
{
- Mutex::Locker locker(GetPlatformListMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
GetPlatformList().push_back(platform_sp);
}
}
@@ -230,7 +228,7 @@ Platform::LocateExecutableScriptingResources (Target *target, Module &module, St
//PlatformSP
//Platform::FindPlugin (Process *process, const ConstString &plugin_name)
//{
-// PlatformCreateInstance create_callback = NULL;
+// PlatformCreateInstance create_callback = nullptr;
// if (plugin_name)
// {
// create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name);
@@ -248,7 +246,7 @@ Platform::LocateExecutableScriptingResources (Target *target, Module &module, St
// }
// else
// {
-// for (uint32_t idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != NULL; ++idx)
+// for (uint32_t idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != nullptr; ++idx)
// {
// PlatformSP platform_sp(create_callback(process, nullptr));
// if (platform_sp)
@@ -311,7 +309,7 @@ Platform::Find (const ConstString &name)
if (name == g_host_platform_name)
return GetHostPlatform();
- Mutex::Locker locker(GetPlatformListMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
for (const auto &platform_sp : GetPlatformList())
{
if (platform_sp->GetName() == name)
@@ -324,7 +322,7 @@ Platform::Find (const ConstString &name)
PlatformSP
Platform::Create (const ConstString &name, Error &error)
{
- PlatformCreateInstance create_callback = NULL;
+ PlatformCreateInstance create_callback = nullptr;
lldb::PlatformSP platform_sp;
if (name)
{
@@ -334,7 +332,7 @@ Platform::Create (const ConstString &name, Error &error)
create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (name);
if (create_callback)
- platform_sp = create_callback(true, NULL);
+ platform_sp = create_callback(true, nullptr);
else
error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", name.GetCString());
}
@@ -343,14 +341,13 @@ Platform::Create (const ConstString &name, Error &error)
if (platform_sp)
{
- Mutex::Locker locker(GetPlatformListMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
GetPlatformList().push_back(platform_sp);
}
return platform_sp;
}
-
PlatformSP
Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error)
{
@@ -360,7 +357,7 @@ Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &erro
// Scope for locker
{
// First try exact arch matches across all platforms already created
- Mutex::Locker locker(GetPlatformListMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
for (const auto &platform_sp : GetPlatformList())
{
if (platform_sp->IsCompatibleArchitecture(arch, true, platform_arch_ptr))
@@ -385,7 +382,7 @@ Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &erro
platform_sp = create_callback(false, &arch);
if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, true, platform_arch_ptr))
{
- Mutex::Locker locker(GetPlatformListMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
GetPlatformList().push_back(platform_sp);
return platform_sp;
}
@@ -399,7 +396,7 @@ Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &erro
platform_sp = create_callback(false, &arch);
if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, false, platform_arch_ptr))
{
- Mutex::Locker locker(GetPlatformListMutex ());
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
GetPlatformList().push_back(platform_sp);
return platform_sp;
}
@@ -417,37 +414,37 @@ Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &erro
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-Platform::Platform (bool is_host) :
- m_is_host (is_host),
- m_os_version_set_while_connected (false),
- m_system_arch_set_while_connected (false),
- m_sdk_sysroot (),
- m_sdk_build (),
- m_working_dir (),
- m_remote_url (),
- m_name (),
- m_major_os_version (UINT32_MAX),
- m_minor_os_version (UINT32_MAX),
- m_update_os_version (UINT32_MAX),
- m_system_arch(),
- m_mutex (Mutex::eMutexTypeRecursive),
- m_uid_map(),
- m_gid_map(),
- m_max_uid_name_len (0),
- m_max_gid_name_len (0),
- m_supports_rsync (false),
- m_rsync_opts (),
- m_rsync_prefix (),
- m_supports_ssh (false),
- m_ssh_opts (),
- m_ignores_remote_hostname (false),
- m_trap_handlers(),
- m_calculated_trap_handlers (false),
- m_module_cache (llvm::make_unique<ModuleCache> ())
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+Platform::Platform(bool is_host)
+ : m_is_host(is_host),
+ m_os_version_set_while_connected(false),
+ m_system_arch_set_while_connected(false),
+ m_sdk_sysroot(),
+ m_sdk_build(),
+ m_working_dir(),
+ m_remote_url(),
+ m_name(),
+ m_major_os_version(UINT32_MAX),
+ m_minor_os_version(UINT32_MAX),
+ m_update_os_version(UINT32_MAX),
+ m_system_arch(),
+ m_mutex(),
+ m_uid_map(),
+ m_gid_map(),
+ m_max_uid_name_len(0),
+ m_max_gid_name_len(0),
+ m_supports_rsync(false),
+ m_rsync_opts(),
+ m_rsync_prefix(),
+ m_supports_ssh(false),
+ m_ssh_opts(),
+ m_ignores_remote_hostname(false),
+ m_trap_handlers(),
+ m_calculated_trap_handlers(false),
+ m_module_cache(llvm::make_unique<ModuleCache>())
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
if (log)
- log->Printf ("%p Platform::Platform()", static_cast<void*>(this));
+ log->Printf("%p Platform::Platform()", static_cast<void *>(this));
}
//------------------------------------------------------------------
@@ -521,18 +518,17 @@ Platform::GetStatus (Stream &strm)
std::string specific_info(GetPlatformSpecificConnectionInformation());
- if (specific_info.empty() == false)
+ if (!specific_info.empty())
strm.Printf("Platform-specific connection: %s\n", specific_info.c_str());
}
-
bool
Platform::GetOSVersion (uint32_t &major,
uint32_t &minor,
uint32_t &update,
Process *process)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
bool success = m_major_os_version != UINT32_MAX;
if (IsHost())
@@ -631,7 +627,6 @@ Platform::AddClangModuleCompilationOptions (Target *target, std::vector<std::str
default_compilation_options.end());
}
-
FileSpec
Platform::GetWorkingDirectory ()
{
@@ -651,7 +646,6 @@ Platform::GetWorkingDirectory ()
}
}
-
struct RecurseCopyBaton
{
const FileSpec& dst;
@@ -659,7 +653,6 @@ struct RecurseCopyBaton
Error error;
};
-
static FileSpec::EnumerateDirectoryResult
RecurseCopy_Callback (void *baton,
FileSpec::FileType file_type,
@@ -728,6 +721,7 @@ RecurseCopy_Callback (void *baton,
return FileSpec::eEnumerateDirectoryResultNext;
}
break;
+
case FileSpec::eFileTypeRegular:
{
// copy the file and keep going
@@ -964,7 +958,7 @@ Platform::GetHostname ()
return "127.0.0.1";
if (m_name.empty())
- return NULL;
+ return nullptr;
return m_name.c_str();
}
@@ -999,7 +993,7 @@ Platform::GetUserName (uint32_t uid)
return SetCachedUserName (uid, name.c_str(), name.size());
}
#endif
- return NULL;
+ return nullptr;
}
const char *
@@ -1016,7 +1010,7 @@ Platform::GetGroupName (uint32_t gid)
return SetCachedGroupName (gid, name.c_str(), name.size());
}
#endif
- return NULL;
+ return nullptr;
}
bool
@@ -1052,7 +1046,6 @@ Platform::SetOSVersion (uint32_t major,
return false;
}
-
Error
Platform::ResolveExecutable (const ModuleSpec &module_spec,
lldb::ModuleSP &exe_module_sp,
@@ -1063,11 +1056,11 @@ Platform::ResolveExecutable (const ModuleSpec &module_spec,
{
if (module_spec.GetArchitecture().IsValid())
{
- error = ModuleList::GetSharedModule (module_spec,
- exe_module_sp,
- module_search_paths_ptr,
- NULL,
- NULL);
+ error = ModuleList::GetSharedModule(module_spec,
+ exe_module_sp,
+ module_search_paths_ptr,
+ nullptr,
+ nullptr);
}
else
{
@@ -1077,11 +1070,11 @@ Platform::ResolveExecutable (const ModuleSpec &module_spec,
ModuleSpec arch_module_spec(module_spec);
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, arch_module_spec.GetArchitecture()); ++idx)
{
- error = ModuleList::GetSharedModule (arch_module_spec,
- exe_module_sp,
- module_search_paths_ptr,
- NULL,
- NULL);
+ error = ModuleList::GetSharedModule(arch_module_spec,
+ exe_module_sp,
+ module_search_paths_ptr,
+ nullptr,
+ nullptr);
// Did we find an executable using one of the
if (error.Success() && exe_module_sp)
break;
@@ -1107,10 +1100,7 @@ Platform::ResolveSymbolFile (Target &target,
else
error.SetErrorString("unable to resolve symbol file");
return error;
-
-}
-
-
+}
bool
Platform::ResolveRemotePath (const FileSpec &platform_path,
@@ -1120,7 +1110,6 @@ Platform::ResolveRemotePath (const FileSpec &platform_path,
return resolved_platform_path.ResolvePath();
}
-
const ArchSpec &
Platform::GetSystemArchitecture()
{
@@ -1166,7 +1155,6 @@ Platform::GetSystemArchitecture()
return m_system_arch;
}
-
Error
Platform::ConnectRemote (Args& args)
{
@@ -1211,7 +1199,6 @@ Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info,
return match_count;
}
-
Error
Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
{
@@ -1254,7 +1241,11 @@ Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
{
error = ShellExpandArguments(launch_info);
if (error.Fail())
+ {
+ error.SetErrorStringWithFormat("shell expansion failed (reason: %s). consider launching with 'process launch'.",
+ error.AsCString("unknown"));
return error;
+ }
}
if (log)
@@ -1309,7 +1300,7 @@ Platform::KillProcess (const lldb::pid_t pid)
lldb::ProcessSP
Platform::DebugProcess (ProcessLaunchInfo &launch_info,
Debugger &debugger,
- Target *target, // Can be NULL, if NULL create a new target, else use existing one
+ Target *target, // Can be nullptr, if nullptr create a new target, else use existing one
Error &error)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
@@ -1376,7 +1367,6 @@ Platform::DebugProcess (ProcessLaunchInfo &launch_info,
return process_sp;
}
-
lldb::PlatformSP
Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr)
{
@@ -1387,7 +1377,6 @@ Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_a
return platform_sp;
}
-
//------------------------------------------------------------------
/// Lets a platform answer if it is compatible with a given
/// architecture and the target triple contained within.
@@ -1442,7 +1431,7 @@ Platform::PutFile (const FileSpec& source,
uint32_t source_open_options = File::eOpenOptionRead | File::eOpenOptionCloseOnExec;
if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink)
- source_open_options |= File::eOpenoptionDontFollowSymlinks;
+ source_open_options |= File::eOpenOptionDontFollowSymlinks;
File source_file(source, source_open_options, lldb::eFilePermissionsUserRW);
Error error;
@@ -1539,11 +1528,11 @@ Platform::ConvertMmapFlagsToPlatform(const ArchSpec &arch, unsigned flags)
}
lldb_private::Error
-Platform::RunShellCommand(const char *command, // Shouldn't be NULL
+Platform::RunShellCommand(const char *command, // Shouldn't be nullptr
const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
- int *status_ptr, // Pass NULL if you don't want the process exit status
- int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
- std::string *command_output, // Pass NULL if you don't want the command output
+ int *status_ptr, // Pass nullptr if you don't want the process exit status
+ int *signo_ptr, // Pass nullptr if you don't want the signal that caused the process to exit
+ std::string *command_output, // Pass nullptr if you don't want the command output
uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
{
if (IsHost())
@@ -1552,7 +1541,6 @@ Platform::RunShellCommand(const char *command, // Shouldn't be NULL
return Error("unimplemented");
}
-
bool
Platform::CalculateMD5 (const FileSpec& file_spec,
uint64_t &low,
@@ -1579,33 +1567,25 @@ Platform::GetLocalCacheDirectory ()
static OptionDefinition
g_rsync_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "rsync" , 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Enable rsync." },
- { LLDB_OPT_SET_ALL, false, "rsync-opts" , 'R', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName , "Platform-specific options required for rsync to work." },
- { LLDB_OPT_SET_ALL, false, "rsync-prefix" , 'P', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName , "Platform-specific rsync prefix put before the remote path." },
- { LLDB_OPT_SET_ALL, false, "ignore-remote-hostname" , 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Do not automatically fill in the remote hostname when composing the rsync command." },
+ { LLDB_OPT_SET_ALL, false, "rsync" , 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Enable rsync." },
+ { LLDB_OPT_SET_ALL, false, "rsync-opts" , 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommandName , "Platform-specific options required for rsync to work." },
+ { LLDB_OPT_SET_ALL, false, "rsync-prefix" , 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommandName , "Platform-specific rsync prefix put before the remote path." },
+ { LLDB_OPT_SET_ALL, false, "ignore-remote-hostname" , 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Do not automatically fill in the remote hostname when composing the rsync command." },
};
static OptionDefinition
g_ssh_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "ssh" , 's', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Enable SSH." },
- { LLDB_OPT_SET_ALL, false, "ssh-opts" , 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName , "Platform-specific options required for SSH to work." },
+ { LLDB_OPT_SET_ALL, false, "ssh" , 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Enable SSH." },
+ { LLDB_OPT_SET_ALL, false, "ssh-opts" , 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommandName , "Platform-specific options required for SSH to work." },
};
static OptionDefinition
g_caching_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "local-cache-dir" , 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePath , "Path in which to store local copies of files." },
+ { LLDB_OPT_SET_ALL, false, "local-cache-dir" , 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePath , "Path in which to store local copies of files." },
};
-OptionGroupPlatformRSync::OptionGroupPlatformRSync ()
-{
-}
-
-OptionGroupPlatformRSync::~OptionGroupPlatformRSync ()
-{
-}
-
const lldb_private::OptionDefinition*
OptionGroupPlatformRSync::GetDefinitions ()
{
@@ -1666,14 +1646,6 @@ Platform::SetThreadCreationBreakpoint (lldb_private::Target &target)
return lldb::BreakpointSP();
}
-OptionGroupPlatformSSH::OptionGroupPlatformSSH ()
-{
-}
-
-OptionGroupPlatformSSH::~OptionGroupPlatformSSH ()
-{
-}
-
const lldb_private::OptionDefinition*
OptionGroupPlatformSSH::GetDefinitions ()
{
@@ -1718,14 +1690,6 @@ OptionGroupPlatformSSH::GetNumDefinitions ()
return llvm::array_lengthof(g_ssh_option_table);
}
-OptionGroupPlatformCaching::OptionGroupPlatformCaching ()
-{
-}
-
-OptionGroupPlatformCaching::~OptionGroupPlatformCaching ()
-{
-}
-
const lldb_private::OptionDefinition*
OptionGroupPlatformCaching::GetDefinitions ()
{
@@ -1777,7 +1741,7 @@ Platform::GetTrapHandlerSymbolNames ()
{
if (!m_calculated_trap_handlers)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
if (!m_calculated_trap_handlers)
{
CalculateTrapHandlerSymbolNames();
@@ -1838,14 +1802,30 @@ Platform::GetRemoteSharedModule (const ModuleSpec &module_spec,
{
// Try to get module information from the process
if (process->GetModuleSpec (module_spec.GetFileSpec (), module_spec.GetArchitecture (), resolved_module_spec))
- got_module_spec = true;
+ {
+ if (module_spec.GetUUID().IsValid() == false || module_spec.GetUUID() == resolved_module_spec.GetUUID())
+ {
+ got_module_spec = true;
+ }
+ }
}
if (!got_module_spec)
{
// Get module information from a target.
if (!GetModuleSpec (module_spec.GetFileSpec (), module_spec.GetArchitecture (), resolved_module_spec))
- return module_resolver (module_spec);
+ {
+ if (module_spec.GetUUID().IsValid() == false || module_spec.GetUUID() == resolved_module_spec.GetUUID())
+ {
+ return module_resolver (module_spec);
+ }
+ }
+ }
+
+ // If we are looking for a specific UUID, make sure resolved_module_spec has the same one before we search.
+ if (module_spec.GetUUID().IsValid())
+ {
+ resolved_module_spec.GetUUID() = module_spec.GetUUID();
}
// Trying to find a module by UUID on local file system.
@@ -2087,3 +2067,115 @@ Platform::ConnectToWaitingProcesses(lldb_private::Debugger& debugger, lldb_priva
error.Clear();
return 0;
}
+
+size_t
+Platform::GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site)
+{
+ ArchSpec arch = target.GetArchitecture();
+ const uint8_t *trap_opcode = nullptr;
+ size_t trap_opcode_size = 0;
+
+ switch (arch.GetMachine())
+ {
+ case llvm::Triple::aarch64:
+ {
+ static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};
+ trap_opcode = g_aarch64_opcode;
+ trap_opcode_size = sizeof(g_aarch64_opcode);
+ }
+ break;
+
+ // TODO: support big-endian arm and thumb trap codes.
+ case llvm::Triple::arm:
+ {
+ // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
+ // but the linux kernel does otherwise.
+ static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
+ static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
+
+ lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
+ AddressClass addr_class = eAddressClassUnknown;
+
+ if (bp_loc_sp)
+ {
+ addr_class = bp_loc_sp->GetAddress().GetAddressClass();
+ if (addr_class == eAddressClassUnknown && (bp_loc_sp->GetAddress().GetFileAddress() & 1))
+ addr_class = eAddressClassCodeAlternateISA;
+ }
+
+ if (addr_class == eAddressClassCodeAlternateISA)
+ {
+ trap_opcode = g_thumb_breakpoint_opcode;
+ trap_opcode_size = sizeof(g_thumb_breakpoint_opcode);
+ }
+ else
+ {
+ trap_opcode = g_arm_breakpoint_opcode;
+ trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
+ }
+ }
+ break;
+
+ case llvm::Triple::mips:
+ case llvm::Triple::mips64:
+ {
+ static const uint8_t g_hex_opcode[] = {0x00, 0x00, 0x00, 0x0d};
+ trap_opcode = g_hex_opcode;
+ trap_opcode_size = sizeof(g_hex_opcode);
+ }
+ break;
+
+ case llvm::Triple::mipsel:
+ case llvm::Triple::mips64el:
+ {
+ static const uint8_t g_hex_opcode[] = {0x0d, 0x00, 0x00, 0x00};
+ trap_opcode = g_hex_opcode;
+ trap_opcode_size = sizeof(g_hex_opcode);
+ }
+ break;
+
+ case llvm::Triple::systemz:
+ {
+ static const uint8_t g_hex_opcode[] = {0x00, 0x01};
+ trap_opcode = g_hex_opcode;
+ trap_opcode_size = sizeof(g_hex_opcode);
+ }
+ break;
+
+ case llvm::Triple::hexagon:
+ {
+ static const uint8_t g_hex_opcode[] = {0x0c, 0xdb, 0x00, 0x54};
+ trap_opcode = g_hex_opcode;
+ trap_opcode_size = sizeof(g_hex_opcode);
+ }
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ {
+ static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08};
+ trap_opcode = g_ppc_opcode;
+ trap_opcode_size = sizeof(g_ppc_opcode);
+ }
+ break;
+
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ {
+ static const uint8_t g_i386_opcode[] = {0xCC};
+ trap_opcode = g_i386_opcode;
+ trap_opcode_size = sizeof(g_i386_opcode);
+ }
+ break;
+
+ default:
+ assert(!"Unhandled architecture in Platform::GetSoftwareBreakpointTrapOpcode");
+ break;
+ }
+
+ assert(bp_site);
+ if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
+ return trap_opcode_size;
+
+ return 0;
+}
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index e4fe419660e2..3d1065450e81 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -9,21 +9,25 @@
// C Includes
// C++ Includes
+#include <atomic>
+#include <mutex>
+
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/Process.h"
-#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Event.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Event.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
-#include "lldb/Expression/UserExpression.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/IRDynamicChecks.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
@@ -36,17 +40,18 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/InstrumentationRuntime.h"
#include "lldb/Target/JITLoader.h"
#include "lldb/Target/JITLoaderList.h"
+#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/MemoryHistory.h"
#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/OperatingSystem.h"
-#include "lldb/Target/LanguageRuntime.h"
-#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/OperatingSystem.h"
#include "lldb/Target/Platform.h"
+#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/SystemRuntime.h"
@@ -57,7 +62,6 @@
#include "lldb/Target/ThreadPlanBase.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/NameMatches.h"
-#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
using namespace lldb;
using namespace lldb_private;
@@ -111,17 +115,17 @@ public:
static PropertyDefinition
g_properties[] =
{
- { "disable-memory-cache" , OptionValue::eTypeBoolean, false, DISABLE_MEM_CACHE_DEFAULT, NULL, NULL, "Disable reading and caching of memory in fixed-size units." },
- { "extra-startup-command", OptionValue::eTypeArray , false, OptionValue::eTypeString, NULL, NULL, "A list containing extra commands understood by the particular process plugin used. "
+ { "disable-memory-cache" , OptionValue::eTypeBoolean, false, DISABLE_MEM_CACHE_DEFAULT, nullptr, nullptr, "Disable reading and caching of memory in fixed-size units." },
+ { "extra-startup-command", OptionValue::eTypeArray , false, OptionValue::eTypeString, nullptr, nullptr, "A list containing extra commands understood by the particular process plugin used. "
"For instance, to turn on debugserver logging set this to \"QSetLogging:bitmask=LOG_DEFAULT;\"" },
- { "ignore-breakpoints-in-expressions", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, breakpoints will be ignored during expression evaluation." },
- { "unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, errors in expression evaluation will unwind the stack back to the state before the call." },
- { "python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, NULL, NULL, "A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class." },
- { "stop-on-sharedlibrary-events" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, stop when a shared library is loaded or unloaded." },
- { "detach-keeps-stopped" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, detach will attempt to keep the process stopped." },
- { "memory-cache-line-size" , OptionValue::eTypeUInt64, false, 512, NULL, NULL, "The memory cache line size" },
- { "optimization-warnings" , OptionValue::eTypeBoolean, false, true, NULL, NULL, "If true, warn when stopped in code that is optimized where stepping and variable availability may not behave as expected." },
- { NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL }
+ { "ignore-breakpoints-in-expressions", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, breakpoints will be ignored during expression evaluation." },
+ { "unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, errors in expression evaluation will unwind the stack back to the state before the call." },
+ { "python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, nullptr, nullptr, "A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class." },
+ { "stop-on-sharedlibrary-events" , OptionValue::eTypeBoolean, true, false, nullptr, nullptr, "If true, stop when a shared library is loaded or unloaded." },
+ { "detach-keeps-stopped" , OptionValue::eTypeBoolean, true, false, nullptr, nullptr, "If true, detach will attempt to keep the process stopped." },
+ { "memory-cache-line-size" , OptionValue::eTypeUInt64, false, 512, nullptr, nullptr, "The memory cache line size" },
+ { "optimization-warnings" , OptionValue::eTypeBoolean, false, true, nullptr, nullptr, "If true, warn when stopped in code that is optimized where stepping and variable availability may not behave as expected." },
+ { nullptr , OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr }
};
enum {
@@ -137,10 +141,10 @@ enum {
};
ProcessProperties::ProcessProperties (lldb_private::Process *process) :
- Properties (),
- m_process (process) // Can be NULL for global ProcessProperties
+ Properties(),
+ m_process(process) // Can be nullptr for global ProcessProperties
{
- if (process == NULL)
+ if (process == nullptr)
{
// Global process properties, set them up one time
m_collection_sp.reset (new ProcessOptionValueProperties(ConstString("process")));
@@ -171,14 +175,14 @@ bool
ProcessProperties::GetDisableMemoryCache() const
{
const uint32_t idx = ePropertyDisableMemCache;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
uint64_t
ProcessProperties::GetMemoryCacheLineSize() const
{
const uint32_t idx = ePropertyMemCacheLineSize;
- return m_collection_sp->GetPropertyAtIndexAsUInt64 (NULL, idx, g_properties[idx].default_uint_value);
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(nullptr, idx, g_properties[idx].default_uint_value);
}
Args
@@ -186,7 +190,7 @@ ProcessProperties::GetExtraStartupCommands () const
{
Args args;
const uint32_t idx = ePropertyExtraStartCommand;
- m_collection_sp->GetPropertyAtIndexAsArgs(NULL, idx, args);
+ m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args);
return args;
}
@@ -194,84 +198,84 @@ void
ProcessProperties::SetExtraStartupCommands (const Args &args)
{
const uint32_t idx = ePropertyExtraStartCommand;
- m_collection_sp->SetPropertyAtIndexFromArgs(NULL, idx, args);
+ m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args);
}
FileSpec
ProcessProperties::GetPythonOSPluginPath () const
{
const uint32_t idx = ePropertyPythonOSPluginPath;
- return m_collection_sp->GetPropertyAtIndexAsFileSpec(NULL, idx);
+ return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
}
void
ProcessProperties::SetPythonOSPluginPath (const FileSpec &file)
{
const uint32_t idx = ePropertyPythonOSPluginPath;
- m_collection_sp->SetPropertyAtIndexAsFileSpec(NULL, idx, file);
+ m_collection_sp->SetPropertyAtIndexAsFileSpec(nullptr, idx, file);
}
bool
ProcessProperties::GetIgnoreBreakpointsInExpressions () const
{
const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
void
ProcessProperties::SetIgnoreBreakpointsInExpressions (bool ignore)
{
const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions;
- m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, ignore);
+ m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, ignore);
}
bool
ProcessProperties::GetUnwindOnErrorInExpressions () const
{
const uint32_t idx = ePropertyUnwindOnErrorInExpressions;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
void
ProcessProperties::SetUnwindOnErrorInExpressions (bool ignore)
{
const uint32_t idx = ePropertyUnwindOnErrorInExpressions;
- m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, ignore);
+ m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, ignore);
}
bool
ProcessProperties::GetStopOnSharedLibraryEvents () const
{
const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
void
ProcessProperties::SetStopOnSharedLibraryEvents (bool stop)
{
const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
- m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, stop);
+ m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, stop);
}
bool
ProcessProperties::GetDetachKeepsStopped () const
{
const uint32_t idx = ePropertyDetachKeepsStopped;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
void
ProcessProperties::SetDetachKeepsStopped (bool stop)
{
const uint32_t idx = ePropertyDetachKeepsStopped;
- m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, stop);
+ m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, stop);
}
bool
ProcessProperties::GetWarningsOptimization () const
{
const uint32_t idx = ePropertyWarningOptimization;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
}
void
@@ -294,7 +298,7 @@ ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const
const uint32_t argc = m_arguments.GetArgumentCount();
if (argc > 0)
{
- for (uint32_t i=0; i<argc; i++)
+ for (uint32_t i = 0; i < argc; i++)
{
const char *arg = m_arguments.GetArgumentAtIndex(i);
if (i < 10)
@@ -307,7 +311,7 @@ ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const
const uint32_t envc = m_environment.GetArgumentCount();
if (envc > 0)
{
- for (uint32_t i=0; i<envc; i++)
+ for (uint32_t i = 0; i < envc; i++)
{
const char *env = m_environment.GetArgumentAtIndex(i);
if (i < 10)
@@ -419,7 +423,7 @@ ProcessInstanceInfo::DumpAsTableRow (Stream &s, Platform *platform, bool show_ar
const uint32_t argc = m_arguments.GetArgumentCount();
if (argc > 0)
{
- for (uint32_t i=0; i<argc; i++)
+ for (uint32_t i = 0; i < argc; i++)
{
if (i > 0)
s.PutChar (' ');
@@ -545,29 +549,29 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
OptionDefinition
ProcessLaunchCommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."},
-{ LLDB_OPT_SET_ALL, false, "disable-aslr", 'A', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Set whether to disable address space layout randomization when launching a process."},
-{ LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
-{ LLDB_OPT_SET_ALL, false, "working-dir", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."},
-{ LLDB_OPT_SET_ALL, false, "arch", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeArchitecture, "Set the architecture for the process to launch when ambiguous."},
-{ LLDB_OPT_SET_ALL, false, "environment", 'v', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "Specify an environment variable name/value string (--environment NAME=VALUE). Can be specified multiple times for subsequent environment entries."},
-{ LLDB_OPT_SET_1|LLDB_OPT_SET_2|LLDB_OPT_SET_3, false, "shell", 'c', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeFilename, "Run the process in a shell (not supported on all platforms)."},
+{ LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process." },
+{ LLDB_OPT_SET_ALL, false, "disable-aslr", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set whether to disable address space layout randomization when launching a process." },
+{ LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use." },
+{ LLDB_OPT_SET_ALL, false, "working-dir", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior." },
+{ LLDB_OPT_SET_ALL, false, "arch", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeArchitecture, "Set the architecture for the process to launch when ambiguous." },
+{ LLDB_OPT_SET_ALL, false, "environment", 'v', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "Specify an environment variable name/value string (--environment NAME=VALUE). Can be specified multiple times for subsequent environment entries." },
+{ LLDB_OPT_SET_1|LLDB_OPT_SET_2|LLDB_OPT_SET_3, false, "shell", 'c', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeFilename, "Run the process in a shell (not supported on all platforms)." },
-{ LLDB_OPT_SET_1 , false, "stdin", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stdin for the process to <filename>."},
-{ LLDB_OPT_SET_1 , false, "stdout", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stdout for the process to <filename>."},
-{ LLDB_OPT_SET_1 , false, "stderr", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stderr for the process to <filename>."},
+{ LLDB_OPT_SET_1 , false, "stdin", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Redirect stdin for the process to <filename>." },
+{ LLDB_OPT_SET_1 , false, "stdout", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Redirect stdout for the process to <filename>." },
+{ LLDB_OPT_SET_1 , false, "stderr", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Redirect stderr for the process to <filename>." },
-{ LLDB_OPT_SET_2 , false, "tty", 't', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Start the process in a terminal (not supported on all platforms)."},
+{ LLDB_OPT_SET_2 , false, "tty", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Start the process in a terminal (not supported on all platforms)." },
-{ LLDB_OPT_SET_3 , false, "no-stdio", 'n', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."},
-{ LLDB_OPT_SET_4, false, "shell-expand-args", 'X', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Set whether to shell expand arguments to the process when launching."},
-{ 0 , false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_3 , false, "no-stdio", 'n', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process." },
+{ LLDB_OPT_SET_4, false, "shell-expand-args", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set whether to shell expand arguments to the process when launching." },
+{ 0 , false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
bool
ProcessInstanceInfoMatch::NameMatches (const char *process_name) const
{
- if (m_name_match_type == eNameMatchIgnore || process_name == NULL)
+ if (m_name_match_type == eNameMatchIgnore || process_name == nullptr)
return true;
const char *match_name = m_match_info.GetName();
if (!match_name)
@@ -654,19 +658,19 @@ ProcessInstanceInfoMatch::Clear()
}
ProcessSP
-Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener &listener, const FileSpec *crash_file_path)
+Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, ListenerSP listener_sp, const FileSpec *crash_file_path)
{
static uint32_t g_process_unique_id = 0;
ProcessSP process_sp;
- ProcessCreateInstance create_callback = NULL;
+ ProcessCreateInstance create_callback = nullptr;
if (plugin_name)
{
ConstString const_plugin_name(plugin_name);
create_callback = PluginManager::GetProcessCreateCallbackForPluginName (const_plugin_name);
if (create_callback)
{
- process_sp = create_callback(target_sp, listener, crash_file_path);
+ process_sp = create_callback(target_sp, listener_sp, crash_file_path);
if (process_sp)
{
if (process_sp->CanDebug(target_sp, true))
@@ -680,9 +684,9 @@ Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener
}
else
{
- for (uint32_t idx = 0; (create_callback = PluginManager::GetProcessCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (uint32_t idx = 0; (create_callback = PluginManager::GetProcessCreateCallbackAtIndex(idx)) != nullptr; ++idx)
{
- process_sp = create_callback(target_sp, listener, crash_file_path);
+ process_sp = create_callback(target_sp, listener_sp, crash_file_path);
if (process_sp)
{
if (process_sp->CanDebug(target_sp, false))
@@ -705,113 +709,107 @@ Process::GetStaticBroadcasterClass ()
return class_name;
}
-Process::Process(lldb::TargetSP target_sp, Listener &listener) :
- Process(target_sp, listener, UnixSignals::Create(HostInfo::GetArchitecture()))
+Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp) :
+ Process(target_sp, listener_sp, UnixSignals::Create(HostInfo::GetArchitecture()))
{
// This constructor just delegates to the full Process constructor,
// defaulting to using the Host's UnixSignals.
}
-Process::Process(lldb::TargetSP target_sp, Listener &listener, const UnixSignalsSP &unix_signals_sp) :
- ProcessProperties (this),
- UserID (LLDB_INVALID_PROCESS_ID),
- Broadcaster (&(target_sp->GetDebugger()), Process::GetStaticBroadcasterClass().AsCString()),
- m_target_sp (target_sp),
- m_public_state (eStateUnloaded),
- m_private_state (eStateUnloaded),
- m_private_state_broadcaster (NULL, "lldb.process.internal_state_broadcaster"),
- m_private_state_control_broadcaster (NULL, "lldb.process.internal_state_control_broadcaster"),
- m_private_state_listener ("lldb.process.internal_state_listener"),
- m_private_state_control_wait(),
- m_mod_id (),
- m_process_unique_id(0),
- m_thread_index_id (0),
- m_thread_id_to_index_id_map (),
- m_exit_status (-1),
- m_exit_string (),
- m_exit_status_mutex(),
- m_thread_mutex (Mutex::eMutexTypeRecursive),
- m_thread_list_real (this),
- m_thread_list (this),
- m_extended_thread_list (this),
- m_extended_thread_stop_id (0),
- m_queue_list (this),
- m_queue_list_stop_id (0),
- m_notifications (),
- m_image_tokens (),
- m_listener (listener),
- m_breakpoint_site_list (),
- m_dynamic_checkers_ap (),
- m_unix_signals_sp (unix_signals_sp),
- m_abi_sp (),
- m_process_input_reader (),
- m_stdio_communication ("process.stdio"),
- m_stdio_communication_mutex (Mutex::eMutexTypeRecursive),
- m_stdin_forward (false),
- m_stdout_data (),
- m_stderr_data (),
- m_profile_data_comm_mutex (Mutex::eMutexTypeRecursive),
- m_profile_data (),
- m_iohandler_sync (0),
- m_memory_cache (*this),
- m_allocated_memory_cache (*this),
- m_should_detach (false),
- m_next_event_action_ap(),
- m_public_run_lock (),
- m_private_run_lock (),
- m_stop_info_override_callback (NULL),
- m_finalizing (false),
- m_finalize_called (false),
- m_clear_thread_plans_on_stop (false),
- m_force_next_event_delivery (false),
- m_last_broadcast_state (eStateInvalid),
- m_destroy_in_process (false),
- m_can_interpret_function_calls(false),
- m_warnings_issued (),
- m_can_jit(eCanJITDontKnow)
-{
- CheckInWithManager ();
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, const UnixSignalsSP &unix_signals_sp)
+ : ProcessProperties(this),
+ UserID(LLDB_INVALID_PROCESS_ID),
+ Broadcaster((target_sp->GetDebugger().GetBroadcasterManager()), Process::GetStaticBroadcasterClass().AsCString()),
+ m_target_sp(target_sp),
+ m_public_state(eStateUnloaded),
+ m_private_state(eStateUnloaded),
+ m_private_state_broadcaster(nullptr, "lldb.process.internal_state_broadcaster"),
+ m_private_state_control_broadcaster(nullptr, "lldb.process.internal_state_control_broadcaster"),
+ m_private_state_listener_sp(Listener::MakeListener("lldb.process.internal_state_listener")),
+ m_mod_id(),
+ m_process_unique_id(0),
+ m_thread_index_id(0),
+ m_thread_id_to_index_id_map(),
+ m_exit_status(-1),
+ m_exit_string(),
+ m_exit_status_mutex(),
+ m_thread_mutex(),
+ m_thread_list_real(this),
+ m_thread_list(this),
+ m_extended_thread_list(this),
+ m_extended_thread_stop_id(0),
+ m_queue_list(this),
+ m_queue_list_stop_id(0),
+ m_notifications(),
+ m_image_tokens(),
+ m_listener_sp(listener_sp),
+ m_breakpoint_site_list(),
+ m_dynamic_checkers_ap(),
+ m_unix_signals_sp(unix_signals_sp),
+ m_abi_sp(),
+ m_process_input_reader(),
+ m_stdio_communication("process.stdio"),
+ m_stdio_communication_mutex(),
+ m_stdin_forward(false),
+ m_stdout_data(),
+ m_stderr_data(),
+ m_profile_data_comm_mutex(),
+ m_profile_data(),
+ m_iohandler_sync(0),
+ m_memory_cache(*this),
+ m_allocated_memory_cache(*this),
+ m_should_detach(false),
+ m_next_event_action_ap(),
+ m_public_run_lock(),
+ m_private_run_lock(),
+ m_stop_info_override_callback(nullptr),
+ m_finalizing(false),
+ m_finalize_called(false),
+ m_clear_thread_plans_on_stop(false),
+ m_force_next_event_delivery(false),
+ m_last_broadcast_state(eStateInvalid),
+ m_destroy_in_process(false),
+ m_can_interpret_function_calls(false),
+ m_warnings_issued(),
+ m_run_thread_plan_lock(),
+ m_can_jit(eCanJITDontKnow)
+{
+ CheckInWithManager();
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
if (log)
- log->Printf ("%p Process::Process()", static_cast<void*>(this));
+ log->Printf("%p Process::Process()", static_cast<void *>(this));
if (!m_unix_signals_sp)
m_unix_signals_sp = std::make_shared<UnixSignals>();
- SetEventName (eBroadcastBitStateChanged, "state-changed");
- SetEventName (eBroadcastBitInterrupt, "interrupt");
- SetEventName (eBroadcastBitSTDOUT, "stdout-available");
- SetEventName (eBroadcastBitSTDERR, "stderr-available");
- SetEventName (eBroadcastBitProfileData, "profile-data-available");
-
- m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlStop , "control-stop" );
- m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlPause , "control-pause" );
- m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlResume, "control-resume");
-
- listener.StartListeningForEvents (this,
- eBroadcastBitStateChanged |
- eBroadcastBitInterrupt |
- eBroadcastBitSTDOUT |
- eBroadcastBitSTDERR |
- eBroadcastBitProfileData);
-
- m_private_state_listener.StartListeningForEvents(&m_private_state_broadcaster,
- eBroadcastBitStateChanged |
- eBroadcastBitInterrupt);
-
- m_private_state_listener.StartListeningForEvents(&m_private_state_control_broadcaster,
- eBroadcastInternalStateControlStop |
- eBroadcastInternalStateControlPause |
- eBroadcastInternalStateControlResume);
+ SetEventName(eBroadcastBitStateChanged, "state-changed");
+ SetEventName(eBroadcastBitInterrupt, "interrupt");
+ SetEventName(eBroadcastBitSTDOUT, "stdout-available");
+ SetEventName(eBroadcastBitSTDERR, "stderr-available");
+ SetEventName(eBroadcastBitProfileData, "profile-data-available");
+
+ m_private_state_control_broadcaster.SetEventName(eBroadcastInternalStateControlStop, "control-stop");
+ m_private_state_control_broadcaster.SetEventName(eBroadcastInternalStateControlPause, "control-pause");
+ m_private_state_control_broadcaster.SetEventName(eBroadcastInternalStateControlResume, "control-resume");
+
+ m_listener_sp->StartListeningForEvents(this, eBroadcastBitStateChanged | eBroadcastBitInterrupt |
+ eBroadcastBitSTDOUT | eBroadcastBitSTDERR |
+ eBroadcastBitProfileData);
+
+ m_private_state_listener_sp->StartListeningForEvents(&m_private_state_broadcaster,
+ eBroadcastBitStateChanged | eBroadcastBitInterrupt);
+
+ m_private_state_listener_sp->StartListeningForEvents(
+ &m_private_state_control_broadcaster, eBroadcastInternalStateControlStop | eBroadcastInternalStateControlPause |
+ eBroadcastInternalStateControlResume);
// We need something valid here, even if just the default UnixSignalsSP.
- assert (m_unix_signals_sp && "null m_unix_signals_sp after initialization");
+ assert(m_unix_signals_sp && "null m_unix_signals_sp after initialization");
// Allow the platform to override the default cache line size
- OptionValueSP value_sp =
- m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyMemCacheLineSize)->GetValue();
+ OptionValueSP value_sp = m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyMemCacheLineSize)->GetValue();
uint32_t platform_cache_line_size = target_sp->GetPlatform()->GetDefaultMemoryCacheLineSize();
- if (! value_sp->OptionWasSet() && platform_cache_line_size != 0)
+ if (!value_sp->OptionWasSet() && platform_cache_line_size != 0)
value_sp->SetUInt64Value(platform_cache_line_size);
}
@@ -831,10 +829,14 @@ Process::~Process()
const ProcessPropertiesSP &
Process::GetGlobalProperties()
{
- static ProcessPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset (new ProcessProperties (NULL));
- return g_settings_sp;
+ // NOTE: intentional leak so we don't crash if global destructor chain gets
+ // called as other threads still use the result of this function
+ static ProcessPropertiesSP *g_settings_sp_ptr = nullptr;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ g_settings_sp_ptr = new ProcessPropertiesSP(new ProcessProperties(nullptr));
+ });
+ return *g_settings_sp_ptr;
}
void
@@ -890,14 +892,14 @@ Process::Finalize()
m_language_runtimes.clear();
m_instrumentation_runtimes.clear();
m_next_event_action_ap.reset();
- m_stop_info_override_callback = NULL;
+ m_stop_info_override_callback = nullptr;
// Clear the last natural stop ID since it has a strong
// reference to this process
m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
//#ifdef LLDB_CONFIGURATION_DEBUG
// StreamFile s(stdout, false);
// EventSP event_sp;
-// while (m_private_state_listener.GetNextEvent(event_sp))
+// while (m_private_state_listener_sp->GetNextEvent(event_sp))
// {
// event_sp->Dump (&s);
// s.EOL();
@@ -906,7 +908,7 @@ Process::Finalize()
// We have to be very careful here as the m_private_state_listener might
// contain events that have ProcessSP values in them which can keep this
// process around forever. These events need to be cleared out.
- m_private_state_listener.Clear();
+ m_private_state_listener_sp->Clear();
m_public_run_lock.TrySetRunning(); // This will do nothing if already locked
m_public_run_lock.SetStopped();
m_private_run_lock.TrySetRunning(); // This will do nothing if already locked
@@ -918,7 +920,7 @@ void
Process::RegisterNotificationCallbacks (const Notifications& callbacks)
{
m_notifications.push_back(callbacks);
- if (callbacks.initialize != NULL)
+ if (callbacks.initialize != nullptr)
callbacks.initialize (callbacks.baton, this);
}
@@ -963,7 +965,7 @@ Process::GetNextEvent (EventSP &event_sp)
{
StateType state = eStateInvalid;
- if (m_listener.GetNextEventForBroadcaster (this, event_sp) && event_sp)
+ if (m_listener_sp->GetNextEventForBroadcaster (this, event_sp) && event_sp)
state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
return state;
@@ -973,7 +975,7 @@ void
Process::SyncIOHandler (uint32_t iohandler_id, uint64_t timeout_msec)
{
// don't sync (potentially context switch) in case where there is no process IO
- if (! m_process_input_reader)
+ if (!m_process_input_reader)
return;
TimeValue timeout = TimeValue::Now();
@@ -990,7 +992,7 @@ StateType
Process::WaitForProcessToStop (const TimeValue *timeout,
EventSP *event_sp_ptr,
bool wait_always,
- Listener *hijack_listener,
+ ListenerSP hijack_listener_sp,
Stream *stream,
bool use_run_lock)
{
@@ -1019,7 +1021,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
__FUNCTION__);
// We need to toggle the run lock as this won't get done in
// SetPublicState() if the process is hijacked.
- if (hijack_listener && use_run_lock)
+ if (hijack_listener_sp && use_run_lock)
m_public_run_lock.SetStopped();
return state;
}
@@ -1027,11 +1029,11 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
while (state != eStateInvalid)
{
EventSP event_sp;
- state = WaitForStateChangedEvents (timeout, event_sp, hijack_listener);
+ state = WaitForStateChangedEvents (timeout, event_sp, hijack_listener_sp);
if (event_sp_ptr && event_sp)
*event_sp_ptr = event_sp;
- bool pop_process_io_handler = hijack_listener != NULL;
+ bool pop_process_io_handler = (hijack_listener_sp.get() != nullptr);
Process::HandleProcessStateChangedEvent (event_sp, stream, pop_process_io_handler);
switch (state)
@@ -1042,7 +1044,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
case eStateUnloaded:
// We need to toggle the run lock as this won't get done in
// SetPublicState() if the process is hijacked.
- if (hijack_listener && use_run_lock)
+ if (hijack_listener_sp && use_run_lock)
m_public_run_lock.SetStopped();
return state;
case eStateStopped:
@@ -1052,7 +1054,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
{
// We need to toggle the run lock as this won't get done in
// SetPublicState() if the process is hijacked.
- if (hijack_listener && use_run_lock)
+ if (hijack_listener_sp && use_run_lock)
m_public_run_lock.SetStopped();
return state;
}
@@ -1068,7 +1070,7 @@ Process::HandleProcessStateChangedEvent (const EventSP &event_sp,
Stream *stream,
bool &pop_process_io_handler)
{
- const bool handle_pop = pop_process_io_handler == true;
+ const bool handle_pop = pop_process_io_handler;
pop_process_io_handler = false;
ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
@@ -1088,15 +1090,12 @@ Process::HandleProcessStateChangedEvent (const EventSP &event_sp,
case eStateLaunching:
case eStateStepping:
case eStateDetached:
- {
- if (stream)
- stream->Printf ("Process %" PRIu64 " %s\n",
- process_sp->GetID(),
- StateAsCString (event_state));
-
- if (event_state == eStateDetached)
- pop_process_io_handler = true;
- }
+ if (stream)
+ stream->Printf("Process %" PRIu64 " %s\n",
+ process_sp->GetID(),
+ StateAsCString (event_state));
+ if (event_state == eStateDetached)
+ pop_process_io_handler = true;
break;
case eStateConnected:
@@ -1149,7 +1148,7 @@ Process::HandleProcessStateChangedEvent (const EventSP &event_sp,
// Lock the thread list so it doesn't change on us, this is the scope for the locker:
{
ThreadList &thread_list = process_sp->GetThreadList();
- Mutex::Locker locker (thread_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(thread_list.GetMutex());
ThreadSP curr_thread (thread_list.GetSelectedThread());
ThreadSP thread;
@@ -1271,7 +1270,6 @@ Process::WaitForState(const TimeValue *timeout,
const uint32_t num_match_states)
{
EventSP event_sp;
- uint32_t i;
StateType state = GetState();
while (state != eStateInvalid)
{
@@ -1280,9 +1278,9 @@ Process::WaitForState(const TimeValue *timeout,
if (state == eStateDetached || state == eStateExited)
return state;
- state = WaitForStateChangedEvents (timeout, event_sp, NULL);
+ state = WaitForStateChangedEvents(timeout, event_sp, nullptr);
- for (i=0; i<num_match_states; ++i)
+ for (uint32_t i = 0; i < num_match_states; ++i)
{
if (match_states[i] == state)
return state;
@@ -1292,11 +1290,11 @@ Process::WaitForState(const TimeValue *timeout,
}
bool
-Process::HijackProcessEvents (Listener *listener)
+Process::HijackProcessEvents (ListenerSP listener_sp)
{
- if (listener != NULL)
+ if (listener_sp)
{
- return HijackBroadcaster(listener, eBroadcastBitStateChanged | eBroadcastBitInterrupt);
+ return HijackBroadcaster(listener_sp, eBroadcastBitStateChanged | eBroadcastBitInterrupt);
}
else
return false;
@@ -1309,7 +1307,7 @@ Process::RestoreProcessEvents ()
}
StateType
-Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, Listener *hijack_listener)
+Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, ListenerSP hijack_listener_sp)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
@@ -1317,15 +1315,15 @@ Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp,
log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__,
static_cast<const void*>(timeout));
- Listener *listener = hijack_listener;
- if (listener == NULL)
- listener = &m_listener;
+ ListenerSP listener_sp = hijack_listener_sp;
+ if (!listener_sp)
+ listener_sp = m_listener_sp;
StateType state = eStateInvalid;
- if (listener->WaitForEventForBroadcasterWithType (timeout,
- this,
- eBroadcastBitStateChanged | eBroadcastBitInterrupt,
- event_sp))
+ if (listener_sp->WaitForEventForBroadcasterWithType (timeout,
+ this,
+ eBroadcastBitStateChanged | eBroadcastBitInterrupt,
+ event_sp))
{
if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged)
state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
@@ -1349,7 +1347,7 @@ Process::PeekAtStateChangedEvents ()
log->Printf ("Process::%s...", __FUNCTION__);
Event *event_ptr;
- event_ptr = m_listener.PeekAtNextEventForBroadcasterWithType (this,
+ event_ptr = m_listener_sp->PeekAtNextEventForBroadcasterWithType (this,
eBroadcastBitStateChanged);
if (log)
{
@@ -1378,7 +1376,7 @@ Process::WaitForStateChangedEventsPrivate (const TimeValue *timeout, EventSP &ev
static_cast<const void*>(timeout));
StateType state = eStateInvalid;
- if (m_private_state_listener.WaitForEventForBroadcasterWithType (timeout,
+ if (m_private_state_listener_sp->WaitForEventForBroadcasterWithType (timeout,
&m_private_state_broadcaster,
eBroadcastBitStateChanged | eBroadcastBitInterrupt,
event_sp))
@@ -1405,9 +1403,9 @@ Process::WaitForEventsPrivate (const TimeValue *timeout, EventSP &event_sp, bool
static_cast<const void*>(timeout));
if (control_only)
- return m_private_state_listener.WaitForEventForBroadcaster(timeout, &m_private_state_control_broadcaster, event_sp);
+ return m_private_state_listener_sp->WaitForEventForBroadcaster(timeout, &m_private_state_control_broadcaster, event_sp);
else
- return m_private_state_listener.WaitForEvent(timeout, event_sp);
+ return m_private_state_listener_sp->WaitForEvent(timeout, event_sp);
}
bool
@@ -1419,7 +1417,7 @@ Process::IsRunning () const
int
Process::GetExitStatus ()
{
- Mutex::Locker locker (m_exit_status_mutex);
+ std::lock_guard<std::mutex> guard(m_exit_status_mutex);
if (m_public_state.GetValue() == eStateExited)
return m_exit_status;
@@ -1429,18 +1427,18 @@ Process::GetExitStatus ()
const char *
Process::GetExitDescription ()
{
- Mutex::Locker locker (m_exit_status_mutex);
+ std::lock_guard<std::mutex> guard(m_exit_status_mutex);
if (m_public_state.GetValue() == eStateExited && !m_exit_string.empty())
return m_exit_string.c_str();
- return NULL;
+ return nullptr;
}
bool
Process::SetExitStatus (int status, const char *cstr)
{
// Use a mutex to protect setting the exit status.
- Mutex::Locker locker (m_exit_status_mutex);
+ std::lock_guard<std::mutex> guard(m_exit_status_mutex);
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS));
if (log)
@@ -1464,14 +1462,6 @@ Process::SetExitStatus (int status, const char *cstr)
else
m_exit_string.clear();
- // When we exit, we don't need the input reader anymore
- if (m_process_input_reader)
- {
- m_process_input_reader->SetIsDone(true);
- m_process_input_reader->Cancel();
- m_process_input_reader.reset();
- }
-
// Clear the last natural stop ID since it has a strong
// reference to this process
m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
@@ -1489,12 +1479,6 @@ Process::IsAlive ()
{
switch (m_private_state.GetValue())
{
- case eStateInvalid:
- case eStateUnloaded:
- case eStateDetached:
- case eStateExited:
- return false;
-
case eStateConnected:
case eStateAttaching:
case eStateLaunching:
@@ -1504,6 +1488,8 @@ Process::IsAlive ()
case eStateCrashed:
case eStateSuspended:
return true;
+ default:
+ return false;
}
}
@@ -1512,21 +1498,15 @@ Process::IsAlive ()
// found in the global target list (we want to be completely sure that the
// lldb_private::Process doesn't go away before we can deliver the signal.
bool
-Process::SetProcessExitStatus (void *callback_baton,
- lldb::pid_t pid,
- bool exited,
- int signo, // Zero for no signal
- int exit_status // Exit value of process if signal is zero
-)
+Process::SetProcessExitStatus(lldb::pid_t pid, bool exited,
+ int signo, // Zero for no signal
+ int exit_status // Exit value of process if signal is zero
+ )
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("Process::SetProcessExitStatus (baton=%p, pid=%" PRIu64 ", exited=%i, signal=%i, exit_status=%i)\n",
- callback_baton,
- pid,
- exited,
- signo,
- exit_status);
+ log->Printf("Process::SetProcessExitStatus (pid=%" PRIu64 ", exited=%i, signal=%i, exit_status=%i)\n", pid,
+ exited, signo, exit_status);
if (exited)
{
@@ -1536,7 +1516,7 @@ Process::SetProcessExitStatus (void *callback_baton,
ProcessSP process_sp (target_sp->GetProcessSP());
if (process_sp)
{
- const char *signal_cstr = NULL;
+ const char *signal_cstr = nullptr;
if (signo)
signal_cstr = process_sp->GetUnixSignals()->GetSignalAsCString(signo);
@@ -1557,7 +1537,7 @@ Process::UpdateThreadListIfNeeded ()
const StateType state = GetPrivateState();
if (StateIsStoppedState (state, true))
{
- Mutex::Locker locker (m_thread_list.GetMutex ());
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
// m_thread_list does have its own mutex, but we need to
// hold onto the mutex between the call to UpdateThreadList(...)
// and the os->UpdateThreadList(...) so it doesn't change on us
@@ -1577,7 +1557,7 @@ Process::UpdateThreadListIfNeeded ()
// Clear any old backing threads where memory threads might have been
// backed by actual threads from the lldb_private::Process subclass
size_t num_old_threads = old_thread_list.GetSize(false);
- for (size_t i=0; i<num_old_threads; ++i)
+ for (size_t i = 0; i < num_old_threads; ++i)
old_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread();
// Turn off dynamic types to ensure we don't run any expressions. Objective C
@@ -1626,7 +1606,7 @@ Process::UpdateThreadListIfNeeded ()
void
Process::UpdateQueueListIfNeeded ()
{
- if (m_system_runtime_ap.get())
+ if (m_system_runtime_ap)
{
if (m_queue_list.GetSize() == 0 || m_queue_list_stop_id != GetLastNaturalStopID())
{
@@ -1691,7 +1671,8 @@ Process::StateChangedIsExternallyHijacked()
{
if (IsHijackedForEvent(eBroadcastBitStateChanged))
{
- if (strcmp(m_hijacking_listeners.back()->GetName(), "lldb.Process.ResumeSynchronous.hijack"))
+ const char *hijacking_name = GetHijackingListenerName();
+ if (hijacking_name && strcmp(hijacking_name, "lldb.Process.ResumeSynchronous.hijack"))
return true;
}
return false;
@@ -1764,13 +1745,13 @@ Process::ResumeSynchronous (Stream *stream)
return error;
}
- ListenerSP listener_sp (new Listener("lldb.Process.ResumeSynchronous.hijack"));
- HijackProcessEvents(listener_sp.get());
+ ListenerSP listener_sp (Listener::MakeListener("lldb.Process.ResumeSynchronous.hijack"));
+ HijackProcessEvents(listener_sp);
Error error = PrivateResume();
if (error.Success())
{
- StateType state = WaitForProcessToStop (NULL, NULL, true, listener_sp.get(), stream);
+ StateType state = WaitForProcessToStop (NULL, NULL, true, listener_sp, stream);
const bool must_be_alive = false; // eStateExited is ok, so this must be false
if (!StateIsStoppedState(state, must_be_alive))
error.SetErrorStringWithFormat("process not in stopped state after synchronous resume: %s", StateAsCString(state));
@@ -1800,8 +1781,8 @@ Process::SetPrivateState (StateType new_state)
if (log)
log->Printf("Process::SetPrivateState (%s)", StateAsCString(new_state));
- Mutex::Locker thread_locker(m_thread_list.GetMutex());
- Mutex::Locker locker(m_private_state.GetMutex());
+ std::lock_guard<std::recursive_mutex> thread_guard(m_thread_list.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_private_state.GetMutex());
const StateType old_state = m_private_state.GetValueNoLock ();
state_changed = old_state != new_state;
@@ -1844,7 +1825,7 @@ Process::SetPrivateState (StateType new_state)
}
// Use our target to get a shared pointer to ourselves...
- if (m_finalize_called && PrivateStateThreadIsValid() == false)
+ if (m_finalize_called && !PrivateStateThreadIsValid())
BroadcastEvent (event_sp);
else
m_private_state_broadcaster.BroadcastEvent (event_sp);
@@ -1899,18 +1880,18 @@ CPPLanguageRuntime *
Process::GetCPPLanguageRuntime (bool retry_if_null)
{
LanguageRuntime *runtime = GetLanguageRuntime(eLanguageTypeC_plus_plus, retry_if_null);
- if (runtime != NULL && runtime->GetLanguageType() == eLanguageTypeC_plus_plus)
+ if (runtime != nullptr && runtime->GetLanguageType() == eLanguageTypeC_plus_plus)
return static_cast<CPPLanguageRuntime *> (runtime);
- return NULL;
+ return nullptr;
}
ObjCLanguageRuntime *
Process::GetObjCLanguageRuntime (bool retry_if_null)
{
LanguageRuntime *runtime = GetLanguageRuntime(eLanguageTypeObjC, retry_if_null);
- if (runtime != NULL && runtime->GetLanguageType() == eLanguageTypeObjC)
+ if (runtime != nullptr && runtime->GetLanguageType() == eLanguageTypeObjC)
return static_cast<ObjCLanguageRuntime *> (runtime);
- return NULL;
+ return nullptr;
}
bool
@@ -2167,7 +2148,7 @@ Error
Process::EnableSoftwareBreakpoint (BreakpointSite *bp_site)
{
Error error;
- assert (bp_site != NULL);
+ assert(bp_site != nullptr);
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
const addr_t bp_addr = bp_site->GetLoadAddress();
if (log)
@@ -2196,7 +2177,7 @@ Process::EnableSoftwareBreakpoint (BreakpointSite *bp_site)
{
const uint8_t * const bp_opcode_bytes = bp_site->GetTrapOpcodeBytes();
- if (bp_opcode_bytes == NULL)
+ if (bp_opcode_bytes == nullptr)
{
error.SetErrorString ("BreakpointSite doesn't contain a valid breakpoint trap opcode.");
return error;
@@ -2244,7 +2225,7 @@ Error
Process::DisableSoftwareBreakpoint (BreakpointSite *bp_site)
{
Error error;
- assert (bp_site != NULL);
+ assert(bp_site != nullptr);
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
addr_t bp_addr = bp_site->GetLoadAddress();
lldb::user_id_t breakID = bp_site->GetID();
@@ -2388,7 +2369,7 @@ Process::ReadCStringFromMemory (addr_t addr, std::string &out_str, Error &error)
char buf[256];
out_str.clear();
addr_t curr_addr = addr;
- while (1)
+ while (true)
{
size_t length = ReadCStringFromMemory (curr_addr, buf, sizeof(buf), error);
if (length == 0)
@@ -2436,7 +2417,7 @@ Process::ReadStringFromMemory (addr_t addr, char *dst, size_t max_bytes, Error &
// Search for a null terminator of correct size and alignment in bytes_read
size_t aligned_start = total_bytes_read - total_bytes_read % type_width;
for (size_t i = aligned_start; i + type_width <= total_bytes_read + bytes_read; i += type_width)
- if (::strncmp(&dst[i], terminator, type_width) == 0)
+ if (::memcmp(&dst[i], terminator, type_width) == 0)
{
error.Clear();
return i;
@@ -2499,7 +2480,7 @@ Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len, Erro
}
else
{
- if (dst == NULL)
+ if (dst == nullptr)
result_error.SetErrorString("invalid arguments");
else
result_error.Clear();
@@ -2510,7 +2491,7 @@ Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len, Erro
size_t
Process::ReadMemoryFromInferior (addr_t addr, void *buf, size_t size, Error &error)
{
- if (buf == NULL || size == 0)
+ if (buf == nullptr || size == 0)
return 0;
size_t bytes_read = 0;
@@ -2536,7 +2517,8 @@ Process::ReadMemoryFromInferior (addr_t addr, void *buf, size_t size, Error &err
}
uint64_t
-Process::ReadUnsignedIntegerFromMemory (lldb::addr_t vm_addr, size_t integer_byte_size, uint64_t fail_value, Error &error)
+Process::ReadUnsignedIntegerFromMemory(lldb::addr_t vm_addr, size_t integer_byte_size, uint64_t fail_value,
+ Error &error)
{
Scalar scalar;
if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, false, scalar, error))
@@ -2544,6 +2526,15 @@ Process::ReadUnsignedIntegerFromMemory (lldb::addr_t vm_addr, size_t integer_byt
return fail_value;
}
+int64_t
+Process::ReadSignedIntegerFromMemory(lldb::addr_t vm_addr, size_t integer_byte_size, int64_t fail_value, Error &error)
+{
+ Scalar scalar;
+ if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, true, scalar, error))
+ return scalar.SLongLong(fail_value);
+ return fail_value;
+}
+
addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error)
{
@@ -2594,7 +2585,7 @@ Process::WriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
m_memory_cache.Flush (addr, size);
#endif
- if (buf == NULL || size == 0)
+ if (buf == nullptr || size == 0)
return 0;
m_mod_id.BumpMemoryID();
@@ -2905,7 +2896,7 @@ Process::WaitForProcessStopPrivate (const TimeValue *timeout, EventSP &event_sp)
StateType state;
// Now wait for the process to launch and return control to us, and then
// call DidLaunch:
- while (1)
+ while (true)
{
event_sp.reset();
state = WaitForStateChangedEventsPrivate (timeout, event_sp);
@@ -2928,7 +2919,7 @@ Process::LoadOperatingSystemPlugin(bool flush)
{
if (flush)
m_thread_list.Clear();
- m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
+ m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr));
if (flush)
Flush();
}
@@ -2943,7 +2934,7 @@ Process::Launch (ProcessLaunchInfo &launch_info)
m_system_runtime_ap.reset();
m_os_ap.reset();
m_process_input_reader.reset();
- m_stop_info_override_callback = NULL;
+ m_stop_info_override_callback = nullptr;
Module *exe_module = GetTarget().GetExecutableModulePointer();
if (exe_module)
@@ -2988,7 +2979,7 @@ Process::Launch (ProcessLaunchInfo &launch_info)
{
SetID (LLDB_INVALID_PROCESS_ID);
const char *error_string = error.AsCString();
- if (error_string == NULL)
+ if (error_string == nullptr)
error_string = "launch failed";
SetExitStatus (-1, error_string);
}
@@ -3001,7 +2992,7 @@ Process::Launch (ProcessLaunchInfo &launch_info)
timeout_time.OffsetWithSeconds(10);
StateType state = WaitForProcessStopPrivate(&timeout_time, event_sp);
- if (state == eStateInvalid || event_sp.get() == NULL)
+ if (state == eStateInvalid || !event_sp)
{
// We were able to launch the process, but we failed to
// catch the initial stop.
@@ -3066,8 +3057,8 @@ Process::LoadCore ()
Error error = DoLoadCore();
if (error.Success())
{
- Listener listener ("lldb.process.load_core_listener");
- HijackProcessEvents(&listener);
+ ListenerSP listener_sp (Listener::MakeListener("lldb.process.load_core_listener"));
+ HijackProcessEvents(listener_sp);
if (PrivateStateThreadIsValid ())
ResumePrivateStateThread ();
@@ -3084,7 +3075,7 @@ Process::LoadCore ()
if (system_runtime)
system_runtime->DidAttach();
- m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
+ m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr));
// We successfully loaded a core file, now pretend we stopped so we can
// show all of the threads in the core file and explore the crashed
// state.
@@ -3092,7 +3083,7 @@ Process::LoadCore ()
// Wait indefinitely for a stopped event since we just posted one above...
lldb::EventSP event_sp;
- listener.WaitForEvent (NULL, event_sp);
+ listener_sp->WaitForEvent (nullptr, event_sp);
StateType state = ProcessEventData::GetStateFromEvent(event_sp.get());
if (!StateIsStoppedState (state, false))
@@ -3110,8 +3101,8 @@ Process::LoadCore ()
DynamicLoader *
Process::GetDynamicLoader ()
{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, NULL));
+ if (!m_dyld_ap)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(this, nullptr));
return m_dyld_ap.get();
}
@@ -3135,8 +3126,8 @@ Process::GetJITLoaders ()
SystemRuntime *
Process::GetSystemRuntime ()
{
- if (m_system_runtime_ap.get() == NULL)
- m_system_runtime_ap.reset (SystemRuntime::FindPlugin(this));
+ if (!m_system_runtime_ap)
+ m_system_runtime_ap.reset(SystemRuntime::FindPlugin(this));
return m_system_runtime_ap.get();
}
@@ -3169,31 +3160,29 @@ Process::AttachCompletionHandler::PerformAction (lldb::EventSP &event_sp)
case eStateStopped:
case eStateCrashed:
+ // During attach, prior to sending the eStateStopped event,
+ // lldb_private::Process subclasses must set the new process ID.
+ assert (m_process->GetID() != LLDB_INVALID_PROCESS_ID);
+ // We don't want these events to be reported, so go set the ShouldReportStop here:
+ m_process->GetThreadList().SetShouldReportStop (eVoteNo);
+
+ if (m_exec_count > 0)
{
- // During attach, prior to sending the eStateStopped event,
- // lldb_private::Process subclasses must set the new process ID.
- assert (m_process->GetID() != LLDB_INVALID_PROCESS_ID);
- // We don't want these events to be reported, so go set the ShouldReportStop here:
- m_process->GetThreadList().SetShouldReportStop (eVoteNo);
-
- if (m_exec_count > 0)
- {
- --m_exec_count;
+ --m_exec_count;
- if (log)
- log->Printf ("Process::AttachCompletionHandler::%s state %s: reduced remaining exec count to %" PRIu32 ", requesting resume", __FUNCTION__, StateAsCString(state), m_exec_count);
+ if (log)
+ log->Printf ("Process::AttachCompletionHandler::%s state %s: reduced remaining exec count to %" PRIu32 ", requesting resume", __FUNCTION__, StateAsCString(state), m_exec_count);
- RequestResume();
- return eEventActionRetry;
- }
- else
- {
- if (log)
- log->Printf ("Process::AttachCompletionHandler::%s state %s: no more execs expected to start, continuing with attach", __FUNCTION__, StateAsCString(state));
+ RequestResume();
+ return eEventActionRetry;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("Process::AttachCompletionHandler::%s state %s: no more execs expected to start, continuing with attach", __FUNCTION__, StateAsCString(state));
- m_process->CompleteAttach ();
- return eEventActionSuccess;
- }
+ m_process->CompleteAttach ();
+ return eEventActionSuccess;
}
break;
@@ -3219,11 +3208,11 @@ Process::AttachCompletionHandler::GetExitString ()
return m_exit_string.c_str();
}
-Listener &
+ListenerSP
ProcessAttachInfo::GetListenerForProcess (Debugger &debugger)
{
if (m_listener_sp)
- return *m_listener_sp;
+ return m_listener_sp;
else
return debugger.GetListener();
}
@@ -3237,7 +3226,7 @@ Process::Attach (ProcessAttachInfo &attach_info)
m_jit_loaders_ap.reset();
m_system_runtime_ap.reset();
m_os_ap.reset();
- m_stop_info_override_callback = NULL;
+ m_stop_info_override_callback = nullptr;
lldb::pid_t attach_pid = attach_info.GetProcessID();
Error error;
@@ -3273,7 +3262,7 @@ Process::Attach (ProcessAttachInfo &attach_info)
if (GetID() != LLDB_INVALID_PROCESS_ID)
{
SetID (LLDB_INVALID_PROCESS_ID);
- if (error.AsCString() == NULL)
+ if (error.AsCString() == nullptr)
error.SetErrorString("attach failed");
SetExitStatus(-1, error.AsCString());
@@ -3358,7 +3347,6 @@ Process::Attach (ProcessAttachInfo &attach_info)
if (error.Success())
{
-
SetNextEventAction(new Process::AttachCompletionHandler(this, attach_info.GetResumeCount()));
StartPrivateStateThread();
}
@@ -3368,7 +3356,7 @@ Process::Attach (ProcessAttachInfo &attach_info)
SetID (LLDB_INVALID_PROCESS_ID);
const char *error_string = error.AsCString();
- if (error_string == NULL)
+ if (error_string == nullptr)
error_string = "attach failed";
SetExitStatus(-1, error_string);
@@ -3381,7 +3369,7 @@ Process::Attach (ProcessAttachInfo &attach_info)
void
Process::CompleteAttach ()
{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TARGET));
if (log)
log->Printf ("Process::%s()", __FUNCTION__);
@@ -3405,11 +3393,11 @@ Process::CompleteAttach ()
// We just attached. If we have a platform, ask it for the process architecture, and if it isn't
// the same as the one we've already set, switch architectures.
PlatformSP platform_sp (GetTarget().GetPlatform ());
- assert (platform_sp.get());
+ assert(platform_sp);
if (platform_sp)
{
const ArchSpec &target_arch = GetTarget().GetArchitecture();
- if (target_arch.IsValid() && !platform_sp->IsCompatibleArchitecture (target_arch, false, NULL))
+ if (target_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(target_arch, false, nullptr))
{
ArchSpec platform_arch;
platform_sp = platform_sp->GetPlatformForArchitecture (target_arch, &platform_arch);
@@ -3424,7 +3412,7 @@ Process::CompleteAttach ()
else if (!process_arch.IsValid())
{
ProcessInstanceInfo process_info;
- platform_sp->GetProcessInfo (GetID(), process_info);
+ GetProcessInfo(process_info);
const ArchSpec &process_arch = process_info.GetArchitecture();
if (process_arch.IsValid() && !GetTarget().GetArchitecture().IsExactMatch(process_arch))
{
@@ -3467,10 +3455,10 @@ Process::CompleteAttach ()
}
}
- m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
+ m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr));
// Figure out which one is the executable, and set that in our target:
const ModuleList &target_modules = GetTarget().GetImages();
- Mutex::Locker modules_locker(target_modules.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
size_t num_modules = target_modules.GetSize();
ModuleSP new_executable_module_sp;
@@ -3514,7 +3502,7 @@ Process::ConnectRemote (Stream *strm, const char *remote_url)
if (GetID() != LLDB_INVALID_PROCESS_ID)
{
EventSP event_sp;
- StateType state = WaitForProcessStopPrivate(NULL, event_sp);
+ StateType state = WaitForProcessStopPrivate(nullptr, event_sp);
if (state == eStateStopped || state == eStateCrashed)
{
@@ -3525,7 +3513,6 @@ Process::ConnectRemote (Stream *strm, const char *remote_url)
// This delays passing the stopped event to listeners till
// CompleteAttach gets a chance to complete...
HandlePrivateEvent (event_sp);
-
}
}
@@ -3607,8 +3594,8 @@ Process::Halt (bool clear_thread_plans, bool use_run_lock)
// own.
m_clear_thread_plans_on_stop |= clear_thread_plans;
- Listener halt_listener ("lldb.process.halt_listener");
- HijackProcessEvents(&halt_listener);
+ ListenerSP halt_listener_sp (Listener::MakeListener("lldb.process.halt_listener"));
+ HijackProcessEvents(halt_listener_sp);
EventSP event_sp;
@@ -3628,7 +3615,7 @@ Process::Halt (bool clear_thread_plans, bool use_run_lock)
TimeValue timeout_time;
timeout_time = TimeValue::Now();
timeout_time.OffsetWithSeconds(10);
- StateType state = WaitForProcessToStop(&timeout_time, &event_sp, true, &halt_listener,
+ StateType state = WaitForProcessToStop(&timeout_time, &event_sp, true, halt_listener_sp,
nullptr, use_run_lock);
RestoreProcessEvents();
@@ -3653,8 +3640,8 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp)
if (log)
log->Printf("Process::%s() About to stop.", __FUNCTION__);
- ListenerSP listener_sp (new Listener("lldb.Process.StopForDestroyOrDetach.hijack"));
- HijackProcessEvents(listener_sp.get());
+ ListenerSP listener_sp (Listener::MakeListener("lldb.Process.StopForDestroyOrDetach.hijack"));
+ HijackProcessEvents(listener_sp);
SendAsyncInterrupt();
@@ -3662,7 +3649,7 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp)
TimeValue timeout (TimeValue::Now());
timeout.OffsetWithSeconds(10);
- StateType state = WaitForProcessToStop (&timeout, &exit_event_sp, true, listener_sp.get());
+ StateType state = WaitForProcessToStop (&timeout, &exit_event_sp, true, listener_sp);
RestoreProcessEvents();
@@ -3688,7 +3675,7 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp)
StateType private_state = m_private_state.GetValue();
if (private_state != eStateStopped)
{
- return error;
+ return Error("Attempt to stop the target in order to detach timed out. State = %s", StateAsCString(GetState()));
}
}
}
@@ -3888,7 +3875,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
m_stdio_communication.StopReadThread();
m_stdin_forward = false;
- // fall-through
+ LLVM_FALLTHROUGH;
case eStateConnected:
case eStateAttaching:
case eStateLaunching:
@@ -3945,7 +3932,6 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
case eStateStopped:
case eStateCrashed:
case eStateSuspended:
- {
// We've stopped. First see if we're going to restart the target.
// If we are going to stop, then we always broadcast the event.
// If we aren't going to stop, let the thread plans decide if we're going to report this event.
@@ -3974,7 +3960,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
// So in that case just report the event.
if (!was_restarted)
- should_resume = m_thread_list.ShouldStop (event_ptr) == false;
+ should_resume = !m_thread_list.ShouldStop(event_ptr);
if (was_restarted || should_resume || m_resume_requested)
{
@@ -4011,8 +3997,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
SynchronouslyNotifyStateChanged (state);
}
}
- }
- break;
+ break;
}
// Forcing the next event delivery is a one shot deal. So reset it here.
@@ -4069,8 +4054,8 @@ Process::StartPrivateStateThread (bool is_secondary_thread)
}
// Create the private state thread, and start it running.
- PrivateStateThreadArgs args = {this, is_secondary_thread};
- m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, (void *) &args, NULL, 8 * 1024 * 1024);
+ PrivateStateThreadArgs *args_ptr = new PrivateStateThreadArgs(this, is_secondary_thread);
+ m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, (void *) args_ptr, nullptr, 8 * 1024 * 1024);
if (m_private_state_thread.IsJoinable())
{
ResumePrivateStateThread();
@@ -4095,7 +4080,7 @@ Process::ResumePrivateStateThread ()
void
Process::StopPrivateStateThread ()
{
- if (PrivateStateThreadIsValid ())
+ if (m_private_state_thread.IsJoinable ())
ControlPrivateStateThread (eBroadcastInternalStateControlStop);
else
{
@@ -4117,47 +4102,52 @@ Process::ControlPrivateStateThread (uint32_t signal)
if (log)
log->Printf ("Process::%s (signal = %d)", __FUNCTION__, signal);
- // Signal the private state thread. First we should copy this is case the
- // thread starts exiting since the private state thread will NULL this out
- // when it exits
- HostThread private_state_thread(m_private_state_thread);
- if (private_state_thread.IsJoinable())
+ // Signal the private state thread
+ if (m_private_state_thread.IsJoinable())
{
- TimeValue timeout_time;
- bool timed_out;
-
- m_private_state_control_broadcaster.BroadcastEvent (signal, NULL);
-
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithSeconds(2);
+ // Broadcast the event.
+ // It is important to do this outside of the if below, because
+ // it's possible that the thread state is invalid but that the
+ // thread is waiting on a control event instead of simply being
+ // on its way out (this should not happen, but it apparently can).
if (log)
log->Printf ("Sending control event of type: %d.", signal);
- m_private_state_control_wait.WaitForValueEqualTo (true, &timeout_time, &timed_out);
- m_private_state_control_wait.SetValue (false, eBroadcastNever);
+ std::shared_ptr<EventDataReceipt> event_receipt_sp(new EventDataReceipt());
+ m_private_state_control_broadcaster.BroadcastEvent(signal, event_receipt_sp);
- if (signal == eBroadcastInternalStateControlStop)
+ // Wait for the event receipt or for the private state thread to exit
+ bool receipt_received = false;
+ if (PrivateStateThreadIsValid())
{
- if (timed_out)
- {
- Error error = private_state_thread.Cancel();
- if (log)
- log->Printf ("Timed out responding to the control event, cancel got error: \"%s\".", error.AsCString());
- }
- else
+ while (!receipt_received)
{
- if (log)
- log->Printf ("The control event killed the private state thread without having to cancel.");
+ bool timed_out = false;
+ TimeValue timeout_time;
+ timeout_time = TimeValue::Now();
+ timeout_time.OffsetWithSeconds(2);
+ // Check for a receipt for 2 seconds and then check if the private state
+ // thread is still around.
+ receipt_received = event_receipt_sp->WaitForEventReceived (&timeout_time, &timed_out);
+ if (!receipt_received)
+ {
+ // Check if the private state thread is still around. If it isn't then we are done waiting
+ if (!PrivateStateThreadIsValid())
+ break; // Private state thread exited or is exiting, we are done
+ }
}
+ }
+ if (signal == eBroadcastInternalStateControlStop)
+ {
thread_result_t result = NULL;
- private_state_thread.Join(&result);
+ m_private_state_thread.Join(&result);
m_private_state_thread.Reset();
}
}
else
{
if (log)
- log->Printf ("Private state thread already dead, no need to signal it to stop.");
+ log->Printf("Private state thread already dead, no need to signal it to stop.");
}
}
@@ -4165,9 +4155,9 @@ void
Process::SendAsyncInterrupt ()
{
if (PrivateStateThreadIsValid())
- m_private_state_broadcaster.BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
+ m_private_state_broadcaster.BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr);
else
- BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
+ BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr);
}
void
@@ -4179,7 +4169,7 @@ Process::HandlePrivateEvent (EventSP &event_sp)
const StateType new_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
// First check to see if anybody wants a shot at this event:
- if (m_next_event_action_ap.get() != NULL)
+ if (m_next_event_action_ap)
{
NextEventAction::EventActionResult action_result = m_next_event_action_ap->PerformAction(event_sp);
if (log)
@@ -4188,7 +4178,7 @@ Process::HandlePrivateEvent (EventSP &event_sp)
switch (action_result)
{
case NextEventAction::eEventActionSuccess:
- SetNextEventAction(NULL);
+ SetNextEventAction(nullptr);
break;
case NextEventAction::eEventActionRetry:
@@ -4202,10 +4192,10 @@ Process::HandlePrivateEvent (EventSP &event_sp)
{
// FIXME: should cons up an exited event, and discard this one.
SetExitStatus(0, m_next_event_action_ap->GetExitString());
- SetNextEventAction(NULL);
+ SetNextEventAction(nullptr);
return;
}
- SetNextEventAction(NULL);
+ SetNextEventAction(nullptr);
break;
}
}
@@ -4273,7 +4263,7 @@ Process::HandlePrivateEvent (EventSP &event_sp)
// events) and we do need the IO handler to be pushed and popped
// correctly.
- if (is_hijacked || GetTarget().GetDebugger().IsHandlingEvents() == false)
+ if (is_hijacked || !GetTarget().GetDebugger().IsHandlingEvents())
PopProcessIOHandler ();
}
}
@@ -4312,8 +4302,9 @@ Process::HaltPrivate()
thread_result_t
Process::PrivateStateThread (void *arg)
{
- PrivateStateThreadArgs *real_args = static_cast<PrivateStateThreadArgs *> (arg);
- thread_result_t result = real_args->process->RunPrivateStateThread(real_args->is_secondary_thread);
+ PrivateStateThreadArgs real_args = *static_cast<PrivateStateThreadArgs *> (arg);
+ free (arg);
+ thread_result_t result = real_args.process->RunPrivateStateThread(real_args.is_secondary_thread);
return result;
}
@@ -4321,7 +4312,6 @@ thread_result_t
Process::RunPrivateStateThread (bool is_secondary_thread)
{
bool control_only = true;
- m_private_state_control_wait.SetValue (false, eBroadcastNever);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
@@ -4333,7 +4323,7 @@ Process::RunPrivateStateThread (bool is_secondary_thread)
while (!exit_now)
{
EventSP event_sp;
- WaitForEventsPrivate (NULL, event_sp, control_only);
+ WaitForEventsPrivate(nullptr, event_sp, control_only);
if (event_sp->BroadcasterIs(&m_private_state_control_broadcaster))
{
if (log)
@@ -4356,7 +4346,6 @@ Process::RunPrivateStateThread (bool is_secondary_thread)
break;
}
- m_private_state_control_wait.SetValue (true, eBroadcastAlways);
continue;
}
else if (event_sp->GetType() == eBroadcastBitInterrupt)
@@ -4367,7 +4356,7 @@ Process::RunPrivateStateThread (bool is_secondary_thread)
log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") woke up with an interrupt while attaching - forwarding interrupt.",
__FUNCTION__, static_cast<void*>(this),
GetID());
- BroadcastEvent (eBroadcastBitInterrupt, NULL);
+ BroadcastEvent(eBroadcastBitInterrupt, nullptr);
}
else if(StateIsRunningState(m_last_broadcast_state))
{
@@ -4452,8 +4441,6 @@ Process::RunPrivateStateThread (bool is_secondary_thread)
// try to change it on the way out.
if (!is_secondary_thread)
m_public_run_lock.SetStopped();
- m_private_state_control_wait.SetValue (true, eBroadcastAlways);
- m_private_state_thread.Reset();
return NULL;
}
@@ -4610,7 +4597,7 @@ Process::ProcessEventData::DoOnRemoval (Event *event_ptr)
this_thread_wants_to_stop = stop_info_sp->ShouldStop(event_ptr);
}
- if (still_should_stop == false)
+ if (!still_should_stop)
still_should_stop = this_thread_wants_to_stop;
}
}
@@ -4660,7 +4647,7 @@ Process::ProcessEventData::GetEventDataFromEvent (const Event *event_ptr)
if (event_data && event_data->GetFlavor() == ProcessEventData::GetFlavorString())
return static_cast <const ProcessEventData *> (event_ptr->GetData());
}
- return NULL;
+ return nullptr;
}
ProcessSP
@@ -4677,7 +4664,7 @@ StateType
Process::ProcessEventData::GetStateFromEvent (const Event *event_ptr)
{
const ProcessEventData *data = GetEventDataFromEvent (event_ptr);
- if (data == NULL)
+ if (data == nullptr)
return eStateInvalid;
else
return data->GetState();
@@ -4687,7 +4674,7 @@ bool
Process::ProcessEventData::GetRestartedFromEvent (const Event *event_ptr)
{
const ProcessEventData *data = GetEventDataFromEvent (event_ptr);
- if (data == NULL)
+ if (data == nullptr)
return false;
else
return data->GetRestarted();
@@ -4697,7 +4684,7 @@ void
Process::ProcessEventData::SetRestartedInEvent (Event *event_ptr, bool new_value)
{
ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
- if (data != NULL)
+ if (data != nullptr)
data->SetRestarted(new_value);
}
@@ -4705,7 +4692,7 @@ size_t
Process::ProcessEventData::GetNumRestartedReasons(const Event *event_ptr)
{
ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
- if (data != NULL)
+ if (data != nullptr)
return data->GetNumRestartedReasons();
else
return 0;
@@ -4715,17 +4702,17 @@ const char *
Process::ProcessEventData::GetRestartedReasonAtIndex(const Event *event_ptr, size_t idx)
{
ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
- if (data != NULL)
+ if (data != nullptr)
return data->GetRestartedReasonAtIndex(idx);
else
- return NULL;
+ return nullptr;
}
void
Process::ProcessEventData::AddRestartedReason (Event *event_ptr, const char *reason)
{
ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
- if (data != NULL)
+ if (data != nullptr)
data->AddRestartedReason(reason);
}
@@ -4733,7 +4720,7 @@ bool
Process::ProcessEventData::GetInterruptedFromEvent (const Event *event_ptr)
{
const ProcessEventData *data = GetEventDataFromEvent (event_ptr);
- if (data == NULL)
+ if (data == nullptr)
return false;
else
return data->GetInterrupted ();
@@ -4743,7 +4730,7 @@ void
Process::ProcessEventData::SetInterruptedInEvent (Event *event_ptr, bool new_value)
{
ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
- if (data != NULL)
+ if (data != nullptr)
data->SetInterrupted(new_value);
}
@@ -4770,8 +4757,8 @@ Process::CalculateExecutionContext (ExecutionContext &exe_ctx)
{
exe_ctx.SetTargetPtr (&GetTarget());
exe_ctx.SetProcessPtr (this);
- exe_ctx.SetThreadPtr(NULL);
- exe_ctx.SetFramePtr (NULL);
+ exe_ctx.SetThreadPtr(nullptr);
+ exe_ctx.SetFramePtr(nullptr);
}
//uint32_t
@@ -4791,11 +4778,11 @@ Process::CalculateExecutionContext (ExecutionContext &exe_ctx)
//{
// return Host::GetArchSpecForExistingProcess (process_name);
//}
-//
+
void
Process::AppendSTDOUT (const char * s, size_t len)
{
- Mutex::Locker locker (m_stdio_communication_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex);
m_stdout_data.append (s, len);
BroadcastEventIfUnique (eBroadcastBitSTDOUT, new ProcessEventData (shared_from_this(), GetState()));
}
@@ -4803,7 +4790,7 @@ Process::AppendSTDOUT (const char * s, size_t len)
void
Process::AppendSTDERR (const char * s, size_t len)
{
- Mutex::Locker locker (m_stdio_communication_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex);
m_stderr_data.append (s, len);
BroadcastEventIfUnique (eBroadcastBitSTDERR, new ProcessEventData (shared_from_this(), GetState()));
}
@@ -4811,7 +4798,7 @@ Process::AppendSTDERR (const char * s, size_t len)
void
Process::BroadcastAsyncProfileData(const std::string &one_profile_data)
{
- Mutex::Locker locker (m_profile_data_comm_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_profile_data_comm_mutex);
m_profile_data.push_back(one_profile_data);
BroadcastEventIfUnique (eBroadcastBitProfileData, new ProcessEventData (shared_from_this(), GetState()));
}
@@ -4819,7 +4806,7 @@ Process::BroadcastAsyncProfileData(const std::string &one_profile_data)
size_t
Process::GetAsyncProfileData (char *buf, size_t buf_size, Error &error)
{
- Mutex::Locker locker(m_profile_data_comm_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_profile_data_comm_mutex);
if (m_profile_data.empty())
return 0;
@@ -4854,7 +4841,7 @@ Process::GetAsyncProfileData (char *buf, size_t buf_size, Error &error)
size_t
Process::GetSTDOUT (char *buf, size_t buf_size, Error &error)
{
- Mutex::Locker locker(m_stdio_communication_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex);
size_t bytes_available = m_stdout_data.size();
if (bytes_available > 0)
{
@@ -4881,7 +4868,7 @@ Process::GetSTDOUT (char *buf, size_t buf_size, Error &error)
size_t
Process::GetSTDERR (char *buf, size_t buf_size, Error &error)
{
- Mutex::Locker locker(m_stdio_communication_mutex);
+ std::lock_guard<std::recursive_mutex> gaurd(m_stdio_communication_mutex);
size_t bytes_available = m_stderr_data.size();
if (bytes_available > 0)
{
@@ -4952,6 +4939,7 @@ public:
// FD_ZERO, FD_SET are not supported on windows
#ifndef _WIN32
const int pipe_read_fd = m_pipe.GetReadFileDescriptor();
+ m_is_running = true;
while (!GetIsDone())
{
fd_set read_fdset;
@@ -4959,7 +4947,8 @@ public:
FD_SET (read_fd, &read_fdset);
FD_SET (pipe_read_fd, &read_fdset);
const int nfds = std::max<int>(read_fd, pipe_read_fd) + 1;
- int num_set_fds = select (nfds, &read_fdset, NULL, NULL, NULL);
+ int num_set_fds = select(nfds, &read_fdset, nullptr, nullptr, nullptr);
+
if (num_set_fds < 0)
{
const int select_errno = errno;
@@ -5003,6 +4992,7 @@ public:
}
}
}
+ m_is_running = false;
#endif
terminal_state.Restore();
}
@@ -5010,9 +5000,24 @@ public:
void
Cancel () override
{
- char ch = 'q'; // Send 'q' for quit
- size_t bytes_written = 0;
- m_pipe.Write(&ch, 1, bytes_written);
+ SetIsDone(true);
+ // Only write to our pipe to cancel if we are in IOHandlerProcessSTDIO::Run().
+ // We can end up with a python command that is being run from the command
+ // interpreter:
+ //
+ // (lldb) step_process_thousands_of_times
+ //
+ // In this case the command interpreter will be in the middle of handling
+ // the command and if the process pushes and pops the IOHandler thousands
+ // of times, we can end up writing to m_pipe without ever consuming the
+ // bytes from the pipe in IOHandlerProcessSTDIO::Run() and end up
+ // deadlocking when the pipe gets fed up and blocks until data is consumed.
+ if (m_is_running)
+ {
+ char ch = 'q'; // Send 'q' for quit
+ size_t bytes_written = 0;
+ m_pipe.Write(&ch, 1, bytes_written);
+ }
}
bool
@@ -5059,6 +5064,7 @@ protected:
File m_read_file; // Read from this file (usually actual STDIN for LLDB
File m_write_file; // Write to this file (usually the master pty for getting io to debuggee)
Pipe m_pipe;
+ std::atomic<bool> m_is_running;
};
void
@@ -5068,7 +5074,7 @@ Process::SetSTDIOFileDescriptor (int fd)
std::unique_ptr<ConnectionFileDescriptor> conn_ap (new ConnectionFileDescriptor (fd, true));
- if (conn_ap.get())
+ if (conn_ap)
{
m_stdio_communication.SetConnection (conn_ap.release());
if (m_stdio_communication.IsConnected())
@@ -5078,7 +5084,7 @@ Process::SetSTDIOFileDescriptor (int fd)
// Now read thread is set up, set up input reader.
- if (!m_process_input_reader.get())
+ if (!m_process_input_reader)
m_process_input_reader.reset (new IOHandlerProcessSTDIO (this, fd));
}
}
@@ -5180,41 +5186,41 @@ namespace
} // anonymous namespace
ExpressionResults
-Process::RunThreadPlan (ExecutionContext &exe_ctx,
- lldb::ThreadPlanSP &thread_plan_sp,
- const EvaluateExpressionOptions &options,
- Stream &errors)
+Process::RunThreadPlan(ExecutionContext &exe_ctx, lldb::ThreadPlanSP &thread_plan_sp,
+ const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager)
{
ExpressionResults return_value = eExpressionSetupError;
+
+ std::lock_guard<std::mutex> run_thread_plan_locker(m_run_thread_plan_lock);
- if (thread_plan_sp.get() == NULL)
+ if (!thread_plan_sp)
{
- errors.Printf("RunThreadPlan called with empty thread plan.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "RunThreadPlan called with empty thread plan.");
return eExpressionSetupError;
}
- if (!thread_plan_sp->ValidatePlan(NULL))
+ if (!thread_plan_sp->ValidatePlan(nullptr))
{
- errors.Printf ("RunThreadPlan called with an invalid thread plan.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "RunThreadPlan called with an invalid thread plan.");
return eExpressionSetupError;
}
if (exe_ctx.GetProcessPtr() != this)
{
- errors.Printf("RunThreadPlan called on wrong process.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "RunThreadPlan called on wrong process.");
return eExpressionSetupError;
}
Thread *thread = exe_ctx.GetThreadPtr();
- if (thread == NULL)
+ if (thread == nullptr)
{
- errors.Printf("RunThreadPlan called with invalid thread.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "RunThreadPlan called with invalid thread.");
return eExpressionSetupError;
}
// We need to change some of the thread plan attributes for the thread plan runner. This will restore them
// when we are done:
-
+
RestorePlanState thread_plan_restorer(thread_plan_sp);
// We rely on the thread plan we are running returning "PlanCompleted" if when it successfully completes.
@@ -5231,7 +5237,8 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
if (m_private_state.GetValue() != eStateStopped)
{
- errors.Printf ("RunThreadPlan called while the private state was not stopped.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "RunThreadPlan called while the private state was not stopped.");
return eExpressionSetupError;
}
@@ -5240,11 +5247,12 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
StackFrameSP selected_frame_sp = thread->GetSelectedFrame();
if (!selected_frame_sp)
{
- thread->SetSelectedFrame(0);
+ thread->SetSelectedFrame(nullptr);
selected_frame_sp = thread->GetSelectedFrame();
if (!selected_frame_sp)
{
- errors.Printf("RunThreadPlan called without a selected frame on thread %d", thread_idx_id);
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "RunThreadPlan called without a selected frame on thread %d", thread_idx_id);
return eExpressionSetupError;
}
}
@@ -5313,7 +5321,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
return eExpressionStoppedForDebug;
}
- Listener listener("lldb.process.listener.run-thread-plan");
+ ListenerSP listener_sp(Listener::MakeListener("lldb.process.listener.run-thread-plan"));
lldb::EventSP event_to_broadcast_sp;
@@ -5324,7 +5332,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
// If the event needs to propagate beyond the hijacker (e.g., the process exits during execution), then the event
// is put into event_to_broadcast_sp for rebroadcasting.
- ProcessEventHijacker run_thread_plan_hijacker (*this, &listener);
+ ProcessEventHijacker run_thread_plan_hijacker (*this, listener_sp);
if (log)
{
@@ -5340,7 +5348,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
lldb::EventSP event_sp;
lldb::StateType stop_state = lldb::eStateInvalid;
- TimeValue* timeout_ptr = NULL;
+ TimeValue* timeout_ptr = nullptr;
TimeValue real_timeout;
bool before_first_timeout = true; // This is set to false the first time that we have to halt the target.
@@ -5386,7 +5394,9 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
{
if (timeout_usec < option_one_thread_timeout)
{
- errors.Printf("RunThreadPlan called without one thread timeout greater than total timeout");
+ diagnostic_manager.PutCString(
+ eDiagnosticSeverityError,
+ "RunThreadPlan called without one thread timeout greater than total timeout");
return eExpressionSetupError;
}
computed_one_thread_timeout = option_one_thread_timeout;
@@ -5414,10 +5424,11 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
// Are there cases where we might want to run the remaining events here, and then try to
// call the function? That's probably being too tricky for our own good.
- Event *other_events = listener.PeekAtNextEvent();
- if (other_events != NULL)
+ Event *other_events = listener_sp->PeekAtNextEvent();
+ if (other_events != nullptr)
{
- errors.Printf("Calling RunThreadPlan with pending events on the queue.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "RunThreadPlan called with pending events on the queue.");
return eExpressionSetupError;
}
@@ -5441,7 +5452,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
TimeValue one_thread_timeout;
TimeValue final_timeout;
- while (1)
+ while (true)
{
// We usually want to resume the process if we get to the top of the loop.
// The only exception is if we get two running events with no intervening
@@ -5459,12 +5470,12 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
if (do_resume)
{
num_resumes++;
- Error resume_error = PrivateResume ();
+ Error resume_error = PrivateResume();
if (!resume_error.Success())
{
- errors.Printf("Error resuming inferior the %d time: \"%s\".\n",
- num_resumes,
- resume_error.AsCString());
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "couldn't resume inferior the %d time: \"%s\".", num_resumes,
+ resume_error.AsCString());
return_value = eExpressionSetupError;
break;
}
@@ -5473,14 +5484,15 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
TimeValue resume_timeout = TimeValue::Now();
resume_timeout.OffsetWithMicroSeconds(500000);
- got_event = listener.WaitForEvent(&resume_timeout, event_sp);
+ got_event = listener_sp->WaitForEvent(&resume_timeout, event_sp);
if (!got_event)
{
if (log)
- log->Printf ("Process::RunThreadPlan(): didn't get any event after resume %d, exiting.",
- num_resumes);
+ log->Printf("Process::RunThreadPlan(): didn't get any event after resume %" PRIu32 ", exiting.",
+ num_resumes);
- errors.Printf("Didn't get any event after resume %d, exiting.", num_resumes);
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "didn't get any event after resume %" PRIu32 ", exiting.", num_resumes);
return_value = eExpressionSetupError;
break;
}
@@ -5513,8 +5525,9 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
Halt(clear_thread_plans, use_run_lock);
}
- errors.Printf("Didn't get running event after initial resume, got %s instead.",
- StateAsCString(stop_state));
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "didn't get running event after initial resume, got %s instead.",
+ StateAsCString(stop_state));
return_value = eExpressionSetupError;
break;
}
@@ -5544,7 +5557,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
else
{
if (timeout_usec == 0)
- timeout_ptr = NULL;
+ timeout_ptr = nullptr;
else
{
final_timeout = TimeValue::Now();
@@ -5556,7 +5569,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
else
{
if (timeout_usec == 0)
- timeout_ptr = NULL;
+ timeout_ptr = nullptr;
else
{
final_timeout = TimeValue::Now();
@@ -5595,11 +5608,11 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
}
else
#endif
- got_event = listener.WaitForEvent (timeout_ptr, event_sp);
+ got_event = listener_sp->WaitForEvent (timeout_ptr, event_sp);
if (got_event)
{
- if (event_sp.get())
+ if (event_sp)
{
bool keep_going = false;
if (event_sp->GetType() == eBroadcastBitInterrupt)
@@ -5608,9 +5621,10 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
const bool use_run_lock = false;
Halt(clear_thread_plans, use_run_lock);
return_value = eExpressionInterrupted;
- errors.Printf ("Execution halted by user interrupt.");
+ diagnostic_manager.PutCString(eDiagnosticSeverityRemark, "execution halted by user interrupt.");
if (log)
- log->Printf ("Process::RunThreadPlan(): Got interrupted by eBroadcastBitInterrupted, exiting.");
+ log->Printf(
+ "Process::RunThreadPlan(): Got interrupted by eBroadcastBitInterrupted, exiting.");
break;
}
else
@@ -5713,7 +5727,8 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
if (stop_state == eStateExited)
event_to_broadcast_sp = event_sp;
- errors.Printf ("Execution stopped with unexpected state.\n");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "execution stopped with unexpected state.");
return_value = eExpressionInterrupted;
break;
}
@@ -5795,7 +5810,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
real_timeout = TimeValue::Now();
real_timeout.OffsetWithMicroSeconds(500000);
- got_event = listener.WaitForEvent(&real_timeout, event_sp);
+ got_event = listener_sp->WaitForEvent(&real_timeout, event_sp);
if (got_event)
{
@@ -5943,7 +5958,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
StreamString ts;
- const char *event_explanation = NULL;
+ const char *event_explanation = nullptr;
do
{
@@ -6091,7 +6106,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
if (GetThreadList().SetSelectedThreadByIndexID (selected_tid) && selected_stack_id.IsValid())
{
// We were able to restore the selected thread, now restore the frame:
- Mutex::Locker lock(GetThreadList().GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetThreadList().GetMutex());
StackFrameSP old_frame_sp = GetThreadList().GetSelectedThread()->GetFrameWithStackID(selected_stack_id);
if (old_frame_sp)
GetThreadList().GetSelectedThread()->SetSelectedFrame(old_frame_sp.get());
@@ -6196,7 +6211,7 @@ Process::GetThreadStatus (Stream &strm,
std::vector<lldb::tid_t> thread_id_array;
//Scope for thread list locker;
{
- Mutex::Locker locker (GetThreadList().GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetThreadList().GetMutex());
ThreadList &curr_thread_list = GetThreadList();
num_threads = curr_thread_list.GetSize();
uint32_t idx;
@@ -6213,7 +6228,7 @@ Process::GetThreadStatus (Stream &strm,
if (only_threads_with_stop_reason)
{
StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
- if (stop_info_sp.get() == NULL || !stop_info_sp->IsValid())
+ if (!stop_info_sp || !stop_info_sp->IsValid())
continue;
}
thread_sp->GetStatus (strm,
@@ -6259,7 +6274,7 @@ Process::RunPreResumeActions ()
struct PreResumeCallbackAndBaton action = m_pre_resume_actions.back();
m_pre_resume_actions.pop_back();
bool this_result = action.callback (action.baton);
- if (result == true)
+ if (result)
result = this_result;
}
return result;
@@ -6312,7 +6327,7 @@ Process::DidExec ()
m_instrumentation_runtimes.clear();
m_thread_list.DiscardThreadPlans();
m_memory_cache.Clear(true);
- m_stop_info_override_callback = NULL;
+ m_stop_info_override_callback = nullptr;
DoDidExec();
CompleteAttach ();
// Flush the process (threads and all stack frames) after running CompleteAttach()
@@ -6389,14 +6404,17 @@ Process::ModulesDidLoad (ModuleList &module_list)
for (const auto &pair: language_runtimes)
{
// We must check language_runtime_sp to make sure it is not
- // NULL as we might cache the fact that we didn't have a
+ // nullptr as we might cache the fact that we didn't have a
// language runtime for a language.
LanguageRuntimeSP language_runtime_sp = pair.second;
if (language_runtime_sp)
language_runtime_sp->ModulesDidLoad(module_list);
}
- LoadOperatingSystemPlugin(false);
+ // If we don't have an operating system plug-in, try to load one since
+ // loading shared libraries might cause a new one to try and load
+ if (!m_os_ap)
+ LoadOperatingSystemPlugin(false);
}
void
@@ -6405,10 +6423,10 @@ Process::PrintWarning (uint64_t warning_type, const void *repeat_key, const char
bool print_warning = true;
StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream();
- if (stream_sp.get() == nullptr)
+ if (!stream_sp)
return;
if (warning_type == eWarningsOptimization
- && GetWarningsOptimization() == false)
+ && !GetWarningsOptimization())
{
return;
}
@@ -6446,16 +6464,28 @@ Process::PrintWarning (uint64_t warning_type, const void *repeat_key, const char
void
Process::PrintWarningOptimization (const SymbolContext &sc)
{
- if (GetWarningsOptimization() == true
- && sc.module_sp.get()
- && sc.module_sp->GetFileSpec().GetFilename().IsEmpty() == false
+ if (GetWarningsOptimization()
+ && sc.module_sp
+ && !sc.module_sp->GetFileSpec().GetFilename().IsEmpty()
&& sc.function
- && sc.function->GetIsOptimized() == true)
+ && sc.function->GetIsOptimized())
{
PrintWarning (Process::Warnings::eWarningsOptimization, sc.module_sp.get(), "%s was compiled with optimization - stepping may behave oddly; variables may not be available.\n", sc.module_sp->GetFileSpec().GetFilename().GetCString());
}
}
+bool
+Process::GetProcessInfo(ProcessInstanceInfo &info)
+{
+ info.Clear();
+
+ PlatformSP platform_sp = GetTarget().GetPlatform();
+ if (! platform_sp)
+ return false;
+
+ return platform_sp->GetProcessInfo(GetID(), info);
+}
+
ThreadCollectionSP
Process::GetHistoryThreads(lldb::addr_t addr)
{
@@ -6463,7 +6493,7 @@ Process::GetHistoryThreads(lldb::addr_t addr)
const MemoryHistorySP &memory_history = MemoryHistory::FindPlugin(shared_from_this());
- if (! memory_history.get()) {
+ if (!memory_history) {
return threads;
}
@@ -6521,13 +6551,13 @@ Process::AdvanceAddressToNextBranchInstruction (Address default_stop_addr, Addre
{
Target &target = GetTarget();
DisassemblerSP disassembler_sp;
- InstructionList *insn_list = NULL;
+ InstructionList *insn_list = nullptr;
Address retval = default_stop_addr;
- if (target.GetUseFastStepping() == false)
+ if (!target.GetUseFastStepping())
return retval;
- if (default_stop_addr.IsValid() == false)
+ if (!default_stop_addr.IsValid())
return retval;
ExecutionContext exe_ctx (this);
@@ -6540,10 +6570,10 @@ Process::AdvanceAddressToNextBranchInstruction (Address default_stop_addr, Addre
exe_ctx,
range_bounds,
prefer_file_cache);
- if (disassembler_sp.get())
+ if (disassembler_sp)
insn_list = &disassembler_sp->GetInstructionList();
- if (insn_list == NULL)
+ if (insn_list == nullptr)
{
return retval;
}
@@ -6569,11 +6599,38 @@ Process::AdvanceAddressToNextBranchInstruction (Address default_stop_addr, Addre
}
}
- if (disassembler_sp.get())
+ return retval;
+}
+
+Error
+Process::GetMemoryRegions (std::vector<lldb::MemoryRegionInfoSP>& region_list)
+{
+
+ Error error;
+
+ lldb::addr_t range_base = 0;
+ lldb::addr_t range_end = 0;
+
+ region_list.clear();
+ do
{
- // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
- disassembler_sp->GetInstructionList().Clear();
- }
+ lldb::MemoryRegionInfoSP region_info( new lldb_private::MemoryRegionInfo() );
+ error = GetMemoryRegionInfo (range_end, *region_info);
+ // GetMemoryRegionInfo should only return an error if it is unimplemented.
+ if (error.Fail())
+ {
+ region_list.clear();
+ break;
+ }
+
+ range_base = region_info->GetRange().GetRangeBase();
+ range_end = region_info->GetRange().GetRangeEnd();
+ if( region_info->GetMapped() == MemoryRegionInfo::eYes )
+ {
+ region_list.push_back(region_info);
+ }
+ } while (range_end != LLDB_INVALID_ADDRESS);
+
+ return error;
- return retval;
}
diff --git a/source/Target/ProcessInfo.cpp b/source/Target/ProcessInfo.cpp
index 22da2c6a2a29..214db9ed3d45 100644
--- a/source/Target/ProcessInfo.cpp
+++ b/source/Target/ProcessInfo.cpp
@@ -7,10 +7,15 @@
//
//===----------------------------------------------------------------------===//
+// C Includes
+// C++ Includes
+#include <climits>
+
+// Other libraries and framework includes
+// Project includes
#include "lldb/Target/ProcessInfo.h"
-// C Includes
-#include <limits.h>
+#include "lldb/Core/Stream.h"
using namespace lldb;
using namespace lldb_private;
@@ -62,6 +67,21 @@ ProcessInfo::GetNameLength() const
}
void
+ProcessInfo::Dump (Stream &s, Platform *platform) const
+{
+ s << "Executable: " << GetName() << "\n";
+ s << "Triple: ";
+ m_arch.DumpTriple(s);
+ s << "\n";
+
+ s << "Arguments:\n";
+ m_arguments.Dump(s);
+
+ s << "Environment:\n";
+ m_environment.Dump(s, "env");
+}
+
+void
ProcessInfo::SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_first_arg)
{
if (exe_file)
@@ -83,9 +103,7 @@ ProcessInfo::SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_f
const char *
ProcessInfo::GetArg0 () const
{
- if (m_arg0.empty())
- return NULL;
- return m_arg0.c_str();
+ return (m_arg0.empty() ? nullptr : m_arg0.c_str());
}
void
@@ -116,6 +134,7 @@ ProcessInfo::SetArguments (char const **argv, bool first_arg_is_executable)
}
}
}
+
void
ProcessInfo::SetArguments (const Args& args, bool first_arg_is_executable)
{
diff --git a/source/Target/ProcessLaunchInfo.cpp b/source/Target/ProcessLaunchInfo.cpp
index fc17fe614c5c..f132450ca359 100644
--- a/source/Target/ProcessLaunchInfo.cpp
+++ b/source/Target/ProcessLaunchInfo.cpp
@@ -7,15 +7,23 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Host/Config.h"
+// C Includes
+// C++ Includes
+#include <climits>
+// Other libraries and framework includes
+// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
+#include "lldb/Host/Config.h"
#include "lldb/Host/FileSystem.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Target/FileAction.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/Target.h"
+#include "llvm/Support/ConvertUTF.h"
+
#if !defined(_WIN32)
#include <limits.h>
#endif
@@ -27,19 +35,19 @@ using namespace lldb_private;
// ProcessLaunchInfo member functions
//----------------------------------------------------------------------------
-ProcessLaunchInfo::ProcessLaunchInfo () :
+ProcessLaunchInfo::ProcessLaunchInfo() :
ProcessInfo(),
- m_working_dir (),
- m_plugin_name (),
- m_flags (0),
- m_file_actions (),
- m_pty (new lldb_utility::PseudoTerminal),
- m_resume_count (0),
- m_monitor_callback (NULL),
- m_monitor_callback_baton (NULL),
- m_monitor_signals (false),
- m_listener_sp (),
- m_hijack_listener_sp ()
+ m_working_dir(),
+ m_plugin_name(),
+ m_flags(0),
+ m_file_actions(),
+ m_pty(new lldb_utility::PseudoTerminal),
+ m_resume_count(0),
+ m_monitor_callback(nullptr),
+ m_monitor_callback_baton(nullptr),
+ m_monitor_signals(false),
+ m_listener_sp(),
+ m_hijack_listener_sp()
{
}
@@ -55,8 +63,8 @@ ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
m_file_actions(),
m_pty(new lldb_utility::PseudoTerminal),
m_resume_count(0),
- m_monitor_callback(NULL),
- m_monitor_callback_baton(NULL),
+ m_monitor_callback(nullptr),
+ m_monitor_callback_baton(nullptr),
m_monitor_signals(false),
m_listener_sp (),
m_hijack_listener_sp()
@@ -143,7 +151,7 @@ ProcessLaunchInfo::GetFileActionAtIndex(size_t idx) const
{
if (idx < m_file_actions.size())
return &m_file_actions[idx];
- return NULL;
+ return nullptr;
}
const FileAction *
@@ -154,7 +162,7 @@ ProcessLaunchInfo::GetFileActionForFD(int fd) const
if (m_file_actions[idx].GetFD () == fd)
return &m_file_actions[idx];
}
- return NULL;
+ return nullptr;
}
const FileSpec &
@@ -172,9 +180,7 @@ ProcessLaunchInfo::SetWorkingDirectory(const FileSpec &working_dir)
const char *
ProcessLaunchInfo::GetProcessPluginName () const
{
- if (m_plugin_name.empty())
- return NULL;
- return m_plugin_name.c_str();
+ return (m_plugin_name.empty() ? nullptr : m_plugin_name.c_str());
}
void
@@ -238,12 +244,9 @@ ProcessLaunchInfo::Clear ()
}
void
-ProcessLaunchInfo::SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback,
- void *baton,
- bool monitor_signals)
+ProcessLaunchInfo::SetMonitorProcessCallback(const Host::MonitorChildProcessCallback &callback, bool monitor_signals)
{
m_monitor_callback = callback;
- m_monitor_callback_baton = baton;
m_monitor_signals = monitor_signals;
}
@@ -253,7 +256,6 @@ ProcessLaunchInfo::MonitorProcess () const
if (m_monitor_callback && ProcessIDIsValid())
{
Host::StartMonitoringChildProcess (m_monitor_callback,
- m_monitor_callback_baton,
GetProcessID(),
m_monitor_signals);
return true;
@@ -277,9 +279,9 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty)
// If nothing for stdin or stdout or stderr was specified, then check the process for any default
// settings that were set with "settings set"
- if (GetFileActionForFD(STDIN_FILENO) == NULL ||
- GetFileActionForFD(STDOUT_FILENO) == NULL ||
- GetFileActionForFD(STDERR_FILENO) == NULL)
+ if (GetFileActionForFD(STDIN_FILENO) == nullptr ||
+ GetFileActionForFD(STDOUT_FILENO) == nullptr ||
+ GetFileActionForFD(STDERR_FILENO) == nullptr)
{
if (log)
log->Printf ("ProcessLaunchInfo::%s at least one of stdin/stdout/stderr was not set, evaluating default handling",
@@ -314,11 +316,11 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty)
{
// Only override with the target settings if we don't already have
// an action for in, out or error
- if (GetFileActionForFD(STDIN_FILENO) == NULL)
+ if (GetFileActionForFD(STDIN_FILENO) == nullptr)
in_file_spec = target->GetStandardInputPath();
- if (GetFileActionForFD(STDOUT_FILENO) == NULL)
+ if (GetFileActionForFD(STDOUT_FILENO) == nullptr)
out_file_spec = target->GetStandardOutputPath();
- if (GetFileActionForFD(STDERR_FILENO) == NULL)
+ if (GetFileActionForFD(STDERR_FILENO) == nullptr)
err_file_spec = target->GetStandardErrorPath();
}
@@ -366,27 +368,27 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty)
// this will have to do for now.
open_flags |= O_CLOEXEC;
#endif
- if (m_pty->OpenFirstAvailableMaster(open_flags, NULL, 0))
+ if (m_pty->OpenFirstAvailableMaster(open_flags, nullptr, 0))
{
- const FileSpec slave_file_spec{m_pty->GetSlaveName(NULL, 0), false};
+ const FileSpec slave_file_spec{m_pty->GetSlaveName(nullptr, 0), false};
// Only use the slave tty if we don't have anything specified for
// input and don't have an action for stdin
- if (!in_file_spec && GetFileActionForFD(STDIN_FILENO) == NULL)
+ if (!in_file_spec && GetFileActionForFD(STDIN_FILENO) == nullptr)
{
AppendOpenFileAction(STDIN_FILENO, slave_file_spec, true, false);
}
// Only use the slave tty if we don't have anything specified for
// output and don't have an action for stdout
- if (!out_file_spec && GetFileActionForFD(STDOUT_FILENO) == NULL)
+ if (!out_file_spec && GetFileActionForFD(STDOUT_FILENO) == nullptr)
{
AppendOpenFileAction(STDOUT_FILENO, slave_file_spec, false, true);
}
// Only use the slave tty if we don't have anything specified for
// error and don't have an action for stderr
- if (!err_file_spec && GetFileActionForFD(STDERR_FILENO) == NULL)
+ if (!err_file_spec && GetFileActionForFD(STDERR_FILENO) == nullptr)
{
AppendOpenFileAction(STDERR_FILENO, slave_file_spec, false, true);
}
@@ -396,7 +398,6 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty)
}
}
-
bool
ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error,
bool localhost,
@@ -413,7 +414,7 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error,
std::string shell_executable = m_shell.GetPath();
const char **argv = GetArguments().GetConstArgumentVector ();
- if (argv == NULL || argv[0] == NULL)
+ if (argv == nullptr || argv[0] == nullptr)
return false;
Args shell_arguments;
std::string safe_arg;
@@ -451,8 +452,8 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error,
if (cwd && cwd[0])
new_path += cwd;
}
- const char *curr_path = getenv("PATH");
- if (curr_path)
+ std::string curr_path;
+ if (HostInfo::GetEnvironmentVar("PATH", curr_path))
{
if (new_path.size() > empty_path_len)
new_path += ':';
@@ -496,9 +497,11 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error,
}
else
{
- for (size_t i=0; argv[i] != NULL; ++i)
+ for (size_t i=0; argv[i] != nullptr; ++i)
{
- const char *arg = Args::GetShellSafeArgument (argv[i], safe_arg);
+ const char *arg = Args::GetShellSafeArgument (m_shell,
+ argv[i],
+ safe_arg);
shell_command.Printf(" %s", arg);
}
}
@@ -519,11 +522,11 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error,
return false;
}
-Listener &
+ListenerSP
ProcessLaunchInfo::GetListenerForProcess (Debugger &debugger)
{
if (m_listener_sp)
- return *m_listener_sp;
+ return m_listener_sp;
else
return debugger.GetListener();
}
diff --git a/source/Target/Queue.cpp b/source/Target/Queue.cpp
index 7cfa6fa5582f..9d4032a29e6f 100644
--- a/source/Target/Queue.cpp
+++ b/source/Target/Queue.cpp
@@ -7,6 +7,10 @@
//
//===----------------------------------------------------------------------===//
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
#include "lldb/Target/Process.h"
#include "lldb/Target/Queue.h"
#include "lldb/Target/QueueList.h"
@@ -32,9 +36,7 @@ Queue::Queue (ProcessSP process_sp, lldb::queue_id_t queue_id, const char *queue
m_process_wp = process_sp;
}
-Queue::~Queue ()
-{
-}
+Queue::~Queue() = default;
queue_id_t
Queue::GetID ()
@@ -45,10 +47,7 @@ Queue::GetID ()
const char *
Queue::GetName ()
{
- const char *result = NULL;
- if (m_queue_name.size() > 0)
- result = m_queue_name.c_str();
- return result;
+ return (m_queue_name.empty() ? nullptr : m_queue_name.c_str());
}
uint32_t
@@ -62,7 +61,7 @@ Queue::GetThreads ()
{
std::vector<ThreadSP> result;
ProcessSP process_sp = m_process_wp.lock();
- if (process_sp.get ())
+ if (process_sp)
{
for (ThreadSP thread_sp : process_sp->Threads())
{
@@ -87,7 +86,6 @@ Queue::GetNumRunningWorkItems () const
return m_running_work_items_count;
}
-
void
Queue::SetNumPendingWorkItems (uint32_t count)
{
@@ -112,11 +110,10 @@ Queue::GetLibdispatchQueueAddress () const
return m_dispatch_queue_t_addr;
}
-
const std::vector<lldb::QueueItemSP> &
Queue::GetPendingItems ()
{
- if (m_pending_items.size() == 0)
+ if (m_pending_items.empty())
{
ProcessSP process_sp = m_process_wp.lock();
if (process_sp && process_sp->GetSystemRuntime())
diff --git a/source/Target/QueueList.cpp b/source/Target/QueueList.cpp
index 6134f5cc0b21..c63331db975a 100644
--- a/source/Target/QueueList.cpp
+++ b/source/Target/QueueList.cpp
@@ -14,11 +14,7 @@
using namespace lldb;
using namespace lldb_private;
-QueueList::QueueList (Process *process) :
- m_process (process),
- m_stop_id (0),
- m_queues (),
- m_mutex ()
+QueueList::QueueList(Process *process) : m_process(process), m_stop_id(0), m_queues(), m_mutex()
{
}
@@ -30,14 +26,14 @@ QueueList::~QueueList ()
uint32_t
QueueList::GetSize ()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
return m_queues.size();
}
lldb::QueueSP
QueueList::GetQueueAtIndex (uint32_t idx)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
if (idx < m_queues.size())
{
return m_queues[idx];
@@ -51,14 +47,14 @@ QueueList::GetQueueAtIndex (uint32_t idx)
void
QueueList::Clear ()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
m_queues.clear();
}
void
QueueList::AddQueue (QueueSP queue_sp)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
if (queue_sp.get ())
{
m_queues.push_back (queue_sp);
@@ -95,8 +91,8 @@ QueueList::FindQueueByIndexID (uint32_t index_id)
return ret;
}
-lldb_private::Mutex &
-QueueList::GetMutex ()
+std::mutex &
+QueueList::GetMutex()
{
return m_mutex;
}
diff --git a/source/Target/RegisterContext.cpp b/source/Target/RegisterContext.cpp
index afc815ba4a4e..483c932719d6 100644
--- a/source/Target/RegisterContext.cpp
+++ b/source/Target/RegisterContext.cpp
@@ -32,12 +32,7 @@ RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) :
{
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-RegisterContext::~RegisterContext()
-{
-}
+RegisterContext::~RegisterContext() = default;
void
RegisterContext::InvalidateIfNeeded (bool force)
@@ -61,7 +56,6 @@ RegisterContext::InvalidateIfNeeded (bool force)
}
}
-
const RegisterInfo *
RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx)
{
@@ -72,14 +66,14 @@ RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx
{
const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
- if ((reg_info->name != NULL && ::strcasecmp (reg_info->name, reg_name) == 0) ||
- (reg_info->alt_name != NULL && ::strcasecmp (reg_info->alt_name, reg_name) == 0))
+ if ((reg_info->name != nullptr && ::strcasecmp (reg_info->name, reg_name) == 0) ||
+ (reg_info->alt_name != nullptr && ::strcasecmp (reg_info->alt_name, reg_name) == 0))
{
return reg_info;
}
}
}
- return NULL;
+ return nullptr;
}
const RegisterInfo *
@@ -87,7 +81,7 @@ RegisterContext::GetRegisterInfo (lldb::RegisterKind kind, uint32_t num)
{
const uint32_t reg_num = ConvertRegisterKindToRegisterNumber(kind, num);
if (reg_num == LLDB_INVALID_REGNUM)
- return NULL;
+ return nullptr;
return GetRegisterInfoAtIndex (reg_num);
}
@@ -97,7 +91,7 @@ RegisterContext::GetRegisterName (uint32_t reg)
const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
if (reg_info)
return reg_info->name;
- return NULL;
+ return nullptr;
}
uint64_t
@@ -191,7 +185,6 @@ RegisterContext::GetFlags (uint64_t fail_value)
return ReadRegisterAsUnsigned (reg, fail_value);
}
-
uint64_t
RegisterContext::ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value)
{
@@ -297,7 +290,6 @@ RegisterContext::ClearHardwareBreakpoint (uint32_t hw_idx)
return false;
}
-
uint32_t
RegisterContext::NumSupportedHardwareWatchpoints ()
{
@@ -329,13 +321,12 @@ RegisterContext::ReadRegisterValueFromMemory (const RegisterInfo *reg_info,
RegisterValue &reg_value)
{
Error error;
- if (reg_info == NULL)
+ if (reg_info == nullptr)
{
error.SetErrorString ("invalid register info argument.");
return error;
}
-
// Moving from addr into a register
//
// Case 1: src_len == dst_len
@@ -408,7 +399,6 @@ RegisterContext::WriteRegisterValueToMemory (const RegisterInfo *reg_info,
uint32_t dst_len,
const RegisterValue &reg_value)
{
-
uint8_t dst[RegisterValue::kMaxRegisterByteSize];
Error error;
@@ -451,7 +441,6 @@ RegisterContext::WriteRegisterValueToMemory (const RegisterInfo *reg_info,
error.SetErrorString("invalid process");
return error;
-
}
bool
@@ -472,7 +461,6 @@ RegisterContext::CalculateTarget ()
return m_thread.CalculateTarget();
}
-
ProcessSP
RegisterContext::CalculateProcess ()
{
@@ -500,7 +488,6 @@ RegisterContext::CalculateExecutionContext (ExecutionContext &exe_ctx)
m_thread.CalculateExecutionContext (exe_ctx);
}
-
bool
RegisterContext::ConvertBetweenRegisterKinds (lldb::RegisterKind source_rk, uint32_t source_regnum, lldb::RegisterKind target_rk, uint32_t& target_regnum)
{
@@ -512,14 +499,7 @@ RegisterContext::ConvertBetweenRegisterKinds (lldb::RegisterKind source_rk, uint
if (reg_info->kinds[source_rk] == source_regnum)
{
target_regnum = reg_info->kinds[target_rk];
- if (target_regnum == LLDB_INVALID_REGNUM)
- {
- return false;
- }
- else
- {
- return true;
- }
+ return (target_regnum != LLDB_INVALID_REGNUM);
}
}
return false;
diff --git a/source/Target/SectionLoadHistory.cpp b/source/Target/SectionLoadHistory.cpp
index 1e5c4175a2bf..196d5b07db20 100644
--- a/source/Target/SectionLoadHistory.cpp
+++ b/source/Target/SectionLoadHistory.cpp
@@ -23,21 +23,21 @@ using namespace lldb_private;
bool
SectionLoadHistory::IsEmpty() const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_stop_id_to_section_load_list.empty();
}
void
SectionLoadHistory::Clear ()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_stop_id_to_section_load_list.clear();
}
uint32_t
SectionLoadHistory::GetLastStopID() const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_stop_id_to_section_load_list.empty())
return 0;
else
@@ -108,7 +108,7 @@ SectionLoadList &
SectionLoadHistory::GetCurrentSectionLoadList ()
{
const bool read_only = true;
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
SectionLoadList *section_load_list = GetSectionLoadListForStopID (eStopIDNow, read_only);
assert(section_load_list != NULL);
return *section_load_list;
@@ -117,7 +117,7 @@ SectionLoadHistory::GetCurrentSectionLoadList ()
addr_t
SectionLoadHistory::GetSectionLoadAddress (uint32_t stop_id, const lldb::SectionSP &section_sp)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const bool read_only = true;
SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only);
return section_load_list->GetSectionLoadAddress(section_sp);
@@ -127,7 +127,7 @@ bool
SectionLoadHistory::ResolveLoadAddress (uint32_t stop_id, addr_t load_addr, Address &so_addr)
{
// First find the top level section that this load address exists in
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const bool read_only = true;
SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only);
return section_load_list->ResolveLoadAddress (load_addr, so_addr);
@@ -139,7 +139,7 @@ SectionLoadHistory::SetSectionLoadAddress (uint32_t stop_id,
addr_t load_addr,
bool warn_multiple)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const bool read_only = false;
SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only);
return section_load_list->SetSectionLoadAddress(section_sp, load_addr, warn_multiple);
@@ -148,7 +148,7 @@ SectionLoadHistory::SetSectionLoadAddress (uint32_t stop_id,
size_t
SectionLoadHistory::SetSectionUnloaded (uint32_t stop_id, const lldb::SectionSP &section_sp)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const bool read_only = false;
SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only);
return section_load_list->SetSectionUnloaded (section_sp);
@@ -157,7 +157,7 @@ SectionLoadHistory::SetSectionUnloaded (uint32_t stop_id, const lldb::SectionSP
bool
SectionLoadHistory::SetSectionUnloaded (uint32_t stop_id, const lldb::SectionSP &section_sp, addr_t load_addr)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const bool read_only = false;
SectionLoadList *section_load_list = GetSectionLoadListForStopID (stop_id, read_only);
return section_load_list->SetSectionUnloaded (section_sp, load_addr);
@@ -166,7 +166,7 @@ SectionLoadHistory::SetSectionUnloaded (uint32_t stop_id, const lldb::SectionSP
void
SectionLoadHistory::Dump (Stream &s, Target *target)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
StopIDToSectionLoadList::iterator pos, end = m_stop_id_to_section_load_list.end();
for (pos = m_stop_id_to_section_load_list.begin(); pos != end; ++pos)
{
diff --git a/source/Target/SectionLoadList.cpp b/source/Target/SectionLoadList.cpp
index da3aea5034d1..1235a3795500 100644
--- a/source/Target/SectionLoadList.cpp
+++ b/source/Target/SectionLoadList.cpp
@@ -24,13 +24,9 @@
using namespace lldb;
using namespace lldb_private;
-
-SectionLoadList::SectionLoadList (const SectionLoadList& rhs) :
- m_addr_to_sect(),
- m_sect_to_addr(),
- m_mutex (Mutex::eMutexTypeRecursive)
+SectionLoadList::SectionLoadList(const SectionLoadList &rhs) : m_addr_to_sect(), m_sect_to_addr(), m_mutex()
{
- Mutex::Locker locker(rhs.m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(rhs.m_mutex);
m_addr_to_sect = rhs.m_addr_to_sect;
m_sect_to_addr = rhs.m_sect_to_addr;
}
@@ -38,8 +34,8 @@ SectionLoadList::SectionLoadList (const SectionLoadList& rhs) :
void
SectionLoadList::operator=(const SectionLoadList &rhs)
{
- Mutex::Locker lhs_locker (m_mutex);
- Mutex::Locker rhs_locker (rhs.m_mutex);
+ std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex);
m_addr_to_sect = rhs.m_addr_to_sect;
m_sect_to_addr = rhs.m_sect_to_addr;
}
@@ -47,14 +43,14 @@ SectionLoadList::operator=(const SectionLoadList &rhs)
bool
SectionLoadList::IsEmpty() const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_addr_to_sect.empty();
}
void
SectionLoadList::Clear ()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_addr_to_sect.clear();
m_sect_to_addr.clear();
}
@@ -66,7 +62,7 @@ SectionLoadList::GetSectionLoadAddress (const lldb::SectionSP &section) const
addr_t section_load_addr = LLDB_INVALID_ADDRESS;
if (section)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
sect_to_addr_collection::const_iterator pos = m_sect_to_addr.find (section.get());
if (pos != m_sect_to_addr.end())
@@ -98,7 +94,7 @@ SectionLoadList::SetSectionLoadAddress (const lldb::SectionSP &section, addr_t l
return false; // No change
// Fill in the section -> load_addr map
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section.get());
if (sta_pos != m_sect_to_addr.end())
{
@@ -172,14 +168,20 @@ SectionLoadList::SetSectionUnloaded (const lldb::SectionSP &section_sp)
if (log)
{
- const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec());
+ ModuleSP module_sp = section_sp->GetModule();
+ std::string module_name("<Unknown>");
+ if (module_sp)
+ {
+ const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec());
+ module_name = module_file_spec.GetPath();
+ }
log->Printf ("SectionLoadList::%s (section = %p (%s.%s))",
__FUNCTION__, static_cast<void*>(section_sp.get()),
- module_file_spec.GetPath().c_str(),
+ module_name.c_str(),
section_sp->GetName().AsCString());
}
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section_sp.get());
if (sta_pos != m_sect_to_addr.end())
@@ -203,14 +205,20 @@ SectionLoadList::SetSectionUnloaded (const lldb::SectionSP &section_sp, addr_t l
if (log)
{
- const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec());
+ ModuleSP module_sp = section_sp->GetModule();
+ std::string module_name("<Unknown>");
+ if (module_sp)
+ {
+ const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec());
+ module_name = module_file_spec.GetPath();
+ }
log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16" PRIx64 ")",
__FUNCTION__, static_cast<void*>(section_sp.get()),
- module_file_spec.GetPath().c_str(),
+ module_name.c_str(),
section_sp->GetName().AsCString(), load_addr);
}
bool erased = false;
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section_sp.get());
if (sta_pos != m_sect_to_addr.end())
{
@@ -232,8 +240,8 @@ SectionLoadList::SetSectionUnloaded (const lldb::SectionSP &section_sp, addr_t l
bool
SectionLoadList::ResolveLoadAddress (addr_t load_addr, Address &so_addr) const
{
- // First find the top level section that this load address exists in
- Mutex::Locker locker(m_mutex);
+ // First find the top level section that this load address exists in
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_addr_to_sect.empty())
{
addr_to_sect_collection::const_iterator pos = m_addr_to_sect.lower_bound (load_addr);
@@ -277,7 +285,7 @@ SectionLoadList::ResolveLoadAddress (addr_t load_addr, Address &so_addr) const
void
SectionLoadList::Dump (Stream &s, Target *target)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
addr_to_sect_collection::const_iterator pos, end;
for (pos = m_addr_to_sect.begin(), end = m_addr_to_sect.end(); pos != end; ++pos)
{
diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp
index e835521e7884..8488377158df 100644
--- a/source/Target/StackFrame.cpp
+++ b/source/Target/StackFrame.cpp
@@ -7,16 +7,16 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Target/StackFrame.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Module.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/FormatEntity.h"
+#include "lldb/Core/Mangled.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Core/ValueObjectConstResult.h"
@@ -44,135 +44,119 @@ using namespace lldb_private;
#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
#define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1)
-StackFrame::StackFrame (const ThreadSP &thread_sp,
- user_id_t frame_idx,
- user_id_t unwind_frame_index,
- addr_t cfa,
- bool cfa_is_valid,
- addr_t pc,
- uint32_t stop_id,
- bool stop_id_is_valid,
- bool is_history_frame,
- const SymbolContext *sc_ptr) :
- m_thread_wp (thread_sp),
- m_frame_index (frame_idx),
- m_concrete_frame_index (unwind_frame_index),
- m_reg_context_sp (),
- m_id (pc, cfa, NULL),
- m_frame_code_addr (pc),
- m_sc (),
- m_flags (),
- m_frame_base (),
- m_frame_base_error (),
- m_cfa_is_valid (cfa_is_valid),
- m_stop_id (stop_id),
- m_stop_id_is_valid (stop_id_is_valid),
- m_is_history_frame (is_history_frame),
- m_variable_list_sp (),
- m_variable_list_value_objects (),
- m_disassembly (),
- m_mutex (Mutex::eMutexTypeRecursive)
+StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, addr_t cfa,
+ bool cfa_is_valid, addr_t pc, uint32_t stop_id, bool stop_id_is_valid, bool is_history_frame,
+ const SymbolContext *sc_ptr)
+ : m_thread_wp(thread_sp),
+ m_frame_index(frame_idx),
+ m_concrete_frame_index(unwind_frame_index),
+ m_reg_context_sp(),
+ m_id(pc, cfa, nullptr),
+ m_frame_code_addr(pc),
+ m_sc(),
+ m_flags(),
+ m_frame_base(),
+ m_frame_base_error(),
+ m_cfa_is_valid(cfa_is_valid),
+ m_stop_id(stop_id),
+ m_stop_id_is_valid(stop_id_is_valid),
+ m_is_history_frame(is_history_frame),
+ m_variable_list_sp(),
+ m_variable_list_value_objects(),
+ m_disassembly(),
+ m_mutex()
{
// If we don't have a CFA value, use the frame index for our StackID so that recursive
// functions properly aren't confused with one another on a history stack.
- if (m_is_history_frame && m_cfa_is_valid == false)
+ if (m_is_history_frame && !m_cfa_is_valid)
{
- m_id.SetCFA (m_frame_index);
+ m_id.SetCFA(m_frame_index);
}
- if (sc_ptr != NULL)
+ if (sc_ptr != nullptr)
{
m_sc = *sc_ptr;
- m_flags.Set(m_sc.GetResolvedMask ());
+ m_flags.Set(m_sc.GetResolvedMask());
}
}
-StackFrame::StackFrame (const ThreadSP &thread_sp,
- user_id_t frame_idx,
- user_id_t unwind_frame_index,
- const RegisterContextSP &reg_context_sp,
- addr_t cfa,
- addr_t pc,
- const SymbolContext *sc_ptr) :
- m_thread_wp (thread_sp),
- m_frame_index (frame_idx),
- m_concrete_frame_index (unwind_frame_index),
- m_reg_context_sp (reg_context_sp),
- m_id (pc, cfa, NULL),
- m_frame_code_addr (pc),
- m_sc (),
- m_flags (),
- m_frame_base (),
- m_frame_base_error (),
- m_cfa_is_valid (true),
- m_stop_id (0),
- m_stop_id_is_valid (false),
- m_is_history_frame (false),
- m_variable_list_sp (),
- m_variable_list_value_objects (),
- m_disassembly (),
- m_mutex (Mutex::eMutexTypeRecursive)
+StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index,
+ const RegisterContextSP &reg_context_sp, addr_t cfa, addr_t pc, const SymbolContext *sc_ptr)
+ : m_thread_wp(thread_sp),
+ m_frame_index(frame_idx),
+ m_concrete_frame_index(unwind_frame_index),
+ m_reg_context_sp(reg_context_sp),
+ m_id(pc, cfa, nullptr),
+ m_frame_code_addr(pc),
+ m_sc(),
+ m_flags(),
+ m_frame_base(),
+ m_frame_base_error(),
+ m_cfa_is_valid(true),
+ m_stop_id(0),
+ m_stop_id_is_valid(false),
+ m_is_history_frame(false),
+ m_variable_list_sp(),
+ m_variable_list_value_objects(),
+ m_disassembly(),
+ m_mutex()
{
- if (sc_ptr != NULL)
+ if (sc_ptr != nullptr)
{
m_sc = *sc_ptr;
- m_flags.Set(m_sc.GetResolvedMask ());
+ m_flags.Set(m_sc.GetResolvedMask());
}
-
+
if (reg_context_sp && !m_sc.target_sp)
{
m_sc.target_sp = reg_context_sp->CalculateTarget();
if (m_sc.target_sp)
- m_flags.Set (eSymbolContextTarget);
+ m_flags.Set(eSymbolContextTarget);
}
}
-StackFrame::StackFrame (const ThreadSP &thread_sp,
- user_id_t frame_idx,
- user_id_t unwind_frame_index,
- const RegisterContextSP &reg_context_sp,
- addr_t cfa,
- const Address& pc_addr,
- const SymbolContext *sc_ptr) :
- m_thread_wp (thread_sp),
- m_frame_index (frame_idx),
- m_concrete_frame_index (unwind_frame_index),
- m_reg_context_sp (reg_context_sp),
- m_id (pc_addr.GetLoadAddress (thread_sp->CalculateTarget().get()), cfa, NULL),
- m_frame_code_addr (pc_addr),
- m_sc (),
- m_flags (),
- m_frame_base (),
- m_frame_base_error (),
- m_cfa_is_valid (true),
- m_stop_id (0),
- m_stop_id_is_valid (false),
- m_is_history_frame (false),
- m_variable_list_sp (),
- m_variable_list_value_objects (),
- m_disassembly (),
- m_mutex (Mutex::eMutexTypeRecursive)
+StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index,
+ const RegisterContextSP &reg_context_sp, addr_t cfa, const Address &pc_addr,
+ const SymbolContext *sc_ptr)
+ : m_thread_wp(thread_sp),
+ m_frame_index(frame_idx),
+ m_concrete_frame_index(unwind_frame_index),
+ m_reg_context_sp(reg_context_sp),
+ m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa, nullptr),
+ m_frame_code_addr(pc_addr),
+ m_sc(),
+ m_flags(),
+ m_frame_base(),
+ m_frame_base_error(),
+ m_cfa_is_valid(true),
+ m_stop_id(0),
+ m_stop_id_is_valid(false),
+ m_is_history_frame(false),
+ m_variable_list_sp(),
+ m_variable_list_value_objects(),
+ m_disassembly(),
+ m_mutex()
{
- if (sc_ptr != NULL)
+ if (sc_ptr != nullptr)
{
m_sc = *sc_ptr;
- m_flags.Set(m_sc.GetResolvedMask ());
+ m_flags.Set(m_sc.GetResolvedMask());
}
-
- if (m_sc.target_sp.get() == NULL && reg_context_sp)
+
+ if (!m_sc.target_sp && reg_context_sp)
{
m_sc.target_sp = reg_context_sp->CalculateTarget();
if (m_sc.target_sp)
- m_flags.Set (eSymbolContextTarget);
+ m_flags.Set(eSymbolContextTarget);
}
-
- ModuleSP pc_module_sp (pc_addr.GetModule());
+
+ ModuleSP pc_module_sp(pc_addr.GetModule());
if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp)
{
if (pc_module_sp)
{
m_sc.module_sp = pc_module_sp;
- m_flags.Set (eSymbolContextModule);
+ m_flags.Set(eSymbolContextModule);
}
else
{
@@ -181,18 +165,12 @@ StackFrame::StackFrame (const ThreadSP &thread_sp,
}
}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-StackFrame::~StackFrame()
-{
-}
+StackFrame::~StackFrame() = default;
StackID&
StackFrame::GetStackID()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Make sure we have resolved the StackID object's symbol context scope if
// we already haven't looked it up.
@@ -209,13 +187,13 @@ StackFrame::GetStackID()
// Calculate the frame block and use this for the stack ID symbol
// context scope if we have one.
SymbolContextScope *scope = GetFrameBlock ();
- if (scope == NULL)
+ if (scope == nullptr)
{
// We don't have a block, so use the symbol
if (m_flags.IsClear (eSymbolContextSymbol))
GetSymbolContext (eSymbolContextSymbol);
- // It is ok if m_sc.symbol is NULL here
+ // It is ok if m_sc.symbol is nullptr here
scope = m_sc.symbol;
}
// Set the symbol context scope (the accessor will set the
@@ -239,7 +217,7 @@ StackFrame::GetFrameIndex () const
void
StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
m_id.SetSymbolContextScope (symbol_scope);
}
@@ -247,7 +225,7 @@ StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
const Address&
StackFrame::GetFrameCodeAddress()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
{
m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
@@ -278,7 +256,7 @@ StackFrame::GetFrameCodeAddress()
bool
StackFrame::ChangePC (addr_t pc)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// We can't change the pc value of a history stack frame - it is immutable.
if (m_is_history_frame)
return false;
@@ -294,15 +272,15 @@ StackFrame::ChangePC (addr_t pc)
const char *
StackFrame::Disassemble ()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_disassembly.GetSize() == 0)
{
ExecutionContext exe_ctx (shared_from_this());
Target *target = exe_ctx.GetTargetPtr();
if (target)
{
- const char *plugin_name = NULL;
- const char *flavor = NULL;
+ const char *plugin_name = nullptr;
+ const char *flavor = nullptr;
Disassembler::Disassemble (target->GetDebugger(),
target->GetArchitecture(),
plugin_name,
@@ -314,7 +292,7 @@ StackFrame::Disassemble ()
m_disassembly);
}
if (m_disassembly.GetSize() == 0)
- return NULL;
+ return nullptr;
}
return m_disassembly.GetData();
}
@@ -322,7 +300,7 @@ StackFrame::Disassemble ()
Block *
StackFrame::GetFrameBlock ()
{
- if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock))
+ if (m_sc.block == nullptr && m_flags.IsClear(eSymbolContextBlock))
GetSymbolContext (eSymbolContextBlock);
if (m_sc.block)
@@ -342,7 +320,7 @@ StackFrame::GetFrameBlock ()
return &m_sc.function->GetBlock (false);
}
}
- return NULL;
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -354,7 +332,7 @@ StackFrame::GetFrameBlock ()
const SymbolContext&
StackFrame::GetSymbolContext (uint32_t resolve_scope)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Copy our internal symbol context into "sc".
if ((m_flags.Get() & resolve_scope) != resolve_scope)
{
@@ -368,7 +346,6 @@ StackFrame::GetSymbolContext (uint32_t resolve_scope)
resolved |= eSymbolContextTarget;
}
-
// Resolve our PC to section offset if we haven't already done so
// and if we don't have a module. The resolved address section will
// contain the module to which it belongs
@@ -411,7 +388,6 @@ StackFrame::GetSymbolContext (uint32_t resolve_scope)
}
}
-
if (m_sc.module_sp)
{
// We have something in our stack frame symbol context, lets check
@@ -487,25 +463,18 @@ StackFrame::GetSymbolContext (uint32_t resolve_scope)
// Only replace what we didn't already have as we may have
// information for an inlined function scope that won't match
// what a standard lookup by address would match
- if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL)
+ if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == nullptr)
m_sc.comp_unit = sc.comp_unit;
- if ((resolved & eSymbolContextFunction) && m_sc.function == NULL)
+ if ((resolved & eSymbolContextFunction) && m_sc.function == nullptr)
m_sc.function = sc.function;
- if ((resolved & eSymbolContextBlock) && m_sc.block == NULL)
+ if ((resolved & eSymbolContextBlock) && m_sc.block == nullptr)
m_sc.block = sc.block;
- if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL)
+ if ((resolved & eSymbolContextSymbol) && m_sc.symbol == nullptr)
m_sc.symbol = sc.symbol;
if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
{
m_sc.line_entry = sc.line_entry;
- if (m_sc.target_sp)
- {
- // Be sure to apply and file remappings to our file and line
- // entries when handing out a line entry
- FileSpec new_file_spec;
- if (m_sc.target_sp->GetSourcePathMap().FindFile (m_sc.line_entry.file, new_file_spec))
- m_sc.line_entry.file = new_file_spec;
- }
+ m_sc.line_entry.ApplyFileMappings(m_sc.target_sp);
}
}
}
@@ -533,11 +502,10 @@ StackFrame::GetSymbolContext (uint32_t resolve_scope)
return m_sc;
}
-
VariableList *
StackFrame::GetVariableList (bool get_file_globals)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_flags.IsClear(RESOLVED_VARIABLES))
{
m_flags.Set(RESOLVED_VARIABLES);
@@ -550,7 +518,11 @@ StackFrame::GetVariableList (bool get_file_globals)
const bool can_create = true;
const bool stop_if_child_block_is_inlined_function = true;
m_variable_list_sp.reset(new VariableList());
- frame_block->AppendBlockVariables(can_create, get_child_variables, stop_if_child_block_is_inlined_function, m_variable_list_sp.get());
+ frame_block->AppendBlockVariables(can_create,
+ get_child_variables,
+ stop_if_child_block_is_inlined_function,
+ [this](Variable* v) { return true; },
+ m_variable_list_sp.get());
}
}
@@ -576,9 +548,9 @@ StackFrame::GetVariableList (bool get_file_globals)
}
VariableListSP
-StackFrame::GetInScopeVariableList (bool get_file_globals)
+StackFrame::GetInScopeVariableList (bool get_file_globals, bool must_have_valid_location)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// We can't fetch variable information for a history stack frame.
if (m_is_history_frame)
return VariableListSP();
@@ -594,10 +566,14 @@ StackFrame::GetInScopeVariableList (bool get_file_globals)
m_sc.block->AppendVariables (can_create,
get_parent_variables,
stop_if_block_is_inlined_function,
+ [this, must_have_valid_location](Variable* v)
+ {
+ return v->IsInScope(this) && (!must_have_valid_location || v->LocationIsValidForFrame(this));
+ },
var_list_sp.get());
}
- if (m_sc.comp_unit)
+ if (m_sc.comp_unit && get_file_globals)
{
VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
if (global_variable_list_sp)
@@ -607,7 +583,6 @@ StackFrame::GetInScopeVariableList (bool get_file_globals)
return var_list_sp;
}
-
ValueObjectSP
StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
DynamicValueType use_dynamic,
@@ -736,7 +711,6 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
const char separator_type = var_path[0];
switch (separator_type)
{
-
case '-':
if (var_path.size() >= 2 && var_path[1] != '>')
return ValueObjectSP();
@@ -745,7 +719,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
{
// Make sure we aren't trying to deref an objective
// C ivar if this is not allowed
- const uint32_t pointer_type_flags = valobj_sp->GetCompilerType().GetTypeInfo (NULL);
+ const uint32_t pointer_type_flags = valobj_sp->GetCompilerType().GetTypeInfo(nullptr);
if ((pointer_type_flags & eTypeIsObjC) &&
(pointer_type_flags & eTypeIsPointer))
{
@@ -756,7 +730,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
}
}
var_path.erase (0, 1); // Remove the '-'
- // Fall through
+ LLVM_FALLTHROUGH;
case '.':
{
const bool expr_is_ptr = var_path[0] == '>';
@@ -800,7 +774,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
if (!child_valobj_sp)
{
- if (no_synth_child == false)
+ if (!no_synth_child)
{
child_valobj_sp = valobj_sp->GetSyntheticValue();
if (child_valobj_sp)
@@ -854,7 +828,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
// Array member access, or treating pointer as an array
if (var_path.size() > 2) // Need at least two brackets and a number
{
- char *end = NULL;
+ char *end = nullptr;
long child_index = ::strtol (&var_path[1], &end, 0);
if (end && *end == ']'
&& *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go
@@ -919,7 +893,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
{
// dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children
ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
- if (synthetic.get() == NULL /* no synthetic */
+ if (!synthetic /* no synthetic */
|| synthetic == valobj_sp) /* synthetic is the same as the original object */
{
valobj_sp->GetExpressionPath (var_expr_path_strm, false);
@@ -961,12 +935,12 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
}
}
}
- else if (valobj_sp->GetCompilerType().IsArrayType (NULL, NULL, &is_incomplete_array))
+ else if (valobj_sp->GetCompilerType().IsArrayType(nullptr, nullptr, &is_incomplete_array))
{
// Pass false to dynamic_value here so we can tell the difference between
// no dynamic value and no member of this type...
child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
- if (!child_valobj_sp && (is_incomplete_array || no_synth_child == false))
+ if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true);
if (!child_valobj_sp)
@@ -995,7 +969,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
{
ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
if (no_synth_child /* synthetic is forbidden */ ||
- synthetic.get() == NULL /* no synthetic */
+ !synthetic /* no synthetic */
|| synthetic == valobj_sp) /* synthetic is the same as the original object */
{
valobj_sp->GetExpressionPath (var_expr_path_strm, false);
@@ -1048,7 +1022,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
else if (end && *end == '-')
{
// this is most probably a BitField, let's take a look
- char *real_end = NULL;
+ char *real_end = nullptr;
long final_index = ::strtol (end+1, &real_end, 0);
bool expand_bitfield = true;
if (real_end && *real_end == ']')
@@ -1174,7 +1148,6 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
if (var_path.empty())
break;
-
}
if (valobj_sp)
{
@@ -1208,8 +1181,8 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
bool
StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
{
- Mutex::Locker locker(m_mutex);
- if (m_cfa_is_valid == false)
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (!m_cfa_is_valid)
{
m_frame_base_error.SetErrorString("No frame base available for this historical stack frame.");
return false;
@@ -1229,7 +1202,15 @@ StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
if (m_sc.function->GetFrameBaseExpression().IsLocationList())
loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr());
- if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false)
+ if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx,
+ nullptr,
+ nullptr,
+ nullptr,
+ loclist_base_addr,
+ nullptr,
+ nullptr,
+ expr_value,
+ &m_frame_base_error) == false)
{
// We should really have an error if evaluate returns, but in case
// we don't, lets set the error to something at least.
@@ -1258,7 +1239,7 @@ StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
RegisterContextSP
StackFrame::GetRegisterContext ()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_reg_context_sp)
{
ThreadSP thread_sp (GetThread());
@@ -1275,11 +1256,10 @@ StackFrame::HasDebugInformation ()
return m_sc.line_entry.IsValid();
}
-
ValueObjectSP
StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
ValueObjectSP valobj_sp;
if (m_is_history_frame)
{
@@ -1294,7 +1274,7 @@ StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, Dynam
if (var_idx < num_variables)
{
valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
- if (valobj_sp.get() == NULL)
+ if (!valobj_sp)
{
if (m_variable_list_value_objects.GetSize() < num_variables)
m_variable_list_value_objects.Resize(num_variables);
@@ -1315,7 +1295,7 @@ StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, Dynam
ValueObjectSP
StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_is_history_frame)
return ValueObjectSP();
@@ -1326,7 +1306,7 @@ StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType
// We aren't already tracking this global
VariableList *var_list = GetVariableList (true);
// If this frame has no variables, create a new list
- if (var_list == NULL)
+ if (var_list == nullptr)
m_variable_list_sp.reset (new VariableList());
// Add the global/static variable to this frame
@@ -1341,10 +1321,10 @@ StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType
bool
StackFrame::IsInlined ()
{
- if (m_sc.block == NULL)
+ if (m_sc.block == nullptr)
GetSymbolContext (eSymbolContextBlock);
if (m_sc.block)
- return m_sc.block->GetContainingInlinedBlock() != NULL;
+ return m_sc.block->GetContainingInlinedBlock() != nullptr;
return false;
}
@@ -1357,6 +1337,23 @@ StackFrame::GetLanguage ()
return lldb::eLanguageTypeUnknown;
}
+lldb::LanguageType
+StackFrame::GuessLanguage ()
+{
+ LanguageType lang_type = GetLanguage();
+
+ if (lang_type == eLanguageTypeUnknown)
+ {
+ Function *f = GetSymbolContext(eSymbolContextFunction).function;
+ if (f)
+ {
+ lang_type = f->GetMangled().GuessLanguage();
+ }
+ }
+
+ return lang_type;
+}
+
TargetSP
StackFrame::CalculateTarget ()
{
@@ -1393,7 +1390,6 @@ StackFrame::CalculateStackFrame ()
return shared_from_this();
}
-
void
StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx)
{
@@ -1403,7 +1399,7 @@ StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx)
void
StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker)
{
- if (strm == NULL)
+ if (strm == nullptr)
return;
GetSymbolContext(eSymbolContextEverything);
@@ -1413,11 +1409,11 @@ StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker)
if (frame_marker)
s.PutCString(frame_marker);
- const FormatEntity::Entry *frame_format = NULL;
+ const FormatEntity::Entry *frame_format = nullptr;
Target *target = exe_ctx.GetTargetPtr();
if (target)
frame_format = target->GetDebugger().GetFrameFormat();
- if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, NULL, NULL, false, false))
+ if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, nullptr, nullptr, false, false))
{
strm->Write(s.GetData(), s.GetSize());
}
@@ -1431,7 +1427,7 @@ StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker)
void
StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
{
- if (strm == NULL)
+ if (strm == nullptr)
return;
if (show_frame_index)
@@ -1459,19 +1455,18 @@ StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
void
StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing
m_variable_list_sp = prev_frame.m_variable_list_sp;
m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
if (!m_disassembly.GetString().empty())
m_disassembly.GetString().swap (m_disassembly.GetString());
}
-
void
StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing
m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value
assert (GetThread() == curr_frame.GetThread());
@@ -1479,10 +1474,10 @@ StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
m_concrete_frame_index = curr_frame.m_concrete_frame_index;
m_reg_context_sp = curr_frame.m_reg_context_sp;
m_frame_code_addr = curr_frame.m_frame_code_addr;
- assert (m_sc.target_sp.get() == NULL || curr_frame.m_sc.target_sp.get() == NULL || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
- assert (m_sc.module_sp.get() == NULL || curr_frame.m_sc.module_sp.get() == NULL || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
- assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
- assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function);
+ assert (!m_sc.target_sp || !curr_frame.m_sc.target_sp || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
+ assert (!m_sc.module_sp || !curr_frame.m_sc.module_sp || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
+ assert (m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
+ assert (m_sc.function == nullptr || curr_frame.m_sc.function == nullptr || m_sc.function == curr_frame.m_sc.function);
m_sc = curr_frame.m_sc;
m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
m_flags.Set (m_sc.GetResolvedMask());
@@ -1490,11 +1485,10 @@ StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
m_frame_base_error.Clear();
}
-
bool
StackFrame::HasCachedData () const
{
- if (m_variable_list_sp.get())
+ if (m_variable_list_sp)
return true;
if (m_variable_list_value_objects.GetSize() > 0)
return true;
@@ -1554,12 +1548,12 @@ StackFrame::GetStatus (Stream& strm,
case Debugger::eStopDisassemblyTypeNoDebugInfo:
if (have_debuginfo)
break;
- // Fall through to next case
+ LLVM_FALLTHROUGH;
case Debugger::eStopDisassemblyTypeNoSource:
if (have_source)
break;
- // Fall through to next case
+ LLVM_FALLTHROUGH;
case Debugger::eStopDisassemblyTypeAlways:
if (target)
@@ -1571,8 +1565,8 @@ StackFrame::GetStatus (Stream& strm,
AddressRange pc_range;
pc_range.GetBaseAddress() = GetFrameCodeAddress();
pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize());
- const char *plugin_name = NULL;
- const char *flavor = NULL;
+ const char *plugin_name = nullptr;
+ const char *flavor = nullptr;
Disassembler::Disassemble (target->GetDebugger(),
target_arch,
plugin_name,
@@ -1591,4 +1585,3 @@ StackFrame::GetStatus (Stream& strm,
}
return true;
}
-
diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp
index f2f3cad471fe..8304caf5710f 100644
--- a/source/Target/StackFrameList.cpp
+++ b/source/Target/StackFrameList.cpp
@@ -7,12 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Target/StackFrameList.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Target/StackFrameList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Core/Log.h"
@@ -37,32 +36,24 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// StackFrameList constructor
//----------------------------------------------------------------------
-StackFrameList::StackFrameList
-(
- Thread &thread,
- const lldb::StackFrameListSP &prev_frames_sp,
- bool show_inline_frames
-) :
- m_thread (thread),
- m_prev_frames_sp (prev_frames_sp),
- m_mutex (Mutex::eMutexTypeRecursive),
- m_frames (),
- m_selected_frame_idx (0),
- m_concrete_frames_fetched (0),
- m_current_inlined_depth (UINT32_MAX),
- m_current_inlined_pc (LLDB_INVALID_ADDRESS),
- m_show_inlined_frames (show_inline_frames)
+StackFrameList::StackFrameList(Thread &thread, const lldb::StackFrameListSP &prev_frames_sp, bool show_inline_frames)
+ : m_thread(thread),
+ m_prev_frames_sp(prev_frames_sp),
+ m_mutex(),
+ m_frames(),
+ m_selected_frame_idx(0),
+ m_concrete_frames_fetched(0),
+ m_current_inlined_depth(UINT32_MAX),
+ m_current_inlined_pc(LLDB_INVALID_ADDRESS),
+ m_show_inlined_frames(show_inline_frames)
{
if (prev_frames_sp)
{
m_current_inlined_depth = prev_frames_sp->m_current_inlined_depth;
- m_current_inlined_pc = prev_frames_sp->m_current_inlined_pc;
+ m_current_inlined_pc = prev_frames_sp->m_current_inlined_pc;
}
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
StackFrameList::~StackFrameList()
{
// Call clear since this takes a lock and clears the stack frame list
@@ -105,12 +96,12 @@ StackFrameList::GetCurrentInlinedDepth ()
void
StackFrameList::ResetCurrentInlinedDepth ()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_show_inlined_frames)
{
GetFramesUpTo(0);
- if (m_frames.size() == 0)
+ if (m_frames.empty())
return;
if (!m_frames[0]->IsInlined())
{
@@ -191,6 +182,7 @@ StackFrameList::ResetCurrentInlinedDepth ()
break;
}
}
+ LLVM_FALLTHROUGH;
default:
{
// Otherwise, we should set ourselves at the container of the inlining, so that the
@@ -199,7 +191,7 @@ StackFrameList::ResetCurrentInlinedDepth ()
int num_inlined_functions = 0;
for (Block *container_ptr = block_ptr->GetInlinedParent();
- container_ptr != NULL;
+ container_ptr != nullptr;
container_ptr = container_ptr->GetInlinedParent())
{
if (!container_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
@@ -258,7 +250,7 @@ void
StackFrameList::GetFramesUpTo(uint32_t end_idx)
{
// this makes sure we do not fetch frames for an invalid thread
- if (m_thread.IsValid() == false)
+ if (!m_thread.IsValid())
return;
// We've already gotten more frames than asked for, or we've already finished unwinding, return.
@@ -304,7 +296,6 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
if (reg_ctx_sp)
{
-
const bool success = unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
// There shouldn't be any way not to get the frame info for frame 0.
// But if the unwinder can't make one, lets make one by hand with the
@@ -315,13 +306,13 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
pc = reg_ctx_sp->GetPC();
}
- unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(),
- m_frames.size(),
- idx,
- reg_ctx_sp,
- cfa,
- pc,
- NULL));
+ unwind_frame_sp.reset(new StackFrame(m_thread.shared_from_this(),
+ m_frames.size(),
+ idx,
+ reg_ctx_sp,
+ cfa,
+ pc,
+ nullptr));
m_frames.push_back (unwind_frame_sp);
}
}
@@ -343,7 +334,8 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
const bool cfa_is_valid = true;
const bool stop_id_is_valid = false;
const bool is_history_frame = false;
- unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(), m_frames.size(), idx, cfa, cfa_is_valid, pc, 0, stop_id_is_valid, is_history_frame, NULL));
+ unwind_frame_sp.reset(new StackFrame(m_thread.shared_from_this(), m_frames.size(), idx, cfa, cfa_is_valid, pc,
+ 0, stop_id_is_valid, is_history_frame, nullptr));
m_frames.push_back (unwind_frame_sp);
}
@@ -353,6 +345,7 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
if (unwind_block)
{
Address curr_frame_address (unwind_frame_sp->GetFrameCodeAddress());
+ TargetSP target_sp = m_thread.CalculateTarget();
// Be sure to adjust the frame address to match the address
// that was used to lookup the symbol context above. If we are
// in the first concrete frame, then we lookup using the current
@@ -365,9 +358,8 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
// If curr_frame_address points to the first address in a section then after
// adjustment it will point to an other section. In that case resolve the
// address again to the correct section plus offset form.
- TargetSP target = m_thread.CalculateTarget();
- addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress(target.get(), eAddressClassCode);
- curr_frame_address.SetOpcodeLoadAddress(load_addr - 1, target.get(), eAddressClassCode);
+ addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress(target_sp.get(), eAddressClassCode);
+ curr_frame_address.SetOpcodeLoadAddress(load_addr - 1, target_sp.get(), eAddressClassCode);
}
else
{
@@ -380,17 +372,18 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
while (unwind_sc.GetParentOfInlinedScope(curr_frame_address, next_frame_sc, next_frame_address))
{
- StackFrameSP frame_sp(new StackFrame (m_thread.shared_from_this(),
- m_frames.size(),
- idx,
- unwind_frame_sp->GetRegisterContextSP (),
- cfa,
- next_frame_address,
- &next_frame_sc));
-
- m_frames.push_back (frame_sp);
- unwind_sc = next_frame_sc;
- curr_frame_address = next_frame_address;
+ next_frame_sc.line_entry.ApplyFileMappings(target_sp);
+ StackFrameSP frame_sp(new StackFrame(m_thread.shared_from_this(),
+ m_frames.size(),
+ idx,
+ unwind_frame_sp->GetRegisterContextSP (),
+ cfa,
+ next_frame_address,
+ &next_frame_sc));
+
+ m_frames.push_back (frame_sp);
+ unwind_sc = next_frame_sc;
+ curr_frame_address = next_frame_address;
}
}
} while (m_frames.size() - 1 < end_idx);
@@ -439,7 +432,7 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
StackFrame *curr_frame = curr_frame_sp.get();
StackFrame *prev_frame = prev_frame_sp.get();
- if (curr_frame == NULL || prev_frame == NULL)
+ if (curr_frame == nullptr || prev_frame == nullptr)
break;
// Check the stack ID to make sure they are equal
@@ -487,7 +480,7 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
uint32_t
StackFrameList::GetNumFrames (bool can_create)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (can_create)
GetFramesUpTo (UINT32_MAX);
@@ -502,9 +495,10 @@ StackFrameList::GetNumFrames (bool can_create)
void
StackFrameList::Dump (Stream *s)
{
- if (s == NULL)
+ if (s == nullptr)
return;
- Mutex::Locker locker (m_mutex);
+
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const_iterator pos, begin = m_frames.begin(), end = m_frames.end();
for (pos = begin; pos != end; ++pos)
@@ -527,7 +521,7 @@ StackFrameSP
StackFrameList::GetFrameAtIndex (uint32_t idx)
{
StackFrameSP frame_sp;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t original_idx = idx;
uint32_t inlined_depth = GetCurrentInlinedDepth();
@@ -562,7 +556,8 @@ StackFrameList::GetFrameAtIndex (uint32_t idx)
const bool cfa_is_valid = true;
const bool stop_id_is_valid = false;
const bool is_history_frame = false;
- frame_sp.reset (new StackFrame (m_thread.shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, 0, stop_id_is_valid, is_history_frame, NULL));
+ frame_sp.reset(new StackFrame(m_thread.shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, 0,
+ stop_id_is_valid, is_history_frame, nullptr));
Function *function = frame_sp->GetSymbolContext (eSymbolContextFunction).function;
if (function)
@@ -573,7 +568,7 @@ StackFrameList::GetFrameAtIndex (uint32_t idx)
}
else
{
- // Set the symbol scope from the symbol regardless if it is NULL or valid.
+ // Set the symbol scope from the symbol regardless if it is nullptr or valid.
frame_sp->SetSymbolContextScope (frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol);
}
SetFrameAtIndex(idx, frame_sp);
@@ -586,17 +581,16 @@ StackFrameList::GetFrameAtIndex (uint32_t idx)
// There should ALWAYS be a frame at index 0. If something went wrong with the CurrentInlinedDepth such that
// there weren't as many frames as we thought taking that into account, then reset the current inlined depth
// and return the real zeroth frame.
- if (m_frames.size() > 0)
- {
- ResetCurrentInlinedDepth();
- frame_sp = m_frames[original_idx];
- }
- else
+ if (m_frames.empty())
{
// Why do we have a thread with zero frames, that should not ever happen...
if (m_thread.IsValid())
assert ("A valid thread has no frames.");
-
+ }
+ else
+ {
+ ResetCurrentInlinedDepth();
+ frame_sp = m_frames[original_idx];
}
}
@@ -636,7 +630,7 @@ StackFrameList::GetFrameWithStackID (const StackID &stack_id)
if (stack_id.IsValid())
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t frame_idx = 0;
// Do a binary search in case the stack frame is already in our cache
collection::const_iterator begin = m_frames.begin();
@@ -682,15 +676,14 @@ StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp)
uint32_t
StackFrameList::GetSelectedFrameIndex () const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_selected_frame_idx;
}
-
uint32_t
StackFrameList::SetSelectedFrame (lldb_private::StackFrame *frame)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const_iterator pos;
const_iterator begin = m_frames.begin();
const_iterator end = m_frames.end();
@@ -714,7 +707,7 @@ StackFrameList::SetSelectedFrame (lldb_private::StackFrame *frame)
bool
StackFrameList::SetSelectedFrameByIndex (uint32_t idx)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
StackFrameSP frame_sp (GetFrameAtIndex (idx));
if (frame_sp)
{
@@ -746,7 +739,7 @@ StackFrameList::SetDefaultFileAndLineToSelectedFrame()
void
StackFrameList::Clear ()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_frames.clear();
m_concrete_frames_fetched = 0;
}
@@ -754,7 +747,7 @@ StackFrameList::Clear ()
void
StackFrameList::InvalidateFrames (uint32_t start_idx)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_show_inlined_frames)
{
Clear();
@@ -773,25 +766,28 @@ StackFrameList::InvalidateFrames (uint32_t start_idx)
void
StackFrameList::Merge (std::unique_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp)
{
- Mutex::Locker curr_locker (curr_ap.get() ? &curr_ap->m_mutex : NULL);
- Mutex::Locker prev_locker (prev_sp.get() ? &prev_sp->m_mutex : NULL);
+ std::unique_lock<std::recursive_mutex> current_lock, previous_lock;
+ if (curr_ap)
+ current_lock = std::unique_lock<std::recursive_mutex>(curr_ap->m_mutex);
+ if (prev_sp)
+ previous_lock = std::unique_lock<std::recursive_mutex>(prev_sp->m_mutex);
#if defined (DEBUG_STACK_FRAMES)
StreamFile s(stdout, false);
s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n");
- if (prev_sp.get())
+ if (prev_sp)
prev_sp->Dump (&s);
else
s.PutCString ("NULL");
s.PutCString("\nCurr:\n");
- if (curr_ap.get())
+ if (curr_ap)
curr_ap->Dump (&s);
else
s.PutCString ("NULL");
s.EOL();
#endif
- if (curr_ap.get() == NULL || curr_ap->GetNumFrames (false) == 0)
+ if (!curr_ap || curr_ap->GetNumFrames(false) == 0)
{
#if defined (DEBUG_STACK_FRAMES)
s.PutCString("No current frames, leave previous frames alone...\n");
@@ -800,7 +796,7 @@ StackFrameList::Merge (std::unique_ptr<StackFrameList>& curr_ap, lldb::StackFram
return;
}
- if (prev_sp.get() == NULL || prev_sp->GetNumFrames (false) == 0)
+ if (!prev_sp || prev_sp->GetNumFrames(false) == 0)
{
#if defined (DEBUG_STACK_FRAMES)
s.PutCString("No previous frames, so use current frames...\n");
@@ -866,8 +862,6 @@ StackFrameList::Merge (std::unique_ptr<StackFrameList>& curr_ap, lldb::StackFram
s.PutCString("\nMerged:\n");
prev_sp->Dump (&s);
#endif
-
-
}
lldb::StackFrameSP
@@ -913,7 +907,7 @@ StackFrameList::GetStatus (Stream& strm,
last_frame = first_frame + num_frames;
StackFrameSP selected_frame_sp = m_thread.GetSelectedFrame();
- const char *unselected_marker = NULL;
+ const char *unselected_marker = nullptr;
std::string buffer;
if (selected_frame_marker)
{
@@ -921,15 +915,15 @@ StackFrameList::GetStatus (Stream& strm,
buffer.insert(buffer.begin(), len, ' ');
unselected_marker = buffer.c_str();
}
- const char *marker = NULL;
+ const char *marker = nullptr;
for (frame_idx = first_frame; frame_idx < last_frame; ++frame_idx)
{
frame_sp = GetFrameAtIndex(frame_idx);
- if (frame_sp.get() == NULL)
+ if (!frame_sp)
break;
- if (selected_frame_marker != NULL)
+ if (selected_frame_marker != nullptr)
{
if (frame_sp == selected_frame_sp)
marker = selected_frame_marker;
@@ -947,4 +941,3 @@ StackFrameList::GetStatus (Stream& strm,
strm.IndentLess();
return num_frames_displayed;
}
-
diff --git a/source/Target/StackID.cpp b/source/Target/StackID.cpp
index ca337f914406..222b2d3f2aa8 100644
--- a/source/Target/StackID.cpp
+++ b/source/Target/StackID.cpp
@@ -7,12 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Target/StackID.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Target/StackID.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Symbol.h"
@@ -20,7 +19,6 @@
using namespace lldb_private;
-
void
StackID::Dump (Stream *s)
{
@@ -48,8 +46,8 @@ lldb_private::operator== (const StackID& lhs, const StackID& rhs)
SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope();
SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope();
- // Only compare the PC values if both symbol context scopes are NULL
- if (lhs_scope == NULL && rhs_scope == NULL)
+ // Only compare the PC values if both symbol context scopes are nullptr
+ if (lhs_scope == nullptr && rhs_scope == nullptr)
return lhs.GetPC() == rhs.GetPC();
return lhs_scope == rhs_scope;
@@ -64,7 +62,7 @@ lldb_private::operator!= (const StackID& lhs, const StackID& rhs)
SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope();
SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope();
- if (lhs_scope == NULL && rhs_scope == NULL)
+ if (lhs_scope == nullptr && rhs_scope == nullptr)
return lhs.GetPC() != rhs.GetPC();
return lhs_scope != rhs_scope;
@@ -88,7 +86,7 @@ lldb_private::operator< (const StackID& lhs, const StackID& rhs)
SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope();
SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope();
- if (lhs_scope != NULL && rhs_scope != NULL)
+ if (lhs_scope != nullptr && rhs_scope != nullptr)
{
// Same exact scope, lhs is not less than (younger than rhs)
if (lhs_scope == rhs_scope)
@@ -101,8 +99,8 @@ lldb_private::operator< (const StackID& lhs, const StackID& rhs)
// Items with the same function can only be compared
if (lhs_sc.function == rhs_sc.function &&
- lhs_sc.function != NULL && lhs_sc.block != NULL &&
- rhs_sc.function != NULL && rhs_sc.block != NULL)
+ lhs_sc.function != nullptr && lhs_sc.block != nullptr &&
+ rhs_sc.function != nullptr && rhs_sc.block != nullptr)
{
return rhs_sc.block->Contains (lhs_sc.block);
}
diff --git a/source/Target/StopInfo.cpp b/source/Target/StopInfo.cpp
index e88b6467f7c6..7c244363ffd2 100644
--- a/source/Target/StopInfo.cpp
+++ b/source/Target/StopInfo.cpp
@@ -228,7 +228,7 @@ public:
break;
}
}
- return all_internal == false;
+ return !all_internal;
}
}
return true;
@@ -254,7 +254,7 @@ public:
for (size_t idx = 0; idx < num_owners; idx++)
{
const char *kind = bp_site_sp->GetOwnerAtIndex(idx)->GetBreakpoint().GetBreakpointKind();
- if (kind != NULL)
+ if (kind != nullptr)
{
m_description.assign (kind);
return kind;
@@ -371,6 +371,10 @@ protected:
// running all the callbacks.
m_should_stop = false;
+
+ // We don't select threads as we go through them testing breakpoint conditions and running commands.
+ // So we need to set the thread for expression evaluation here:
+ ThreadList::ExpressionExecutionThreadPusher thread_pusher(thread_sp);
ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
Process *process = exe_ctx.GetProcessPtr();
@@ -467,7 +471,7 @@ protected:
// Next run the condition for the breakpoint. If that says we should stop, then we'll run
// the callback for the breakpoint. If the callback says we shouldn't stop that will win.
- if (bp_loc_sp->GetConditionText() != NULL)
+ if (bp_loc_sp->GetConditionText() != nullptr)
{
Error condition_error;
bool condition_says_stop = bp_loc_sp->ConditionSaysStop(exe_ctx, condition_error);
@@ -544,7 +548,6 @@ protected:
}
// We've figured out what this stop wants to do, so mark it as valid so we don't compute it again.
m_should_stop_is_valid = true;
-
}
else
{
@@ -733,7 +736,7 @@ protected:
new_plan_sp->SetOkayToDiscard (false);
new_plan_sp->SetPrivate (true);
process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
- process->ResumeSynchronous(NULL);
+ process->ResumeSynchronous(nullptr);
process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
thread_sp->SetStopInfo(stored_stop_info_sp);
}
@@ -769,7 +772,7 @@ protected:
if (wp_sp->GetHitCount() <= wp_sp->GetIgnoreCount())
m_should_stop = false;
- if (m_should_stop && wp_sp->GetConditionText() != NULL)
+ if (m_should_stop && wp_sp->GetConditionText() != nullptr)
{
// We need to make sure the user sees any parse errors in their condition, so we'll hook the
// constructor errors up to the debugger's Async I/O.
@@ -779,12 +782,12 @@ protected:
expr_options.SetIgnoreBreakpoints(true);
ValueObjectSP result_value_sp;
Error error;
- result_code = UserExpression::Evaluate (exe_ctx,
- expr_options,
- wp_sp->GetConditionText(),
- NULL,
- result_value_sp,
- error);
+ result_code = UserExpression::Evaluate(exe_ctx,
+ expr_options,
+ wp_sp->GetConditionText(),
+ nullptr,
+ result_value_sp,
+ error);
if (result_code == eExpressionCompleted)
{
@@ -951,7 +954,7 @@ public:
ThreadSP thread_sp (m_thread_wp.lock());
if (thread_sp)
{
- if (thread_sp->GetProcess()->GetUnixSignals()->GetShouldSuppress(m_value) == false)
+ if (!thread_sp->GetProcess()->GetUnixSignals()->GetShouldSuppress(m_value))
thread_sp->SetResumeSignal(m_value);
}
}
diff --git a/source/Target/SystemRuntime.cpp b/source/Target/SystemRuntime.cpp
index c3fb9c8091fd..522b535039ff 100644
--- a/source/Target/SystemRuntime.cpp
+++ b/source/Target/SystemRuntime.cpp
@@ -7,6 +7,10 @@
//
//===----------------------------------------------------------------------===//
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Process.h"
@@ -18,17 +22,16 @@ using namespace lldb_private;
SystemRuntime*
SystemRuntime::FindPlugin (Process *process)
{
- SystemRuntimeCreateInstance create_callback = NULL;
- for (uint32_t idx = 0; (create_callback = PluginManager::GetSystemRuntimeCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ SystemRuntimeCreateInstance create_callback = nullptr;
+ for (uint32_t idx = 0; (create_callback = PluginManager::GetSystemRuntimeCreateCallbackAtIndex(idx)) != nullptr; ++idx)
{
std::unique_ptr<SystemRuntime> instance_ap(create_callback(process));
- if (instance_ap.get())
+ if (instance_ap)
return instance_ap.release();
}
- return NULL;
+ return nullptr;
}
-
//----------------------------------------------------------------------
// SystemRuntime constructor
//----------------------------------------------------------------------
@@ -38,12 +41,7 @@ SystemRuntime::SystemRuntime(Process *process) :
{
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-SystemRuntime::~SystemRuntime()
-{
-}
+SystemRuntime::~SystemRuntime() = default;
void
SystemRuntime::DidAttach ()
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index 21e42916bae9..9ef56f01c659 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -9,6 +9,7 @@
// C Includes
// C++ Includes
+#include <mutex>
// Other libraries and framework includes
// Project includes
#include "lldb/Target/Target.h"
@@ -67,45 +68,47 @@ Target::GetStaticBroadcasterClass ()
return class_name;
}
-Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp, bool is_dummy_target) :
- TargetProperties (this),
- Broadcaster (&debugger, Target::GetStaticBroadcasterClass().AsCString()),
- ExecutionContextScope (),
- m_debugger (debugger),
- m_platform_sp (platform_sp),
- m_mutex (Mutex::eMutexTypeRecursive),
- m_arch (target_arch),
- m_images (this),
- m_section_load_history (),
- m_breakpoint_list (false),
- m_internal_breakpoint_list (true),
- m_watchpoint_list (),
- m_process_sp (),
- m_search_filter_sp (),
- m_image_search_paths (ImageSearchPathsChanged, this),
- m_ast_importer_sp (),
- m_source_manager_ap(),
- m_stop_hooks (),
- m_stop_hook_next_id (0),
- m_valid (true),
- m_suppress_stop_hooks (false),
- m_is_dummy_target(is_dummy_target)
-
-{
- SetEventName (eBroadcastBitBreakpointChanged, "breakpoint-changed");
- SetEventName (eBroadcastBitModulesLoaded, "modules-loaded");
- SetEventName (eBroadcastBitModulesUnloaded, "modules-unloaded");
- SetEventName (eBroadcastBitWatchpointChanged, "watchpoint-changed");
- SetEventName (eBroadcastBitSymbolsLoaded, "symbols-loaded");
+Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp,
+ bool is_dummy_target)
+ : TargetProperties(this),
+ Broadcaster(debugger.GetBroadcasterManager(), Target::GetStaticBroadcasterClass().AsCString()),
+ ExecutionContextScope(),
+ m_debugger(debugger),
+ m_platform_sp(platform_sp),
+ m_mutex(),
+ m_arch(target_arch),
+ m_images(this),
+ m_section_load_history(),
+ m_breakpoint_list(false),
+ m_internal_breakpoint_list(true),
+ m_watchpoint_list(),
+ m_process_sp(),
+ m_search_filter_sp(),
+ m_image_search_paths(ImageSearchPathsChanged, this),
+ m_ast_importer_sp(),
+ m_source_manager_ap(),
+ m_stop_hooks(),
+ m_stop_hook_next_id(0),
+ m_valid(true),
+ m_suppress_stop_hooks(false),
+ m_is_dummy_target(is_dummy_target)
+
+{
+ SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed");
+ SetEventName(eBroadcastBitModulesLoaded, "modules-loaded");
+ SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded");
+ SetEventName(eBroadcastBitWatchpointChanged, "watchpoint-changed");
+ SetEventName(eBroadcastBitSymbolsLoaded, "symbols-loaded");
CheckInWithManager();
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
if (log)
- log->Printf ("%p Target::Target()", static_cast<void*>(this));
+ log->Printf("%p Target::Target()", static_cast<void *>(this));
if (m_arch.IsValid())
{
- LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET, "Target::Target created with architecture %s (%s)", m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str());
+ LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET, "Target::Target created with architecture %s (%s)",
+ m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str());
}
}
@@ -168,8 +171,8 @@ Target::CleanupProcess ()
m_breakpoint_list.ClearAllBreakpointSites();
m_internal_breakpoint_list.ClearAllBreakpointSites();
// Disable watchpoints just on the debugger side.
- Mutex::Locker locker;
- this->GetWatchpointList().GetListMutex(locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ this->GetWatchpointList().GetListMutex(lock);
DisableAllWatchpoints(false);
ClearAllWatchpointHitCounts();
ClearAllWatchpointHistoricValues();
@@ -193,10 +196,10 @@ Target::DeleteCurrentProcess ()
}
const lldb::ProcessSP &
-Target::CreateProcess (Listener &listener, const char *plugin_name, const FileSpec *crash_file)
+Target::CreateProcess (ListenerSP listener_sp, const char *plugin_name, const FileSpec *crash_file)
{
DeleteCurrentProcess ();
- m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name, listener, crash_file);
+ m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name, listener_sp, crash_file);
return m_process_sp;
}
@@ -221,7 +224,7 @@ Target::GetREPL (Error &err, lldb::LanguageType language, const char *repl_optio
}
else if (repl_languages.size() == 0)
{
- err.SetErrorStringWithFormat("LLDB isn't configured with support support for any REPLs.");
+ err.SetErrorStringWithFormat("LLDB isn't configured with REPL support for any languages.");
return REPLSP();
}
else
@@ -272,7 +275,7 @@ Target::SetREPL (lldb::LanguageType language, lldb::REPLSP repl_sp)
void
Target::Destroy()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_valid = false;
DeleteCurrentProcess ();
m_platform_sp.reset();
@@ -325,6 +328,7 @@ Target::GetBreakpointByID (break_id_t break_id)
BreakpointSP
Target::CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
const FileSpecList *source_file_spec_list,
+ const std::unordered_set<std::string> &function_names,
RegularExpression &source_regex,
bool internal,
bool hardware,
@@ -333,7 +337,11 @@ Target::CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, source_file_spec_list));
if (move_to_nearest_code == eLazyBoolCalculate)
move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
- BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(nullptr, source_regex, !static_cast<bool>(move_to_nearest_code)));
+ BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(nullptr,
+ source_regex,
+ function_names,
+ !static_cast<bool>(move_to_nearest_code)));
+
return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
}
@@ -341,12 +349,20 @@ BreakpointSP
Target::CreateBreakpoint (const FileSpecList *containingModules,
const FileSpec &file,
uint32_t line_no,
+ lldb::addr_t offset,
LazyBool check_inlines,
LazyBool skip_prologue,
bool internal,
bool hardware,
LazyBool move_to_nearest_code)
{
+ FileSpec remapped_file;
+ ConstString remapped_path;
+ if (GetSourcePathMap().ReverseRemapPath(ConstString(file.GetPath().c_str()), remapped_path))
+ remapped_file.SetFile(remapped_path.AsCString(), true);
+ else
+ remapped_file = file;
+
if (check_inlines == eLazyBoolCalculate)
{
const InlineStrategy inline_strategy = GetInlineStrategy();
@@ -357,7 +373,7 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
break;
case eInlineBreakpointsHeaders:
- if (file.IsSourceImplementationFile())
+ if (remapped_file.IsSourceImplementationFile())
check_inlines = eLazyBoolNo;
else
check_inlines = eLazyBoolYes;
@@ -373,7 +389,7 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
{
// Not checking for inlines, we are looking only for matching compile units
FileSpecList compile_unit_list;
- compile_unit_list.Append (file);
+ compile_unit_list.Append (remapped_file);
filter_sp = GetSearchFilterForModuleAndCUList (containingModules, &compile_unit_list);
}
else
@@ -385,12 +401,13 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
if (move_to_nearest_code == eLazyBoolCalculate)
move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
- BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine(nullptr,
- file,
- line_no,
- check_inlines,
- skip_prologue,
- !static_cast<bool>(move_to_nearest_code)));
+ BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine (nullptr,
+ remapped_file,
+ line_no,
+ offset,
+ check_inlines,
+ skip_prologue,
+ !static_cast<bool>(move_to_nearest_code)));
return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
}
@@ -439,8 +456,9 @@ BreakpointSP
Target::CreateBreakpoint (const FileSpecList *containingModules,
const FileSpecList *containingSourceFiles,
const char *func_name,
- uint32_t func_name_type_mask,
+ uint32_t func_name_type_mask,
LanguageType language,
+ lldb::addr_t offset,
LazyBool skip_prologue,
bool internal,
bool hardware)
@@ -455,12 +473,13 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
if (language == lldb::eLanguageTypeUnknown)
language = GetLanguage();
- BreakpointResolverSP resolver_sp(new BreakpointResolverName(nullptr,
- func_name,
- func_name_type_mask,
- language,
- Breakpoint::Exact,
- skip_prologue));
+ BreakpointResolverSP resolver_sp (new BreakpointResolverName (nullptr,
+ func_name,
+ func_name_type_mask,
+ language,
+ Breakpoint::Exact,
+ offset,
+ skip_prologue));
bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
}
return bp_sp;
@@ -472,6 +491,7 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
const std::vector<std::string> &func_names,
uint32_t func_name_type_mask,
LanguageType language,
+ lldb::addr_t offset,
LazyBool skip_prologue,
bool internal,
bool hardware)
@@ -487,11 +507,13 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
if (language == lldb::eLanguageTypeUnknown)
language = GetLanguage();
- BreakpointResolverSP resolver_sp(new BreakpointResolverName(nullptr,
- func_names,
- func_name_type_mask,
- language,
- skip_prologue));
+
+ BreakpointResolverSP resolver_sp (new BreakpointResolverName (nullptr,
+ func_names,
+ func_name_type_mask,
+ language,
+ offset,
+ skip_prologue));
bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
}
return bp_sp;
@@ -502,8 +524,9 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
const FileSpecList *containingSourceFiles,
const char *func_names[],
size_t num_names,
- uint32_t func_name_type_mask,
+ uint32_t func_name_type_mask,
LanguageType language,
+ lldb::addr_t offset,
LazyBool skip_prologue,
bool internal,
bool hardware)
@@ -514,16 +537,23 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles));
if (skip_prologue == eLazyBoolCalculate)
- skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+ {
+ if (offset == 0)
+ skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+ else
+ skip_prologue = eLazyBoolNo;
+ }
if (language == lldb::eLanguageTypeUnknown)
language = GetLanguage();
- BreakpointResolverSP resolver_sp(new BreakpointResolverName(nullptr,
- func_names,
- num_names,
- func_name_type_mask,
- language,
- skip_prologue));
+ BreakpointResolverSP resolver_sp (new BreakpointResolverName (nullptr,
+ func_names,
+ num_names,
+ func_name_type_mask,
+ language,
+ offset,
+ skip_prologue));
+ resolver_sp->SetOffset(offset);
bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
}
return bp_sp;
@@ -602,10 +632,11 @@ Target::CreateFuncRegexBreakpoint (const FileSpecList *containingModules,
bool skip =
(skip_prologue == eLazyBoolCalculate) ? GetSkipPrologue()
: static_cast<bool>(skip_prologue);
- BreakpointResolverSP resolver_sp(new BreakpointResolverName(nullptr,
- func_regex,
- requested_language,
- skip));
+ BreakpointResolverSP resolver_sp(new BreakpointResolverName (nullptr,
+ func_regex,
+ requested_language,
+ 0,
+ skip));
return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
}
@@ -678,14 +709,13 @@ CheckIfWatchpointsExhausted(Target *target, Error &error)
{
uint32_t num_supported_hardware_watchpoints;
Error rc = target->GetProcessSP()->GetWatchpointSupportInfo(num_supported_hardware_watchpoints);
- if (rc.Success())
+ if (num_supported_hardware_watchpoints == 0)
{
- uint32_t num_current_watchpoints = target->GetWatchpointList().GetSize();
- if (num_current_watchpoints >= num_supported_hardware_watchpoints)
- error.SetErrorStringWithFormat("number of supported hardware watchpoints (%u) has been reached",
- num_supported_hardware_watchpoints);
+ error.SetErrorStringWithFormat ("Target supports (%u) hardware watchpoint slots.\n",
+ num_supported_hardware_watchpoints);
+ return false;
}
- return false;
+ return true;
}
// See also Watchpoint::SetWatchpointType(uint32_t type) and
@@ -719,13 +749,16 @@ Target::CreateWatchpoint(lldb::addr_t addr, size_t size, const CompilerType *typ
error.SetErrorStringWithFormat ("invalid watchpoint type: %d", kind);
}
+ if (!CheckIfWatchpointsExhausted (this, error))
+ return wp_sp;
+
// Currently we only support one watchpoint per address, with total number
// of watchpoints limited by the hardware which the inferior is running on.
// Grab the list mutex while doing operations.
const bool notify = false; // Don't notify about all the state changes we do on creating the watchpoint.
- Mutex::Locker locker;
- this->GetWatchpointList().GetListMutex(locker);
+ std::unique_lock<std::recursive_mutex> lock;
+ this->GetWatchpointList().GetListMutex(lock);
WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr);
if (matched_sp)
{
@@ -767,11 +800,9 @@ Target::CreateWatchpoint(lldb::addr_t addr, size_t size, const CompilerType *typ
// Remove the said watchpoint from the list maintained by the target instance.
m_watchpoint_list.Remove (wp_sp->GetID(), true);
// See if we could provide more helpful error message.
- if (!CheckIfWatchpointsExhausted(this, error))
- {
- if (!OptionGroupWatchpoint::IsWatchSizeSupported(size))
- error.SetErrorStringWithFormat("watch size of %" PRIu64 " is not supported", (uint64_t)size);
- }
+ if (!OptionGroupWatchpoint::IsWatchSizeSupported(size))
+ error.SetErrorStringWithFormat("watch size of %" PRIu64 " is not supported", (uint64_t)size);
+
wp_sp.reset();
}
else
@@ -1277,7 +1308,7 @@ Target::SetArchitecture (const ArchSpec &arch_spec)
os_ver_changed,
env_changed);
- if (!arch_changed && !vendor_changed && !os_changed)
+ if (!arch_changed && !vendor_changed && !os_changed && !env_changed)
replace_local_arch = false;
}
}
@@ -1941,7 +1972,7 @@ Target::CalculateTarget ()
ProcessSP
Target::CalculateProcess ()
{
- return ProcessSP();
+ return m_process_sp;
}
ThreadSP
@@ -2210,7 +2241,8 @@ ExpressionResults
Target::EvaluateExpression(const char *expr_cstr,
ExecutionContextScope *exe_scope,
lldb::ValueObjectSP &result_valobj_sp,
- const EvaluateExpressionOptions& options)
+ const EvaluateExpressionOptions& options,
+ std::string *fixed_expression)
{
result_valobj_sp.reset();
@@ -2260,7 +2292,9 @@ Target::EvaluateExpression(const char *expr_cstr,
expr_cstr,
prefix,
result_valobj_sp,
- error);
+ error,
+ 0, // Line Number
+ fixed_expression);
}
m_suppress_stop_hooks = old_suppress_value;
@@ -2579,11 +2613,11 @@ Target::GetSourceManager ()
ClangModulesDeclVendor *
Target::GetClangModulesDeclVendor ()
{
- static Mutex s_clang_modules_decl_vendor_mutex; // If this is contended we can make it per-target
-
+ static std::mutex s_clang_modules_decl_vendor_mutex; // If this is contended we can make it per-target
+
{
- Mutex::Locker clang_modules_decl_vendor_locker(s_clang_modules_decl_vendor_mutex);
-
+ std::lock_guard<std::mutex> guard(s_clang_modules_decl_vendor_mutex);
+
if (!m_clang_modules_decl_vendor_ap)
{
m_clang_modules_decl_vendor_ap.reset(ClangModulesDeclVendor::Create(*this));
@@ -2777,12 +2811,14 @@ Target::RunStopHooks ()
const TargetPropertiesSP &
Target::GetGlobalProperties()
{
- static TargetPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- {
- g_settings_sp.reset(new TargetProperties(nullptr));
- }
- return g_settings_sp;
+ // NOTE: intentional leak so we don't crash if global destructor chain gets
+ // called as other threads still use the result of this function
+ static TargetPropertiesSP *g_settings_sp_ptr = nullptr;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ g_settings_sp_ptr = new TargetPropertiesSP(new TargetProperties(nullptr));
+ });
+ return *g_settings_sp_ptr;
}
Error
@@ -2802,10 +2838,10 @@ Target::Install (ProcessLaunchInfo *launch_info)
const size_t num_images = modules.GetSize();
for (size_t idx = 0; idx < num_images; ++idx)
{
- const bool is_main_executable = idx == 0;
ModuleSP module_sp(modules.GetModuleAtIndex(idx));
if (module_sp)
{
+ const bool is_main_executable = module_sp == GetExecutableModule();
FileSpec local_file (module_sp->GetFileSpec());
if (local_file)
{
@@ -3062,12 +3098,12 @@ Target::Launch (ProcessLaunchInfo &launch_info, Stream *stream)
ListenerSP hijack_listener_sp (launch_info.GetHijackListener());
if (!hijack_listener_sp)
{
- hijack_listener_sp.reset(new Listener("lldb.Target.Launch.hijack"));
+ hijack_listener_sp = Listener::MakeListener("lldb.Target.Launch.hijack");
launch_info.SetHijackListener(hijack_listener_sp);
- m_process_sp->HijackProcessEvents(hijack_listener_sp.get());
+ m_process_sp->HijackProcessEvents(hijack_listener_sp);
}
- StateType state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, false, hijack_listener_sp.get(), nullptr);
+ StateType state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, false, hijack_listener_sp, nullptr);
if (state == eStateStopped)
{
@@ -3078,7 +3114,7 @@ Target::Launch (ProcessLaunchInfo &launch_info, Stream *stream)
error = m_process_sp->PrivateResume();
if (error.Success())
{
- state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, true, hijack_listener_sp.get(), stream);
+ state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, true, hijack_listener_sp, stream);
const bool must_be_alive = false; // eStateExited is ok, so this must be false
if (!StateIsStoppedState(state, must_be_alive))
{
@@ -3172,7 +3208,7 @@ Target::Attach (ProcessAttachInfo &attach_info, Stream *stream)
const bool async = attach_info.GetAsync();
if (!async)
{
- hijack_listener_sp.reset (new Listener ("lldb.Target.Attach.attach.hijack"));
+ hijack_listener_sp = Listener::MakeListener("lldb.Target.Attach.attach.hijack");
attach_info.SetHijackListener (hijack_listener_sp);
}
@@ -3195,7 +3231,7 @@ Target::Attach (ProcessAttachInfo &attach_info, Stream *stream)
}
}
if (hijack_listener_sp)
- process_sp->HijackProcessEvents (hijack_listener_sp.get ());
+ process_sp->HijackProcessEvents (hijack_listener_sp);
error = process_sp->Attach (attach_info);
}
@@ -3207,7 +3243,7 @@ Target::Attach (ProcessAttachInfo &attach_info, Stream *stream)
}
else
{
- state = process_sp->WaitForProcessToStop (nullptr, nullptr, false, attach_info.GetHijackListener ().get (), stream);
+ state = process_sp->WaitForProcessToStop (nullptr, nullptr, false, attach_info.GetHijackListener(), stream);
process_sp->RestoreProcessEvents ();
if (state != eStateStopped)
@@ -3363,6 +3399,15 @@ g_load_script_from_sym_file_values[] =
};
static OptionEnumValueElement
+g_load_current_working_dir_lldbinit_values[] =
+{
+ { eLoadCWDlldbinitTrue, "true", "Load .lldbinit files from current directory"},
+ { eLoadCWDlldbinitFalse, "false", "Do not load .lldbinit files from current directory"},
+ { eLoadCWDlldbinitWarn, "warn", "Warn about loading .lldbinit files from current directory"},
+ { 0, nullptr, nullptr }
+};
+
+static OptionEnumValueElement
g_memory_module_load_level_values[] =
{
{ eMemoryModuleLoadLevelMinimal, "minimal" , "Load minimal information when loading modules from memory. Currently this setting loads sections only."},
@@ -3389,7 +3434,9 @@ g_properties[] =
{ "exec-search-paths" , OptionValue::eTypeFileSpecList, false, 0 , nullptr, nullptr, "Executable search paths to use when locating executable files whose paths don't match the local file system." },
{ "debug-file-search-paths" , OptionValue::eTypeFileSpecList, false, 0 , nullptr, nullptr, "List of directories to be searched when locating debug symbol files." },
{ "clang-module-search-paths" , OptionValue::eTypeFileSpecList, false, 0 , nullptr, nullptr, "List of directories to be searched when locating modules for Clang." },
- { "auto-import-clang-modules" , OptionValue::eTypeBoolean , false, false , nullptr, nullptr, "Automatically load Clang modules referred to by the program." },
+ { "auto-import-clang-modules" , OptionValue::eTypeBoolean , false, true , nullptr, nullptr, "Automatically load Clang modules referred to by the program." },
+ { "auto-apply-fixits" , OptionValue::eTypeBoolean , false, true , nullptr, nullptr, "Automatically apply fix-it hints to expressions." },
+ { "notify-about-fixits" , OptionValue::eTypeBoolean , false, true , nullptr, nullptr, "Print the fixed expression text." },
{ "max-children-count" , OptionValue::eTypeSInt64 , false, 256 , nullptr, nullptr, "Maximum number of children to expand in any level of depth." },
{ "max-string-summary-length" , OptionValue::eTypeSInt64 , false, 1024 , nullptr, nullptr, "Maximum number of characters to show when using %s in summary strings." },
{ "max-memory-read-size" , OptionValue::eTypeSInt64 , false, 1024 , nullptr, nullptr, "Maximum number of bytes that 'memory read' will fetch before --force must be specified." },
@@ -3418,6 +3465,7 @@ g_properties[] =
{ "hex-immediate-style" , OptionValue::eTypeEnum , false, Disassembler::eHexStyleC, nullptr, g_hex_immediate_style_values, "Which style to use for printing hexadecimal disassembly values." },
{ "use-fast-stepping" , OptionValue::eTypeBoolean , false, true, nullptr, nullptr, "Use a fast stepping algorithm based on running from branch to branch rather than instruction single-stepping." },
{ "load-script-from-symbol-file" , OptionValue::eTypeEnum , false, eLoadScriptFromSymFileWarn, nullptr, g_load_script_from_sym_file_values, "Allow LLDB to load scripting resources embedded in symbol files when available." },
+ { "load-cwd-lldbinit" , OptionValue::eTypeEnum , false, eLoadCWDlldbinitWarn, nullptr, g_load_current_working_dir_lldbinit_values, "Allow LLDB to .lldbinit files from the current directory automatically." },
{ "memory-module-load-level" , OptionValue::eTypeEnum , false, eMemoryModuleLoadLevelComplete, nullptr, g_memory_module_load_level_values,
"Loading modules from memory can be slow as reading the symbol tables and other data can take a long time depending on your connection to the debug target. "
"This setting helps users control how much information gets loaded when loading modules from memory."
@@ -3445,6 +3493,8 @@ enum
ePropertyDebugFileSearchPaths,
ePropertyClangModuleSearchPaths,
ePropertyAutoImportClangModules,
+ ePropertyAutoApplyFixIts,
+ ePropertyNotifyAboutFixIts,
ePropertyMaxChildrenCount,
ePropertyMaxSummaryLength,
ePropertyMaxMemReadSize,
@@ -3465,11 +3515,13 @@ enum
ePropertyHexImmediateStyle,
ePropertyUseFastStepping,
ePropertyLoadScriptFromSymbolFile,
+ ePropertyLoadCWDlldbinitFile,
ePropertyMemoryModuleLoadLevel,
ePropertyDisplayExpressionsInCrashlogs,
ePropertyTrapHandlerNames,
ePropertyDisplayRuntimeSupportValues,
- ePropertyNonStopModeEnabled
+ ePropertyNonStopModeEnabled,
+ ePropertyExperimental
};
class TargetOptionValueProperties : public OptionValueProperties
@@ -3580,6 +3632,38 @@ protected:
//----------------------------------------------------------------------
// TargetProperties
//----------------------------------------------------------------------
+static PropertyDefinition
+g_experimental_properties[]
+{
+{ "inject-local-vars", OptionValue::eTypeBoolean , true, true, nullptr, nullptr, "If true, inject local variables explicitly into the expression text. "
+ "This will fix symbol resolution when there are name collisions between ivars and local variables. "
+ "But it can make expressions run much more slowly." },
+{ nullptr, OptionValue::eTypeInvalid , true, 0 , nullptr, nullptr, nullptr }
+};
+
+enum
+{
+ ePropertyInjectLocalVars = 0
+};
+
+class TargetExperimentalOptionValueProperties : public OptionValueProperties
+{
+public:
+ TargetExperimentalOptionValueProperties () :
+ OptionValueProperties (ConstString(Properties::GetExperimentalSettingsName()))
+ {
+ }
+};
+
+TargetExperimentalProperties::TargetExperimentalProperties() :
+ Properties(OptionValuePropertiesSP(new TargetExperimentalOptionValueProperties()))
+{
+ m_collection_sp->Initialize(g_experimental_properties);
+}
+
+//----------------------------------------------------------------------
+// TargetProperties
+//----------------------------------------------------------------------
TargetProperties::TargetProperties (Target *target) :
Properties (),
m_launch_info ()
@@ -3598,7 +3682,13 @@ TargetProperties::TargetProperties (Target *target) :
m_collection_sp->SetValueChangedCallback(ePropertyDetachOnError, TargetProperties::DetachOnErrorValueChangedCallback, this);
m_collection_sp->SetValueChangedCallback(ePropertyDisableASLR, TargetProperties::DisableASLRValueChangedCallback, this);
m_collection_sp->SetValueChangedCallback(ePropertyDisableSTDIO, TargetProperties::DisableSTDIOValueChangedCallback, this);
-
+
+ m_experimental_properties_up.reset(new TargetExperimentalProperties());
+ m_collection_sp->AppendProperty (ConstString(Properties::GetExperimentalSettingsName()),
+ ConstString("Experimental settings - setting these won't produce errors if the setting is not present."),
+ true,
+ m_experimental_properties_up->GetValueProperties());
+
// Update m_launch_info once it was created
Arg0ValueChangedCallback(this, nullptr);
RunArgsValueChangedCallback(this, nullptr);
@@ -3614,8 +3704,13 @@ TargetProperties::TargetProperties (Target *target) :
{
m_collection_sp.reset (new TargetOptionValueProperties(ConstString("target")));
m_collection_sp->Initialize(g_properties);
+ m_experimental_properties_up.reset(new TargetExperimentalProperties());
+ m_collection_sp->AppendProperty (ConstString(Properties::GetExperimentalSettingsName()),
+ ConstString("Experimental settings - setting these won't produce errors if the setting is not present."),
+ true,
+ m_experimental_properties_up->GetValueProperties());
m_collection_sp->AppendProperty(ConstString("process"),
- ConstString("Settings specify to processes."),
+ ConstString("Settings specific to processes."),
true,
Process::GetGlobalProperties()->GetValueProperties());
}
@@ -3623,6 +3718,26 @@ TargetProperties::TargetProperties (Target *target) :
TargetProperties::~TargetProperties() = default;
+bool
+TargetProperties::GetInjectLocalVariables(ExecutionContext *exe_ctx) const
+{
+ const Property *exp_property = m_collection_sp->GetPropertyAtIndex(exe_ctx, false, ePropertyExperimental);
+ OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties();
+ if (exp_values)
+ return exp_values->GetPropertyAtIndexAsBoolean(exe_ctx, ePropertyInjectLocalVars, true);
+ else
+ return true;
+}
+
+void
+TargetProperties::SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b)
+{
+ const Property *exp_property = m_collection_sp->GetPropertyAtIndex(exe_ctx, true, ePropertyExperimental);
+ OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties();
+ if (exp_values)
+ exp_values->SetPropertyAtIndexAsBoolean(exe_ctx, ePropertyInjectLocalVars, true);
+}
+
ArchSpec
TargetProperties::GetDefaultArchitecture () const
{
@@ -3817,6 +3932,20 @@ TargetProperties::GetEnableAutoImportClangModules() const
}
bool
+TargetProperties::GetEnableAutoApplyFixIts() const
+{
+ const uint32_t idx = ePropertyAutoApplyFixIts;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+}
+
+bool
+TargetProperties::GetEnableNotifyAboutFixIts() const
+{
+ const uint32_t idx = ePropertyNotifyAboutFixIts;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+}
+
+bool
TargetProperties::GetEnableSyntheticValue () const
{
const uint32_t idx = ePropertyEnableSynthetic;
@@ -3945,6 +4074,13 @@ TargetProperties::GetLoadScriptFromSymbolFile () const
return (LoadScriptFromSymFile)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
}
+LoadCWDlldbinitFile
+TargetProperties::GetLoadCWDlldbinitFile () const
+{
+ const uint32_t idx = ePropertyLoadCWDlldbinitFile;
+ return (LoadCWDlldbinitFile) m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
+}
+
Disassembler::HexImmediateStyle
TargetProperties::GetHexImmediateStyle () const
{
@@ -4147,6 +4283,12 @@ Target::TargetEventData::GetFlavorString ()
void
Target::TargetEventData::Dump (Stream *s) const
{
+ for (size_t i = 0; i < m_module_list.GetSize(); ++i)
+ {
+ if (i != 0)
+ *s << ", ";
+ m_module_list.GetModuleAtIndex(i)->GetDescription(s, lldb::eDescriptionLevelBrief);
+ }
}
const Target::TargetEventData *
diff --git a/source/Target/TargetList.cpp b/source/Target/TargetList.cpp
index ffec758ac215..349544676919 100644
--- a/source/Target/TargetList.cpp
+++ b/source/Target/TargetList.cpp
@@ -42,11 +42,11 @@ TargetList::GetStaticBroadcasterClass ()
//----------------------------------------------------------------------
// TargetList constructor
//----------------------------------------------------------------------
-TargetList::TargetList(Debugger &debugger) :
- Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()),
- m_target_list(),
- m_target_list_mutex (Mutex::eMutexTypeRecursive),
- m_selected_target_idx (0)
+TargetList::TargetList(Debugger &debugger)
+ : Broadcaster(debugger.GetBroadcasterManager(), TargetList::GetStaticBroadcasterClass().AsCString()),
+ m_target_list(),
+ m_target_list_mutex(),
+ m_selected_target_idx(0)
{
CheckInWithManager();
}
@@ -56,7 +56,7 @@ TargetList::TargetList(Debugger &debugger) :
//----------------------------------------------------------------------
TargetList::~TargetList()
{
- Mutex::Locker locker(m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
m_target_list.clear();
}
@@ -515,7 +515,7 @@ TargetList::CreateTargetInternal (Debugger &debugger,
// Don't put the dummy target in the target list, it's held separately.
if (!is_dummy_target)
{
- Mutex::Locker locker(m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
m_selected_target_idx = m_target_list.size();
m_target_list.push_back(target_sp);
// Now prime this from the dummy target:
@@ -533,7 +533,7 @@ TargetList::CreateTargetInternal (Debugger &debugger,
bool
TargetList::DeleteTarget (TargetSP &target_sp)
{
- Mutex::Locker locker(m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
collection::iterator pos, end = m_target_list.end();
for (pos = m_target_list.begin(); pos != end; ++pos)
@@ -551,7 +551,7 @@ TargetSP
TargetList::FindTargetWithExecutableAndArchitecture(const FileSpec &exe_file_spec,
const ArchSpec *exe_arch_ptr) const
{
- Mutex::Locker locker (m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
TargetSP target_sp;
bool full_match = (bool)exe_file_spec.GetDirectory();
@@ -580,7 +580,7 @@ TargetList::FindTargetWithExecutableAndArchitecture(const FileSpec &exe_file_spe
TargetSP
TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
{
- Mutex::Locker locker(m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
TargetSP target_sp;
collection::const_iterator pos, end = m_target_list.end();
for (pos = m_target_list.begin(); pos != end; ++pos)
@@ -601,7 +601,7 @@ TargetList::FindTargetWithProcess (Process *process) const
TargetSP target_sp;
if (process)
{
- Mutex::Locker locker(m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
collection::const_iterator pos, end = m_target_list.end();
for (pos = m_target_list.begin(); pos != end; ++pos)
{
@@ -621,7 +621,7 @@ TargetList::GetTargetSP (Target *target) const
TargetSP target_sp;
if (target)
{
- Mutex::Locker locker(m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
collection::const_iterator pos, end = m_target_list.end();
for (pos = m_target_list.begin(); pos != end; ++pos)
{
@@ -671,7 +671,7 @@ TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
if (pid == LLDB_INVALID_PROCESS_ID)
{
// Signal all processes with signal
- Mutex::Locker locker(m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
collection::iterator pos, end = m_target_list.end();
for (pos = m_target_list.begin(); pos != end; ++pos)
{
@@ -709,7 +709,7 @@ TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
int
TargetList::GetNumTargets () const
{
- Mutex::Locker locker (m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
return m_target_list.size();
}
@@ -717,7 +717,7 @@ lldb::TargetSP
TargetList::GetTargetAtIndex (uint32_t idx) const
{
TargetSP target_sp;
- Mutex::Locker locker (m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
if (idx < m_target_list.size())
target_sp = m_target_list[idx];
return target_sp;
@@ -726,7 +726,7 @@ TargetList::GetTargetAtIndex (uint32_t idx) const
uint32_t
TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const
{
- Mutex::Locker locker (m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
size_t num_targets = m_target_list.size();
for (size_t idx = 0; idx < num_targets; idx++)
{
@@ -739,7 +739,7 @@ TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const
uint32_t
TargetList::SetSelectedTarget (Target* target)
{
- Mutex::Locker locker (m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
collection::const_iterator pos,
begin = m_target_list.begin(),
end = m_target_list.end();
@@ -758,7 +758,7 @@ TargetList::SetSelectedTarget (Target* target)
lldb::TargetSP
TargetList::GetSelectedTarget ()
{
- Mutex::Locker locker (m_target_list_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
if (m_selected_target_idx >= m_target_list.size())
m_selected_target_idx = 0;
return GetTargetAtIndex (m_selected_target_idx);
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 551e48000936..40c137c4d521 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -58,10 +58,14 @@ using namespace lldb_private;
const ThreadPropertiesSP &
Thread::GetGlobalProperties()
{
- static ThreadPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset (new ThreadProperties (true));
- return g_settings_sp;
+ // NOTE: intentional leak so we don't crash if global destructor chain gets
+ // called as other threads still use the result of this function
+ static ThreadPropertiesSP *g_settings_sp_ptr = nullptr;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ g_settings_sp_ptr = new ThreadPropertiesSP(new ThreadProperties (true));
+ });
+ return *g_settings_sp_ptr;
}
static PropertyDefinition
@@ -266,36 +270,36 @@ Thread::GetStaticBroadcasterClass ()
return class_name;
}
-Thread::Thread (Process &process, lldb::tid_t tid, bool use_invalid_index_id) :
- ThreadProperties (false),
- UserID (tid),
- Broadcaster(&process.GetTarget().GetDebugger(), Thread::GetStaticBroadcasterClass().AsCString()),
- m_process_wp (process.shared_from_this()),
- m_stop_info_sp (),
- m_stop_info_stop_id (0),
- m_stop_info_override_stop_id (0),
- m_index_id (use_invalid_index_id ? LLDB_INVALID_INDEX32 : process.GetNextThreadIndexID(tid)),
- m_reg_context_sp (),
- m_state (eStateUnloaded),
- m_state_mutex (Mutex::eMutexTypeRecursive),
- m_plan_stack (),
- m_completed_plan_stack(),
- m_frame_mutex (Mutex::eMutexTypeRecursive),
- m_curr_frames_sp (),
- m_prev_frames_sp (),
- m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
- m_resume_state (eStateRunning),
- m_temporary_resume_state (eStateRunning),
- m_unwinder_ap (),
- m_destroy_called (false),
- m_override_should_notify (eLazyBoolCalculate),
- m_extended_info_fetched (false),
- m_extended_info ()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+Thread::Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id)
+ : ThreadProperties(false),
+ UserID(tid),
+ Broadcaster(process.GetTarget().GetDebugger().GetBroadcasterManager(),
+ Thread::GetStaticBroadcasterClass().AsCString()),
+ m_process_wp(process.shared_from_this()),
+ m_stop_info_sp(),
+ m_stop_info_stop_id(0),
+ m_stop_info_override_stop_id(0),
+ m_index_id(use_invalid_index_id ? LLDB_INVALID_INDEX32 : process.GetNextThreadIndexID(tid)),
+ m_reg_context_sp(),
+ m_state(eStateUnloaded),
+ m_state_mutex(),
+ m_plan_stack(),
+ m_completed_plan_stack(),
+ m_frame_mutex(),
+ m_curr_frames_sp(),
+ m_prev_frames_sp(),
+ m_resume_signal(LLDB_INVALID_SIGNAL_NUMBER),
+ m_resume_state(eStateRunning),
+ m_temporary_resume_state(eStateRunning),
+ m_unwinder_ap(),
+ m_destroy_called(false),
+ m_override_should_notify(eLazyBoolCalculate),
+ m_extended_info_fetched(false),
+ m_extended_info()
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
if (log)
- log->Printf ("%p Thread::Thread(tid = 0x%4.4" PRIx64 ")",
- static_cast<void*>(this), GetID());
+ log->Printf("%p Thread::Thread(tid = 0x%4.4" PRIx64 ")", static_cast<void *>(this), GetID());
CheckInWithManager();
QueueFundamentalPlan(true);
@@ -340,7 +344,7 @@ Thread::DestroyThread ()
m_stop_info_sp.reset();
m_reg_context_sp.reset();
m_unwinder_ap.reset();
- Mutex::Locker locker(m_frame_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);
m_curr_frames_sp.reset();
m_prev_frames_sp.reset();
}
@@ -640,14 +644,14 @@ StateType
Thread::GetState() const
{
// If any other threads access this we will need a mutex for it
- Mutex::Locker locker(m_state_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
return m_state;
}
void
Thread::SetState(StateType state)
{
- Mutex::Locker locker(m_state_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
m_state = state;
}
@@ -701,7 +705,6 @@ Thread::SetupForResume ()
ThreadPlanSP step_bp_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
if (step_bp_plan_sp)
{
- ;
step_bp_plan_sp->SetPrivate (true);
if (GetCurrentPlan()->RunState() != eStateStepping)
@@ -1819,7 +1822,7 @@ StackFrameListSP
Thread::GetStackFrameList ()
{
StackFrameListSP frame_list_sp;
- Mutex::Locker locker(m_frame_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);
if (m_curr_frames_sp)
{
frame_list_sp = m_curr_frames_sp;
@@ -1835,7 +1838,7 @@ Thread::GetStackFrameList ()
void
Thread::ClearStackFrames ()
{
- Mutex::Locker locker(m_frame_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);
Unwind *unwinder = GetUnwinder ();
if (unwinder)
@@ -2087,13 +2090,13 @@ Thread::GetThreadPointer ()
}
addr_t
-Thread::GetThreadLocalData (const ModuleSP module)
+Thread::GetThreadLocalData(const ModuleSP module, lldb::addr_t tls_file_addr)
{
// The default implementation is to ask the dynamic loader for it.
// This can be overridden for specific platforms.
DynamicLoader *loader = GetProcess()->GetDynamicLoader();
if (loader)
- return loader->GetThreadLocalData (module, shared_from_this());
+ return loader->GetThreadLocalData(module, shared_from_this(), tls_file_addr);
else
return LLDB_INVALID_ADDRESS;
}
@@ -2336,6 +2339,7 @@ Thread::GetUnwinder ()
case llvm::Triple::mips64el:
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
+ case llvm::Triple::systemz:
case llvm::Triple::hexagon:
m_unwinder_ap.reset (new UnwindLLDB (*this));
break;
diff --git a/source/Target/ThreadCollection.cpp b/source/Target/ThreadCollection.cpp
index dc1e38e02420..d8d622e9387a 100644
--- a/source/Target/ThreadCollection.cpp
+++ b/source/Target/ThreadCollection.cpp
@@ -9,8 +9,10 @@
#include <stdlib.h>
#include <algorithm>
+#include <mutex>
#include "lldb/Target/ThreadCollection.h"
+#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
@@ -30,14 +32,32 @@ ThreadCollection::ThreadCollection(collection threads) :
void
ThreadCollection::AddThread (const ThreadSP &thread_sp)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
m_threads.push_back (thread_sp);
}
void
+ThreadCollection::AddThreadSortedByIndexID (const ThreadSP &thread_sp)
+{
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
+ // Make sure we always keep the threads sorted by thread index ID
+ const uint32_t thread_index_id = thread_sp->GetIndexID();
+ if (m_threads.empty() || m_threads.back()->GetIndexID() < thread_index_id)
+ m_threads.push_back (thread_sp);
+ else
+ {
+ m_threads.insert(std::upper_bound(m_threads.begin(), m_threads.end(), thread_sp,
+ [] (const ThreadSP &lhs, const ThreadSP &rhs) -> bool
+ {
+ return lhs->GetIndexID() < rhs->GetIndexID();
+ }), thread_sp);
+ }
+}
+
+void
ThreadCollection::InsertThread (const lldb::ThreadSP &thread_sp, uint32_t idx)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
if (idx < m_threads.size())
m_threads.insert(m_threads.begin() + idx, thread_sp);
else
@@ -47,14 +67,14 @@ ThreadCollection::InsertThread (const lldb::ThreadSP &thread_sp, uint32_t idx)
uint32_t
ThreadCollection::GetSize ()
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
return m_threads.size();
}
ThreadSP
ThreadCollection::GetThreadAtIndex (uint32_t idx)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
ThreadSP thread_sp;
if (idx < m_threads.size())
thread_sp = m_threads[idx];
diff --git a/source/Target/ThreadList.cpp b/source/Target/ThreadList.cpp
index a34cb0fa143a..23e9f7807321 100644
--- a/source/Target/ThreadList.cpp
+++ b/source/Target/ThreadList.cpp
@@ -53,7 +53,8 @@ ThreadList::operator = (const ThreadList& rhs)
{
// Lock both mutexes to make sure neither side changes anyone on us
// while the assignment occurs
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
+
m_process = rhs.m_process;
m_stop_id = rhs.m_stop_id;
m_threads = rhs.m_threads;
@@ -71,6 +72,30 @@ ThreadList::~ThreadList()
Clear();
}
+lldb::ThreadSP
+ThreadList::GetExpressionExecutionThread()
+{
+ if (m_expression_tid_stack.empty())
+ return GetSelectedThread();
+ ThreadSP expr_thread_sp = FindThreadByID(m_expression_tid_stack.back());
+ if (expr_thread_sp)
+ return expr_thread_sp;
+ else
+ return GetSelectedThread();
+}
+
+void
+ThreadList::PushExpressionExecutionThread(lldb::tid_t tid)
+{
+ m_expression_tid_stack.push_back(tid);
+}
+
+void
+ThreadList::PopExpressionExecutionThread(lldb::tid_t tid)
+{
+ assert(m_expression_tid_stack.back() == tid);
+ m_expression_tid_stack.pop_back();
+}
uint32_t
ThreadList::GetStopID () const
@@ -87,7 +112,8 @@ ThreadList::SetStopID (uint32_t stop_id)
uint32_t
ThreadList::GetSize (bool can_update)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
+
if (can_update)
m_process->UpdateThreadListIfNeeded();
return m_threads.size();
@@ -96,7 +122,8 @@ ThreadList::GetSize (bool can_update)
ThreadSP
ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
+
if (can_update)
m_process->UpdateThreadListIfNeeded();
@@ -109,7 +136,7 @@ ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update)
ThreadSP
ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
if (can_update)
m_process->UpdateThreadListIfNeeded();
@@ -131,8 +158,8 @@ ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update)
ThreadSP
ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update)
{
- Mutex::Locker locker(GetMutex());
-
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
+
if (can_update)
m_process->UpdateThreadListIfNeeded();
@@ -154,8 +181,8 @@ ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update)
ThreadSP
ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update)
{
- Mutex::Locker locker(GetMutex());
-
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
+
if (can_update)
m_process->UpdateThreadListIfNeeded();
@@ -177,8 +204,8 @@ ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update)
ThreadSP
ThreadList::RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update)
{
- Mutex::Locker locker(GetMutex());
-
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
+
if (can_update)
m_process->UpdateThreadListIfNeeded();
@@ -203,7 +230,7 @@ ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
ThreadSP thread_sp;
if (thread_ptr)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
uint32_t idx = 0;
const uint32_t num_threads = m_threads.size();
@@ -224,7 +251,7 @@ ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
ThreadSP
ThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
if (can_update)
m_process->UpdateThreadListIfNeeded();
@@ -260,7 +287,7 @@ ThreadList::ShouldStop (Event *event_ptr)
collection threads_copy;
{
// Scope for locker
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
m_process->UpdateThreadListIfNeeded();
for (lldb::ThreadSP thread_sp : m_threads)
@@ -371,7 +398,7 @@ ThreadList::ShouldStop (Event *event_ptr)
Vote
ThreadList::ShouldReportStop (Event *event_ptr)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
Vote result = eVoteNoOpinion;
m_process->UpdateThreadListIfNeeded();
@@ -422,7 +449,8 @@ ThreadList::ShouldReportStop (Event *event_ptr)
void
ThreadList::SetShouldReportStop (Vote vote)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
+
m_process->UpdateThreadListIfNeeded();
collection::iterator pos, end = m_threads.end();
for (pos = m_threads.begin(); pos != end; ++pos)
@@ -436,7 +464,7 @@ Vote
ThreadList::ShouldReportRun (Event *event_ptr)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
Vote result = eVoteNoOpinion;
m_process->UpdateThreadListIfNeeded();
@@ -475,7 +503,7 @@ ThreadList::ShouldReportRun (Event *event_ptr)
void
ThreadList::Clear()
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
m_stop_id = 0;
m_threads.clear();
m_selected_tid = LLDB_INVALID_THREAD_ID;
@@ -484,7 +512,7 @@ ThreadList::Clear()
void
ThreadList::Destroy()
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
const uint32_t num_threads = m_threads.size();
for (uint32_t idx = 0; idx < num_threads; ++idx)
{
@@ -495,7 +523,7 @@ ThreadList::Destroy()
void
ThreadList::RefreshStateAfterStop ()
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
m_process->UpdateThreadListIfNeeded();
@@ -513,7 +541,7 @@ ThreadList::DiscardThreadPlans ()
{
// You don't need to update the thread list here, because only threads
// that you currently know about have any thread plans.
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
collection::iterator pos, end = m_threads.end();
for (pos = m_threads.begin(); pos != end; ++pos)
@@ -528,7 +556,7 @@ ThreadList::WillResume ()
// But we only do this for threads that are running, user suspended
// threads stay where they are.
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
m_process->UpdateThreadListIfNeeded();
collection::iterator pos, end = m_threads.end();
@@ -676,7 +704,7 @@ ThreadList::WillResume ()
void
ThreadList::DidResume ()
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
collection::iterator pos, end = m_threads.end();
for (pos = m_threads.begin(); pos != end; ++pos)
{
@@ -691,7 +719,7 @@ ThreadList::DidResume ()
void
ThreadList::DidStop ()
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
collection::iterator pos, end = m_threads.end();
for (pos = m_threads.begin(); pos != end; ++pos)
{
@@ -712,7 +740,7 @@ ThreadList::DidStop ()
ThreadSP
ThreadList::GetSelectedThread ()
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
ThreadSP thread_sp = FindThreadByID(m_selected_tid);
if (!thread_sp.get())
{
@@ -727,7 +755,7 @@ ThreadList::GetSelectedThread ()
bool
ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
ThreadSP selected_thread_sp(FindThreadByID(tid));
if (selected_thread_sp)
{
@@ -746,7 +774,7 @@ ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify)
bool
ThreadList::SetSelectedThreadByIndexID (uint32_t index_id, bool notify)
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
ThreadSP selected_thread_sp (FindThreadByIndexID(index_id));
if (selected_thread_sp.get())
{
@@ -778,7 +806,8 @@ ThreadList::Update (ThreadList &rhs)
{
// Lock both mutexes to make sure neither side changes anyone on us
// while the assignment occurs
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
+
m_process = rhs.m_process;
m_stop_id = rhs.m_stop_id;
m_threads.swap(rhs.m_threads);
@@ -816,15 +845,28 @@ ThreadList::Update (ThreadList &rhs)
void
ThreadList::Flush ()
{
- Mutex::Locker locker(GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
collection::iterator pos, end = m_threads.end();
for (pos = m_threads.begin(); pos != end; ++pos)
(*pos)->Flush ();
}
-Mutex &
-ThreadList::GetMutex ()
+std::recursive_mutex &
+ThreadList::GetMutex()
{
return m_process->m_thread_mutex;
}
+ThreadList::ExpressionExecutionThreadPusher::ExpressionExecutionThreadPusher (lldb::ThreadSP thread_sp) :
+ m_thread_list(nullptr),
+ m_tid(LLDB_INVALID_THREAD_ID)
+{
+ if (thread_sp)
+ {
+ m_tid = thread_sp->GetID();
+ m_thread_list = &thread_sp->GetProcess()->GetThreadList();
+ m_thread_list->PushExpressionExecutionThread(m_tid);
+ }
+}
+
+
diff --git a/source/Target/ThreadPlan.cpp b/source/Target/ThreadPlan.cpp
index 24323337accb..bf9a05497c74 100644
--- a/source/Target/ThreadPlan.cpp
+++ b/source/Target/ThreadPlan.cpp
@@ -27,21 +27,21 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// ThreadPlan constructor
//----------------------------------------------------------------------
-ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote) :
- m_thread (thread),
- m_stop_vote (stop_vote),
- m_run_vote (run_vote),
- m_kind (kind),
- m_name (name),
- m_plan_complete_mutex (Mutex::eMutexTypeRecursive),
- m_cached_plan_explains_stop (eLazyBoolCalculate),
- m_plan_complete (false),
- m_plan_private (false),
- m_okay_to_discard (true),
- m_is_master_plan (false),
- m_plan_succeeded(true)
+ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote)
+ : m_thread(thread),
+ m_stop_vote(stop_vote),
+ m_run_vote(run_vote),
+ m_kind(kind),
+ m_name(name),
+ m_plan_complete_mutex(),
+ m_cached_plan_explains_stop(eLazyBoolCalculate),
+ m_plan_complete(false),
+ m_plan_private(false),
+ m_okay_to_discard(true),
+ m_is_master_plan(false),
+ m_plan_succeeded(true)
{
- SetID (GetNextID());
+ SetID(GetNextID());
}
//----------------------------------------------------------------------
@@ -67,14 +67,14 @@ ThreadPlan::PlanExplainsStop (Event *event_ptr)
bool
ThreadPlan::IsPlanComplete ()
{
- Mutex::Locker locker(m_plan_complete_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
return m_plan_complete;
}
void
ThreadPlan::SetPlanComplete (bool success)
{
- Mutex::Locker locker(m_plan_complete_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
m_plan_complete = true;
m_plan_succeeded = success;
}
@@ -82,7 +82,7 @@ ThreadPlan::SetPlanComplete (bool success)
bool
ThreadPlan::MischiefManaged ()
{
- Mutex::Locker locker(m_plan_complete_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
// Mark the plan is complete, but don't override the success flag.
m_plan_complete = true;
return true;
diff --git a/source/Target/ThreadPlanCallUserExpression.cpp b/source/Target/ThreadPlanCallUserExpression.cpp
index b24f74b10dfa..d4259ed18d34 100644
--- a/source/Target/ThreadPlanCallUserExpression.cpp
+++ b/source/Target/ThreadPlanCallUserExpression.cpp
@@ -19,8 +19,9 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
-#include "lldb/Expression/UserExpression.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/IRDynamicChecks.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
@@ -90,15 +91,16 @@ ThreadPlanCallUserExpression::MischiefManaged ()
function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
function_stack_top = function_stack_pointer;
-
- StreamString error_stream;
-
+
+ DiagnosticManager diagnostics;
+
ExecutionContext exe_ctx(GetThread());
- m_user_expression_sp->FinalizeJITExecution(error_stream, exe_ctx, m_result_var_sp, function_stack_bottom, function_stack_top);
+ m_user_expression_sp->FinalizeJITExecution(diagnostics, exe_ctx, m_result_var_sp, function_stack_bottom,
+ function_stack_top);
}
-
- ThreadPlan::MischiefManaged ();
+
+ ThreadPlan::MischiefManaged();
return true;
}
else
diff --git a/source/Target/ThreadPlanShouldStopHere.cpp b/source/Target/ThreadPlanShouldStopHere.cpp
index 55aaaf00b569..fcbc7f01c901 100644
--- a/source/Target/ThreadPlanShouldStopHere.cpp
+++ b/source/Target/ThreadPlanShouldStopHere.cpp
@@ -11,10 +11,11 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Core/Log.h"
+#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanShouldStopHere.h"
-#include "lldb/Core/Log.h"
using namespace lldb;
using namespace lldb_private;
@@ -113,19 +114,45 @@ ThreadPlanShouldStopHere::DefaultStepFromHereCallback (ThreadPlan *current_plan,
ThreadPlanSP return_plan_sp;
// If we are stepping through code at line number 0, then we need to step over this range. Otherwise
// we will step out.
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+
StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
if (!frame)
return return_plan_sp;
SymbolContext sc;
- sc = frame->GetSymbolContext (eSymbolContextLineEntry);
+ sc = frame->GetSymbolContext (eSymbolContextLineEntry|eSymbolContextSymbol);
+
if (sc.line_entry.line == 0)
{
AddressRange range = sc.line_entry.range;
- return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepOverRange(false,
- range,
- sc,
- eOnlyDuringStepping,
- eLazyBoolNo);
+
+ // If the whole function is marked line 0 just step out, that's easier & faster than continuing
+ // to step through it.
+ bool just_step_out = false;
+ if (sc.symbol && sc.symbol->ValueIsAddress())
+ {
+ Address symbol_end = sc.symbol->GetAddress();
+ symbol_end.Slide(sc.symbol->GetByteSize() - 1);
+ if (range.ContainsFileAddress(sc.symbol->GetAddress()) && range.ContainsFileAddress(symbol_end))
+ {
+ if (log)
+ log->Printf("Stopped in a function with only line 0 lines, just stepping out.");
+ just_step_out = true;
+ }
+ }
+ if (!just_step_out)
+ {
+ if (log)
+ log->Printf ("ThreadPlanShouldStopHere::DefaultStepFromHereCallback Queueing StepInRange plan to step through line 0 code.");
+
+ return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepInRange(false,
+ range,
+ sc,
+ NULL,
+ eOnlyDuringStepping,
+ eLazyBoolCalculate,
+ eLazyBoolNo);
+ }
}
if (!return_plan_sp)
diff --git a/source/Target/ThreadPlanStepInstruction.cpp b/source/Target/ThreadPlanStepInstruction.cpp
index 9d7d52167ffc..ccfd52e00e10 100644
--- a/source/Target/ThreadPlanStepInstruction.cpp
+++ b/source/Target/ThreadPlanStepInstruction.cpp
@@ -239,7 +239,8 @@ ThreadPlanStepInstruction::ShouldStop (Event *event_ptr)
}
else
{
- if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
+ lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC(0);
+ if (pc_addr != m_instruction_addr)
{
if (--m_iteration_count <= 0)
{
diff --git a/source/Target/ThreadPlanStepOverRange.cpp b/source/Target/ThreadPlanStepOverRange.cpp
index 2e731a845788..95dc2205bbf6 100644
--- a/source/Target/ThreadPlanStepOverRange.cpp
+++ b/source/Target/ThreadPlanStepOverRange.cpp
@@ -232,7 +232,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
sc = frame_sp->GetSymbolContext (eSymbolContextEverything);
if (sc.line_entry.IsValid())
{
- if (sc.line_entry.file != m_addr_context.line_entry.file
+ if (sc.line_entry.original_file != m_addr_context.line_entry.original_file
&& sc.comp_unit == m_addr_context.comp_unit
&& sc.function == m_addr_context.function)
{
@@ -256,7 +256,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
// some code fragment by using #include <source-fragment.c> directly.
LineEntry prev_line_entry;
if (line_table->GetLineEntryAtIndex(entry_idx - 1, prev_line_entry)
- && prev_line_entry.file == line_entry.file)
+ && prev_line_entry.original_file == line_entry.original_file)
{
SymbolContext prev_sc;
Address prev_address = prev_line_entry.range.GetBaseAddress();
@@ -289,7 +289,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
if (next_line_function != m_addr_context.function)
break;
- if (next_line_entry.file == m_addr_context.line_entry.file)
+ if (next_line_entry.original_file == m_addr_context.line_entry.original_file)
{
const bool abort_other_plans = false;
const RunMode stop_other_threads = RunMode::eAllThreads;
diff --git a/source/Target/ThreadPlanStepRange.cpp b/source/Target/ThreadPlanStepRange.cpp
index 02667f8236ea..32e225c4af70 100644
--- a/source/Target/ThreadPlanStepRange.cpp
+++ b/source/Target/ThreadPlanStepRange.cpp
@@ -64,16 +64,6 @@ ThreadPlanStepRange::ThreadPlanStepRange (ThreadPlanKind kind,
ThreadPlanStepRange::~ThreadPlanStepRange ()
{
ClearNextBranchBreakpoint();
-
- size_t num_instruction_ranges = m_instruction_ranges.size();
-
- // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
- // I'll fix that but for now, just clear the list and it will go away nicely.
- for (size_t i = 0; i < num_instruction_ranges; i++)
- {
- if (m_instruction_ranges[i])
- m_instruction_ranges[i]->GetInstructionList().Clear();
- }
}
void
@@ -155,7 +145,7 @@ ThreadPlanStepRange::InRange ()
SymbolContext new_context(frame->GetSymbolContext(eSymbolContextEverything));
if (m_addr_context.line_entry.IsValid() && new_context.line_entry.IsValid())
{
- if (m_addr_context.line_entry.file == new_context.line_entry.file)
+ if (m_addr_context.line_entry.original_file == new_context.line_entry.original_file)
{
if (m_addr_context.line_entry.line == new_context.line_entry.line)
{
diff --git a/source/Target/ThreadPlanStepThrough.cpp b/source/Target/ThreadPlanStepThrough.cpp
index a5346a4cddee..c345b6a7d4ac 100644
--- a/source/Target/ThreadPlanStepThrough.cpp
+++ b/source/Target/ThreadPlanStepThrough.cpp
@@ -124,7 +124,7 @@ ThreadPlanStepThrough::GetDescription (Stream *s, lldb::DescriptionLevel level)
s->Address(m_start_address, sizeof (addr_t));
if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID)
{
- s->Printf (" with backstop breakpoint id: %d at address: ", m_backstop_bkpt_id);
+ s->Printf(" with backstop breakpoint ID: %d at address: ", m_backstop_bkpt_id);
s->Address (m_backstop_addr, sizeof (addr_t));
}
else
diff --git a/source/Target/UnixSignals.cpp b/source/Target/UnixSignals.cpp
index 8a98c21560d7..cf244ba8f7d3 100644
--- a/source/Target/UnixSignals.cpp
+++ b/source/Target/UnixSignals.cpp
@@ -7,15 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Target/UnixSignals.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Target/UnixSignals.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Host/StringConvert.h"
-
#include "Plugins/Process/Utility/FreeBSDSignals.h"
#include "Plugins/Process/Utility/LinuxSignals.h"
#include "Plugins/Process/Utility/MipsLinuxSignals.h"
@@ -23,15 +22,12 @@
using namespace lldb_private;
-UnixSignals::Signal::Signal
-(
- const char *name,
- bool default_suppress,
- bool default_stop,
- bool default_notify,
- const char *description,
- const char *alias
-) :
+UnixSignals::Signal::Signal(const char *name,
+ bool default_suppress,
+ bool default_stop,
+ bool default_notify,
+ const char *description,
+ const char *alias) :
m_name (name),
m_alias (alias),
m_description (),
@@ -85,12 +81,7 @@ UnixSignals::UnixSignals(const UnixSignals &rhs)
{
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-UnixSignals::~UnixSignals ()
-{
-}
+UnixSignals::~UnixSignals() = default;
void
UnixSignals::Reset ()
@@ -135,16 +126,13 @@ UnixSignals::Reset ()
}
void
-UnixSignals::AddSignal
-(
- int signo,
- const char *name,
- bool default_suppress,
- bool default_stop,
- bool default_notify,
- const char *description,
- const char *alias
-)
+UnixSignals::AddSignal(int signo,
+ const char *name,
+ bool default_suppress,
+ bool default_stop,
+ bool default_notify,
+ const char *description,
+ const char *alias)
{
Signal new_signal (name, default_suppress, default_stop, default_notify, description, alias);
m_signals.insert (std::make_pair(signo, new_signal));
@@ -163,12 +151,11 @@ UnixSignals::GetSignalAsCString (int signo) const
{
collection::const_iterator pos = m_signals.find (signo);
if (pos == m_signals.end())
- return NULL;
+ return nullptr;
else
return pos->second.m_name.GetCString ();
}
-
bool
UnixSignals::SignalIsValid (int32_t signo) const
{
@@ -180,7 +167,7 @@ UnixSignals::GetShortName(ConstString name) const
{
if (name)
{
- char* signame = (char*)(name.AsCString());
+ const char* signame = name.AsCString();
return ConstString(signame + 3); // Remove "SIG" from name
}
return name;
@@ -232,17 +219,14 @@ UnixSignals::GetNextSignalNumber (int32_t current_signal) const
}
const char *
-UnixSignals::GetSignalInfo
-(
- int32_t signo,
- bool &should_suppress,
- bool &should_stop,
- bool &should_notify
-) const
+UnixSignals::GetSignalInfo(int32_t signo,
+ bool &should_suppress,
+ bool &should_stop,
+ bool &should_notify) const
{
collection::const_iterator pos = m_signals.find (signo);
if (pos == m_signals.end())
- return NULL;
+ return nullptr;
else
{
const Signal &signal = pos->second;
diff --git a/source/Target/UnwindAssembly.cpp b/source/Target/UnwindAssembly.cpp
index af7f86fe492a..3dc443599016 100644
--- a/source/Target/UnwindAssembly.cpp
+++ b/source/Target/UnwindAssembly.cpp
@@ -1,4 +1,4 @@
-//===-- UnwindAssembly.cpp ------------------------------*- C++ -*-===//
+//===-- UnwindAssembly.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,6 +7,10 @@
//
//===----------------------------------------------------------------------===//
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/PluginInterface.h"
@@ -21,14 +25,14 @@ UnwindAssembly::FindPlugin (const ArchSpec &arch)
UnwindAssemblyCreateInstance create_callback;
for (uint32_t idx = 0;
- (create_callback = PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(idx)) != NULL;
+ (create_callback = PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(idx)) != nullptr;
++idx)
{
UnwindAssemblySP assembly_profiler_ap (create_callback (arch));
- if (assembly_profiler_ap.get ())
+ if (assembly_profiler_ap)
return assembly_profiler_ap;
}
- return NULL;
+ return nullptr;
}
UnwindAssembly::UnwindAssembly (const ArchSpec &arch) :
@@ -36,6 +40,4 @@ UnwindAssembly::UnwindAssembly (const ArchSpec &arch) :
{
}
-UnwindAssembly::~UnwindAssembly ()
-{
-}
+UnwindAssembly::~UnwindAssembly() = default;
diff --git a/source/Utility/ConvertEnum.cpp b/source/Utility/ConvertEnum.cpp
index 3231397a05e3..99515631db25 100644
--- a/source/Utility/ConvertEnum.cpp
+++ b/source/Utility/ConvertEnum.cpp
@@ -115,6 +115,8 @@ lldb_private::GetSectionTypeAsCString(lldb::SectionType sect_type)
return "compact-unwind";
case eSectionTypeGoSymtab:
return "go-symtab";
+ case eSectionTypeAbsoluteAddress:
+ return "absolute";
case eSectionTypeOther:
return "regular";
}
diff --git a/source/Utility/JSON.cpp b/source/Utility/JSON.cpp
index 8b96a06e08e8..7ad3232c564d 100644
--- a/source/Utility/JSON.cpp
+++ b/source/Utility/JSON.cpp
@@ -445,6 +445,7 @@ JSONParser::GetToken (std::string &value)
value = std::move(error.GetString());
return Token::Error;
}
+ break;
default:
done = true;
diff --git a/source/Utility/Makefile b/source/Utility/Makefile
deleted file mode 100644
index 13bcd8376c2d..000000000000
--- a/source/Utility/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- source/Utility/Makefile -----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LIBRARYNAME := lldbUtility
-BUILD_ARCHIVE = 1
-NO_PEDANTIC = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Utility/ModuleCache.cpp b/source/Utility/ModuleCache.cpp
index 7c57d0baeccd..92520f768b3f 100644
--- a/source/Utility/ModuleCache.cpp
+++ b/source/Utility/ModuleCache.cpp
@@ -33,6 +33,21 @@ const char* kLockDirName = ".lock";
const char* kTempFileName = ".temp";
const char* kTempSymFileName = ".symtemp";
const char* kSymFileExtension = ".sym";
+const char* kFSIllegalChars = "\\/:*?\"<>|";
+
+std::string
+GetEscapedHostname(const char* hostname)
+{
+ std::string result(hostname);
+ size_t size = result.size();
+ for (size_t i = 0; i < size; ++i)
+ {
+ if ((result[i] >=1 && result[i] <= 31) ||
+ strchr(kFSIllegalChars, result[i]) != nullptr)
+ result[i] = '_';
+ }
+ return result;
+}
class ModuleLock
{
@@ -280,8 +295,9 @@ ModuleCache::GetAndPut (const FileSpec &root_dir_spec,
if (error.Fail ())
return Error("Failed to lock module %s: %s", module_spec.GetUUID ().GetAsString().c_str(), error.AsCString ());
+ const auto escaped_hostname(GetEscapedHostname(hostname));
// Check local cache for a module.
- error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr);
+ error = Get (root_dir_spec, escaped_hostname.c_str(), module_spec, cached_module_sp, did_create_ptr);
if (error.Success ())
return error;
@@ -292,12 +308,12 @@ ModuleCache::GetAndPut (const FileSpec &root_dir_spec,
return Error("Failed to download module: %s", error.AsCString ());
// Put downloaded file into local module cache.
- error = Put (root_dir_spec, hostname, module_spec, tmp_download_file_spec, module_spec.GetFileSpec ());
+ error = Put (root_dir_spec, escaped_hostname.c_str(), module_spec, tmp_download_file_spec, module_spec.GetFileSpec ());
if (error.Fail ())
return Error ("Failed to put module into cache: %s", error.AsCString ());
tmp_file_remover.releaseFile ();
- error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr);
+ error = Get (root_dir_spec, escaped_hostname.c_str(), module_spec, cached_module_sp, did_create_ptr);
if (error.Fail ())
return error;
@@ -310,7 +326,7 @@ ModuleCache::GetAndPut (const FileSpec &root_dir_spec,
// contain the neccessary symbols and the debugging is also possible without a symfile.
return Error ();
- error = Put (root_dir_spec, hostname, module_spec, tmp_download_sym_file_spec, GetSymbolFileSpec(module_spec.GetFileSpec ()));
+ error = Put (root_dir_spec, escaped_hostname.c_str(), module_spec, tmp_download_sym_file_spec, GetSymbolFileSpec(module_spec.GetFileSpec ()));
if (error.Fail ())
return Error ("Failed to put symbol file into cache: %s", error.AsCString ());
diff --git a/source/Utility/SharingPtr.cpp b/source/Utility/SharingPtr.cpp
index 7f1278567ff1..7eedeb08afd1 100644
--- a/source/Utility/SharingPtr.cpp
+++ b/source/Utility/SharingPtr.cpp
@@ -14,12 +14,12 @@
// If ENABLE_SP_LOGGING is defined, then log all shared pointer assignments
// and allow them to be queried using a pointer by a call to:
#include <execinfo.h>
-#include <map>
#include <assert.h>
-#include "lldb/Host/Mutex.h"
#include "llvm/ADT/STLExtras.h"
+#include <map>
+#include <mutex>
#include <vector>
class Backtrace
@@ -70,8 +70,8 @@ extern "C" void track_sp (void *sp_this, void *ptr, long use_count)
{
typedef std::pair<void *, Backtrace> PtrBacktracePair;
typedef std::map<void *, PtrBacktracePair> PtrToBacktraceMap;
- static lldb_private::Mutex g_mutex(lldb_private::Mutex::eMutexTypeNormal);
- lldb_private::Mutex::Locker locker (g_mutex);
+ static std::mutex g_mutex;
+ std::lock_guard<std::mutex> guard(g_mutex);
static PtrToBacktraceMap g_map;
if (sp_this)
diff --git a/source/Utility/StringExtractor.cpp b/source/Utility/StringExtractor.cpp
index ae92704668fc..4c0029a0649b 100644
--- a/source/Utility/StringExtractor.cpp
+++ b/source/Utility/StringExtractor.cpp
@@ -104,6 +104,7 @@ StringExtractor::GetChar (char fail_value)
int
StringExtractor::DecodeHexU8()
{
+ SkipSpaces();
if (GetBytesLeft() < 2)
{
return -1;
@@ -230,6 +231,7 @@ StringExtractor::GetHexMaxU32 (bool little_endian, uint32_t fail_value)
uint32_t result = 0;
uint32_t nibble_count = 0;
+ SkipSpaces();
if (little_endian)
{
uint32_t shift_amount = 0;
@@ -292,6 +294,7 @@ StringExtractor::GetHexMaxU64 (bool little_endian, uint64_t fail_value)
uint64_t result = 0;
uint32_t nibble_count = 0;
+ SkipSpaces();
if (little_endian)
{
uint32_t shift_amount = 0;
diff --git a/source/Utility/StringExtractorGDBRemote.cpp b/source/Utility/StringExtractorGDBRemote.cpp
index 56df0be21edf..d2619afd5bfa 100644
--- a/source/Utility/StringExtractorGDBRemote.cpp
+++ b/source/Utility/StringExtractorGDBRemote.cpp
@@ -15,8 +15,6 @@
// Project includes
#include "Utility/StringExtractorGDBRemote.h"
-
-
StringExtractorGDBRemote::ResponseType
StringExtractorGDBRemote::GetResponseType () const
{
@@ -227,7 +225,7 @@ StringExtractorGDBRemote::GetServerPacketType () const
case 'j':
if (PACKET_MATCHES("jSignalsInfo")) return eServerPacketType_jSignalsInfo;
if (PACKET_MATCHES("jThreadsInfo")) return eServerPacketType_jThreadsInfo;
-
+ break;
case 'v':
if (PACKET_STARTS_WITH("vFile:"))
@@ -391,3 +389,132 @@ StringExtractorGDBRemote::GetEscapedBinaryData (std::string &str)
return str.size();
}
+static bool
+OKErrorNotSupportedResponseValidator(void *, const StringExtractorGDBRemote &response)
+{
+ switch (response.GetResponseType())
+ {
+ case StringExtractorGDBRemote::eOK:
+ case StringExtractorGDBRemote::eError:
+ case StringExtractorGDBRemote::eUnsupported:
+ return true;
+
+ case StringExtractorGDBRemote::eAck:
+ case StringExtractorGDBRemote::eNack:
+ case StringExtractorGDBRemote::eResponse:
+ break;
+ }
+ return false;
+}
+
+static bool
+JSONResponseValidator(void *, const StringExtractorGDBRemote &response)
+{
+ switch (response.GetResponseType())
+ {
+ case StringExtractorGDBRemote::eUnsupported:
+ case StringExtractorGDBRemote::eError:
+ return true; // Accept unsupported or EXX as valid responses
+
+ case StringExtractorGDBRemote::eOK:
+ case StringExtractorGDBRemote::eAck:
+ case StringExtractorGDBRemote::eNack:
+ break;
+
+ case StringExtractorGDBRemote::eResponse:
+ // JSON that is returned in from JSON query packets is currently always
+ // either a dictionary which starts with a '{', or an array which
+ // starts with a '['. This is a quick validator to just make sure the
+ // response could be valid JSON without having to validate all of the
+ // JSON content.
+ switch (response.GetStringRef()[0])
+ {
+ case '{': return true;
+ case '[': return true;
+ default:
+ break;
+ }
+ break;
+ }
+ return false;
+}
+
+static bool
+ASCIIHexBytesResponseValidator(void *, const StringExtractorGDBRemote &response)
+{
+ switch (response.GetResponseType())
+ {
+ case StringExtractorGDBRemote::eUnsupported:
+ case StringExtractorGDBRemote::eError:
+ return true; // Accept unsupported or EXX as valid responses
+
+ case StringExtractorGDBRemote::eOK:
+ case StringExtractorGDBRemote::eAck:
+ case StringExtractorGDBRemote::eNack:
+ break;
+
+ case StringExtractorGDBRemote::eResponse:
+ {
+ uint32_t valid_count = 0;
+ for (const char ch : response.GetStringRef())
+ {
+ if (!isxdigit(ch))
+ {
+ return false;
+ }
+ if (++valid_count >= 16)
+ break; // Don't validate all the characters in case the packet is very large
+ }
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+void
+StringExtractorGDBRemote::CopyResponseValidator(const StringExtractorGDBRemote& rhs)
+{
+ m_validator = rhs.m_validator;
+ m_validator_baton = rhs.m_validator_baton;
+}
+
+void
+StringExtractorGDBRemote::SetResponseValidator(ResponseValidatorCallback callback, void *baton)
+{
+ m_validator = callback;
+ m_validator_baton = baton;
+}
+
+void
+StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported()
+{
+ m_validator = OKErrorNotSupportedResponseValidator;
+ m_validator_baton = nullptr;
+}
+
+void
+StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes()
+{
+ m_validator = ASCIIHexBytesResponseValidator;
+ m_validator_baton = nullptr;
+}
+
+void
+StringExtractorGDBRemote::SetResponseValidatorToJSON()
+{
+ m_validator = JSONResponseValidator;
+ m_validator_baton = nullptr;
+}
+
+bool
+StringExtractorGDBRemote::ValidateResponse() const
+{
+ // If we have a validator callback, try to validate the callback
+ if (m_validator)
+ return m_validator(m_validator_baton, *this);
+ else
+ return true; // No validator, so response is valid
+}
+
+
diff --git a/source/Utility/StringExtractorGDBRemote.h b/source/Utility/StringExtractorGDBRemote.h
index 7e2f1e7c6962..ade0edbbb7ae 100644
--- a/source/Utility/StringExtractorGDBRemote.h
+++ b/source/Utility/StringExtractorGDBRemote.h
@@ -20,18 +20,23 @@
class StringExtractorGDBRemote : public StringExtractor
{
public:
+ typedef bool (*ResponseValidatorCallback)(void * baton, const StringExtractorGDBRemote &response);
StringExtractorGDBRemote() :
- StringExtractor ()
+ StringExtractor(),
+ m_validator(nullptr)
{
}
StringExtractorGDBRemote(const char *cstr) :
- StringExtractor (cstr)
+ StringExtractor(cstr),
+ m_validator(nullptr)
{
}
+
StringExtractorGDBRemote(const StringExtractorGDBRemote& rhs) :
- StringExtractor (rhs)
+ StringExtractor(rhs),
+ m_validator(rhs.m_validator)
{
}
@@ -39,6 +44,24 @@ public:
{
}
+ bool
+ ValidateResponse() const;
+
+ void
+ CopyResponseValidator(const StringExtractorGDBRemote& rhs);
+
+ void
+ SetResponseValidator(ResponseValidatorCallback callback, void *baton);
+
+ void
+ SetResponseValidatorToOKErrorNotSupported();
+
+ void
+ SetResponseValidatorToASCIIHexBytes();
+
+ void
+ SetResponseValidatorToJSON();
+
enum ServerPacketType
{
eServerPacketType_nack = 0,
@@ -192,6 +215,9 @@ public:
size_t
GetEscapedBinaryData (std::string &str);
+protected:
+ ResponseValidatorCallback m_validator;
+ void *m_validator_baton;
};
#endif // utility_StringExtractorGDBRemote_h_
diff --git a/source/Utility/TaskPool.cpp b/source/Utility/TaskPool.cpp
index 75fe59d1e711..c5c63a20cebc 100644
--- a/source/Utility/TaskPool.cpp
+++ b/source/Utility/TaskPool.cpp
@@ -61,8 +61,9 @@ TaskPoolImpl::AddTask(std::function<void()>&& task_fn)
if (m_thread_count < max_threads)
{
m_thread_count++;
- lock.unlock();
-
+ // Note that this detach call needs to happen with the m_tasks_mutex held. This prevents the thread
+ // from exiting prematurely and triggering a linux libc bug
+ // (https://sourceware.org/bugzilla/show_bug.cgi?id=19951).
std::thread (Worker, this).detach();
}
}