aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.arcconfig2
-rw-r--r--.gitignore1
-rw-r--r--CMakeLists.txt4
-rw-r--r--Makefile112
-rw-r--r--cmake/LLDBDependencies.cmake13
-rw-r--r--cmake/modules/AddLLDB.cmake2
-rw-r--r--cmake/modules/LLDBConfig.cmake51
-rw-r--r--cmake/modules/LLDBStandalone.cmake135
-rw-r--r--cmake/platforms/Android.cmake12
-rw-r--r--docs/lldb-for-gdb-users.txt2
-rw-r--r--docs/lldb-gdb-remote.txt66
-rwxr-xr-xexamples/python/crashlog.py2
-rw-r--r--examples/python/scripted_step.py25
-rw-r--r--examples/python/shadow.py57
-rwxr-xr-xexamples/python/symbolication.py2
-rw-r--r--examples/synthetic/gnu_libstdcpp.py11
-rw-r--r--include/Makefile13
-rw-r--r--include/lldb/API/LLDB.h2
-rw-r--r--include/lldb/API/SBCommandReturnObject.h10
-rw-r--r--include/lldb/API/SBDefines.h2
-rw-r--r--include/lldb/API/SBExpressionOptions.h13
-rw-r--r--include/lldb/API/SBFileSpec.h3
-rw-r--r--include/lldb/API/SBHostOS.h3
-rw-r--r--include/lldb/API/SBInstruction.h11
-rw-r--r--include/lldb/API/SBLaunchInfo.h2
-rw-r--r--include/lldb/API/SBListener.h15
-rw-r--r--include/lldb/API/SBMemoryRegionInfo.h117
-rw-r--r--include/lldb/API/SBMemoryRegionInfoList.h63
-rw-r--r--include/lldb/API/SBProcess.h28
-rw-r--r--include/lldb/API/SBStream.h1
-rw-r--r--include/lldb/API/SBStringList.h3
-rw-r--r--include/lldb/API/SBTarget.h18
-rw-r--r--include/lldb/API/SBThread.h12
-rw-r--r--include/lldb/API/SBThreadCollection.h1
-rw-r--r--include/lldb/API/SBValue.h6
-rw-r--r--include/lldb/Breakpoint/BreakpointList.h16
-rw-r--r--include/lldb/Breakpoint/BreakpointLocation.h5
-rw-r--r--include/lldb/Breakpoint/BreakpointLocationCollection.h5
-rw-r--r--include/lldb/Breakpoint/BreakpointLocationList.h4
-rw-r--r--include/lldb/Breakpoint/BreakpointResolver.h29
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverFileLine.h1
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverFileRegex.h9
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverName.h27
-rw-r--r--include/lldb/Breakpoint/BreakpointSite.h4
-rw-r--r--include/lldb/Breakpoint/BreakpointSiteList.h12
-rw-r--r--include/lldb/Breakpoint/WatchpointList.h9
-rw-r--r--include/lldb/Core/ArchSpec.h60
-rw-r--r--include/lldb/Core/Broadcaster.h326
-rw-r--r--include/lldb/Core/Communication.h10
-rw-r--r--include/lldb/Core/ConstString.h33
-rw-r--r--include/lldb/Core/DataExtractor.h12
-rw-r--r--include/lldb/Core/Debugger.h24
-rw-r--r--include/lldb/Core/EmulateInstruction.h9
-rw-r--r--include/lldb/Core/Event.h77
-rw-r--r--include/lldb/Core/History.h24
-rw-r--r--include/lldb/Core/IOHandler.h66
-rw-r--r--include/lldb/Core/Listener.h34
-rw-r--r--include/lldb/Core/Logging.h1
-rw-r--r--include/lldb/Core/MappedHash.h6
-rw-r--r--include/lldb/Core/Module.h150
-rw-r--r--include/lldb/Core/ModuleList.h16
-rw-r--r--include/lldb/Core/ModuleSpec.h80
-rw-r--r--include/lldb/Core/RangeMap.h64
-rw-r--r--include/lldb/Core/RegisterValue.h3
-rw-r--r--include/lldb/Core/Scalar.h43
-rw-r--r--include/lldb/Core/SearchFilter.h12
-rw-r--r--include/lldb/Core/Section.h23
-rw-r--r--include/lldb/Core/StreamCallback.h6
-rw-r--r--include/lldb/Core/StreamTee.h84
-rw-r--r--include/lldb/Core/ThreadSafeSTLMap.h53
-rw-r--r--include/lldb/Core/ThreadSafeSTLVector.h99
-rw-r--r--include/lldb/Core/ThreadSafeValue.h30
-rw-r--r--include/lldb/Core/Timer.h5
-rw-r--r--include/lldb/Core/UserSettingsController.h15
-rw-r--r--include/lldb/Core/Value.h5
-rw-r--r--include/lldb/Core/ValueObject.h53
-rw-r--r--include/lldb/Core/ValueObjectConstResult.h5
-rw-r--r--include/lldb/Core/ValueObjectConstResultCast.h3
-rw-r--r--include/lldb/Core/ValueObjectConstResultChild.h5
-rw-r--r--include/lldb/Core/ValueObjectConstResultImpl.h5
-rw-r--r--include/lldb/Core/ValueObjectDynamicValue.h6
-rw-r--r--include/lldb/Core/ValueObjectSyntheticFilter.h9
-rw-r--r--include/lldb/DataFormatters/DumpValueObjectOptions.h4
-rw-r--r--include/lldb/DataFormatters/FormatCache.h6
-rw-r--r--include/lldb/DataFormatters/FormatManager.h3
-rw-r--r--include/lldb/DataFormatters/FormattersContainer.h151
-rw-r--r--include/lldb/DataFormatters/FormattersHelpers.h30
-rw-r--r--include/lldb/DataFormatters/TypeCategory.h7
-rw-r--r--include/lldb/DataFormatters/TypeCategoryMap.h12
-rw-r--r--include/lldb/DataFormatters/TypeSynthetic.h8
-rw-r--r--include/lldb/DataFormatters/ValueObjectPrinter.h4
-rw-r--r--include/lldb/DataFormatters/VectorIterator.h4
-rw-r--r--include/lldb/Expression/DWARFExpression.h15
-rw-r--r--include/lldb/Expression/DiagnosticManager.h212
-rw-r--r--include/lldb/Expression/ExpressionParser.h23
-rw-r--r--include/lldb/Expression/ExpressionSourceCode.h9
-rw-r--r--include/lldb/Expression/ExpressionVariable.h13
-rw-r--r--include/lldb/Expression/FunctionCaller.h84
-rw-r--r--include/lldb/Expression/IRDynamicChecks.h15
-rw-r--r--include/lldb/Expression/IRExecutionUnit.h170
-rw-r--r--include/lldb/Expression/IRInterpreter.h2
-rw-r--r--include/lldb/Expression/IRMemoryMap.h2
-rw-r--r--include/lldb/Expression/LLVMUserExpression.h60
-rw-r--r--include/lldb/Expression/UserExpression.h54
-rw-r--r--include/lldb/Expression/UtilityFunction.h12
-rw-r--r--include/lldb/Host/Editline.h29
-rw-r--r--include/lldb/Host/File.h16
-rw-r--r--include/lldb/Host/FileSpec.h19
-rw-r--r--include/lldb/Host/FileSystem.h12
-rw-r--r--include/lldb/Host/Host.h18
-rw-r--r--include/lldb/Host/HostInfoBase.h2
-rw-r--r--include/lldb/Host/HostNativeProcessBase.h5
-rw-r--r--include/lldb/Host/HostProcess.h8
-rw-r--r--include/lldb/Host/OptionParser.h5
-rw-r--r--include/lldb/Host/ProcessRunLock.h1
-rw-r--r--include/lldb/Host/common/NativeBreakpointList.h4
-rw-r--r--include/lldb/Host/common/NativeProcessProtocol.h8
-rw-r--r--include/lldb/Host/linux/Signalfd.h54
-rw-r--r--include/lldb/Host/macosx/HostInfoMacOSX.h1
-rw-r--r--include/lldb/Host/posix/ConnectionFileDescriptorPosix.h4
-rw-r--r--include/lldb/Host/posix/HostInfoPosix.h5
-rw-r--r--include/lldb/Host/posix/HostProcessPosix.h3
-rw-r--r--include/lldb/Host/windows/HostInfoWindows.h31
-rw-r--r--include/lldb/Host/windows/HostProcessWindows.h5
-rw-r--r--include/lldb/Initialization/SystemLifetimeManager.h17
-rw-r--r--include/lldb/Interpreter/Args.h29
-rw-r--r--include/lldb/Interpreter/CommandAlias.h123
-rw-r--r--include/lldb/Interpreter/CommandHistory.h4
-rw-r--r--include/lldb/Interpreter/CommandInterpreter.h42
-rw-r--r--include/lldb/Interpreter/CommandObject.h96
-rw-r--r--include/lldb/Interpreter/CommandObjectMultiword.h14
-rw-r--r--include/lldb/Interpreter/OptionGroupValueObjectDisplay.h1
-rw-r--r--include/lldb/Interpreter/ScriptInterpreter.h6
-rw-r--r--include/lldb/Makefile31
-rw-r--r--include/lldb/Symbol/ArmUnwindInfo.h1
-rw-r--r--include/lldb/Symbol/Block.h8
-rw-r--r--include/lldb/Symbol/ClangASTContext.h117
-rw-r--r--include/lldb/Symbol/ClangASTImporter.h42
-rw-r--r--include/lldb/Symbol/ClangUtil.h37
-rw-r--r--include/lldb/Symbol/CompactUnwindInfo.h10
-rw-r--r--include/lldb/Symbol/CompileUnit.h20
-rw-r--r--include/lldb/Symbol/CompilerDecl.h6
-rw-r--r--include/lldb/Symbol/CompilerDeclContext.h2
-rw-r--r--include/lldb/Symbol/CompilerType.h11
-rw-r--r--include/lldb/Symbol/DWARFCallFrameInfo.h7
-rw-r--r--include/lldb/Symbol/FuncUnwinders.h12
-rw-r--r--include/lldb/Symbol/Function.h8
-rw-r--r--include/lldb/Symbol/GoASTContext.h13
-rw-r--r--include/lldb/Symbol/JavaASTContext.h385
-rw-r--r--include/lldb/Symbol/LineEntry.h13
-rw-r--r--include/lldb/Symbol/ObjectFile.h36
-rw-r--r--include/lldb/Symbol/Symbol.h3
-rw-r--r--include/lldb/Symbol/SymbolContext.h3
-rw-r--r--include/lldb/Symbol/SymbolFile.h9
-rw-r--r--include/lldb/Symbol/SymbolVendor.h7
-rw-r--r--include/lldb/Symbol/Symtab.h15
-rw-r--r--include/lldb/Symbol/Type.h9
-rw-r--r--include/lldb/Symbol/TypeSystem.h43
-rw-r--r--include/lldb/Symbol/UnwindPlan.h8
-rw-r--r--include/lldb/Symbol/UnwindTable.h7
-rw-r--r--include/lldb/Symbol/Variable.h6
-rw-r--r--include/lldb/Target/ABI.h5
-rw-r--r--include/lldb/Target/DynamicLoader.h20
-rw-r--r--include/lldb/Target/ExecutionContext.h7
-rw-r--r--include/lldb/Target/InstrumentationRuntime.h4
-rw-r--r--include/lldb/Target/JITLoaderList.h4
-rw-r--r--include/lldb/Target/Language.h3
-rw-r--r--include/lldb/Target/LanguageRuntime.h19
-rw-r--r--include/lldb/Target/Memory.h6
-rw-r--r--include/lldb/Target/MemoryRegionInfo.h61
-rw-r--r--include/lldb/Target/PathMappingList.h4
-rw-r--r--include/lldb/Target/Platform.h111
-rw-r--r--include/lldb/Target/Process.h119
-rw-r--r--include/lldb/Target/ProcessLaunchInfo.h12
-rw-r--r--include/lldb/Target/QueueList.h9
-rw-r--r--include/lldb/Target/SectionLoadHistory.h10
-rw-r--r--include/lldb/Target/SectionLoadList.h12
-rw-r--r--include/lldb/Target/StackFrame.h10
-rw-r--r--include/lldb/Target/StackFrameList.h4
-rw-r--r--include/lldb/Target/Target.h67
-rw-r--r--include/lldb/Target/TargetList.h4
-rw-r--r--include/lldb/Target/Thread.h10
-rw-r--r--include/lldb/Target/ThreadCollection.h19
-rw-r--r--include/lldb/Target/ThreadList.h43
-rw-r--r--include/lldb/Target/ThreadPlan.h4
-rw-r--r--include/lldb/Target/ThreadPlanPython.h1
-rw-r--r--include/lldb/Target/ThreadPlanStepInstruction.h11
-rw-r--r--include/lldb/Target/Unwind.h37
-rw-r--r--include/lldb/Utility/Iterable.h30
-rw-r--r--include/lldb/Utility/ProcessStructReader.h9
-rw-r--r--include/lldb/Utility/SharedCluster.h56
-rw-r--r--include/lldb/lldb-enumerations.h27
-rw-r--r--include/lldb/lldb-forward.h8
-rw-r--r--include/lldb/lldb-private-defines.h39
-rw-r--r--include/lldb/lldb-private-enumerations.h5
-rw-r--r--include/lldb/lldb-private-interfaces.h2
-rw-r--r--include/lldb/lldb-private-types.h1
-rw-r--r--include/lldb/lldb-private.h1
-rw-r--r--lib/Makefile217
-rw-r--r--lit/CMakeLists.txt2
-rw-r--r--lit/Unit/lit.site.cfg.in4
-rw-r--r--lit/lit.site.cfg.in4
-rw-r--r--lldb.xcodeproj/project.pbxproj499
-rw-r--r--lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme2
-rw-r--r--lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme2
-rw-r--r--packages/Python/lldbsuite/support/encoded_file.py48
-rw-r--r--packages/Python/lldbsuite/support/funcutils.py16
-rw-r--r--packages/Python/lldbsuite/support/gmodules.py30
-rw-r--r--packages/Python/lldbsuite/support/optional_with.py (renamed from packages/Python/lldbsuite/test/test_runner/lib/lldb_utils.py)26
-rw-r--r--packages/Python/lldbsuite/test/android/platform/TestDefaultCacheLineSize.py3
-rw-r--r--packages/Python/lldbsuite/test/api/check_public_api_headers/TestPublicAPIHeaders.py3
-rw-r--r--packages/Python/lldbsuite/test/api/listeners/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/api/listeners/TestListener.py55
-rw-r--r--packages/Python/lldbsuite/test/api/listeners/main.c7
-rw-r--r--packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py14
-rw-r--r--packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py6
-rw-r--r--packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp46
-rw-r--r--packages/Python/lldbsuite/test/arm_emulation/TestEmulations.py2
-rw-r--r--packages/Python/lldbsuite/test/benchmarks/continue/TestBenchmarkContinue.py4
-rw-r--r--packages/Python/lldbsuite/test/benchmarks/disassembly/TestDisassembly.py8
-rw-r--r--packages/Python/lldbsuite/test/benchmarks/disassembly/TestDoAttachThenDisassembly.py3
-rw-r--r--packages/Python/lldbsuite/test/benchmarks/disassembly/TestXcode41Vs42GDBDisassembly.py9
-rw-r--r--packages/Python/lldbsuite/test/benchmarks/expression/TestExpressionCmd.py7
-rw-r--r--packages/Python/lldbsuite/test/benchmarks/expression/TestRepeatedExprs.py7
-rw-r--r--packages/Python/lldbsuite/test/benchmarks/frame_variable/TestFrameVariableResponse.py3
-rw-r--r--packages/Python/lldbsuite/test/benchmarks/libcxxlist/TestBenchmarkLibcxxList.py4
-rw-r--r--packages/Python/lldbsuite/test/benchmarks/libcxxmap/TestBenchmarkLibcxxMap.py4
-rw-r--r--packages/Python/lldbsuite/test/benchmarks/startup/TestStartupDelays.py3
-rw-r--r--packages/Python/lldbsuite/test/benchmarks/stepping/TestSteppingSpeed.py5
-rw-r--r--packages/Python/lldbsuite/test/benchmarks/turnaround/TestCompileRunToBreakpointTurnaround.py7
-rw-r--r--packages/Python/lldbsuite/test/configuration.py9
-rw-r--r--packages/Python/lldbsuite/test/decorators.py524
-rw-r--r--packages/Python/lldbsuite/test/dosep.py61
-rw-r--r--packages/Python/lldbsuite/test/dotest.py174
-rw-r--r--packages/Python/lldbsuite/test/dotest_args.py2
-rw-r--r--packages/Python/lldbsuite/test/driver/batch_mode/TestBatchMode.py8
-rw-r--r--packages/Python/lldbsuite/test/expression_command/anonymous-struct/Makefile12
-rw-r--r--packages/Python/lldbsuite/test/expression_command/anonymous-struct/TestCallUserAnonTypedef.py42
-rw-r--r--packages/Python/lldbsuite/test/expression_command/anonymous-struct/main.cpp26
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py9
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-function/TestCallStopAndContinue.py5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-function/TestCallUserDefinedFunction.py5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py3
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py3
-rw-r--r--packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py17
-rw-r--r--packages/Python/lldbsuite/test/expression_command/expr-in-syscall/TestExpressionInSyscall.py5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/fixits/Makefile12
-rw-r--r--packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py81
-rw-r--r--packages/Python/lldbsuite/test/expression_command/fixits/main.cpp25
-rw-r--r--packages/Python/lldbsuite/test/expression_command/formatters/TestFormatters.py8
-rw-r--r--packages/Python/lldbsuite/test/expression_command/ir-interpreter-phi-nodes/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/ir-interpreter-phi-nodes/TestIRInterpreterPHINodes.py40
-rw-r--r--packages/Python/lldbsuite/test/expression_command/ir-interpreter-phi-nodes/main.cpp17
-rw-r--r--packages/Python/lldbsuite/test/expression_command/ir-interpreter/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/expression_command/ir-interpreter/TestIRInterpreter.py72
-rw-r--r--packages/Python/lldbsuite/test/expression_command/ir-interpreter/main.c7
-rw-r--r--packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/macros/TestMacros.py10
-rw-r--r--packages/Python/lldbsuite/test/expression_command/multiline/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py57
-rw-r--r--packages/Python/lldbsuite/test/expression_command/multiline/main.c6
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py3
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persistent_types/TestNestedPersistentTypes.py4
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py4
-rw-r--r--packages/Python/lldbsuite/test/expression_command/po_verbosity/TestPoVerbosity.py3
-rw-r--r--packages/Python/lldbsuite/test/expression_command/radar_9531204/TestPrintfAfterUp.py5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/test/TestExprs.py16
-rw-r--r--packages/Python/lldbsuite/test/expression_command/test/TestExprs2.py5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/timeout/TestCallWithTimeout.py10
-rw-r--r--packages/Python/lldbsuite/test/expression_command/top-level/Makefile12
-rw-r--r--packages/Python/lldbsuite/test/expression_command/top-level/TestTopLevelExprs.py89
-rw-r--r--packages/Python/lldbsuite/test/expression_command/top-level/dummy.cpp7
-rw-r--r--packages/Python/lldbsuite/test/expression_command/top-level/main.cpp9
-rw-r--r--packages/Python/lldbsuite/test/expression_command/top-level/test.cpp107
-rw-r--r--packages/Python/lldbsuite/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py3
-rw-r--r--packages/Python/lldbsuite/test/expression_command/unwind_expression/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/unwind_expression/TestUnwindExpression.py83
-rw-r--r--packages/Python/lldbsuite/test/expression_command/unwind_expression/main.cpp14
-rw-r--r--packages/Python/lldbsuite/test/functionalities/abbreviation/TestAbbreviations.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/abbreviation/TestCommonShortSpellings.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/apropos_with_process/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/apropos_with_process/TestAproposWithProcess.py44
-rw-r--r--packages/Python/lldbsuite/test/functionalities/apropos_with_process/main.cpp15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/archives/TestBSDArchives.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/asan/TestMemoryHistory.py33
-rw-r--r--packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py24
-rw-r--r--packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py22
-rw-r--r--packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/TestFdLeak.py16
-rw-r--r--packages/Python/lldbsuite/test/functionalities/backticks/TestBackticksWithoutATarget.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py77
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/TestBreakpointCaseSensitivity.py121
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/main.c8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/TestAvoidBreakpointInDelaySlot.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_set_restart/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_set_restart/TestBreakpointSetRestart.py43
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_set_restart/main.cpp25
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/TestConsecutiveBreakpoints.py59
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/Makefile (renamed from packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/Makefile)0
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/TestConsecutiveBreakpoints.py101
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/main.cpp (renamed from packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/main.cpp)0
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/TestCPPBreakpointLocations.py39
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/main.cpp14
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/TestCPPExceptionBreakpoint.py7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/debugbreak/TestDebugBreak.py11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/objc/TestObjCBreakpoints.py7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/TestSourceRegexBreakpoints.py100
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/a.c16
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/a.h1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/main.c17
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_history/TestCommandHistory.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_regex/TestCommandRegex.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/TestCommandScript.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/TestImport.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/TestRdar12586188.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/__init__.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script_alias/.categories1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script_alias/TestCommandScriptAlias.py37
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script_alias/tcsacmd.py11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/TestCommandScriptImmediateOutput.py86
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/custom_command.py17
-rw-r--r--packages/Python/lldbsuite/test/functionalities/command_source/TestCommandSource.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py69
-rw-r--r--packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/TestFormattersBoolRefPtr.py11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/main.mm4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/TestCompactVectors.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py71
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/main.m86
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/TestFormattersOneIsSingular.py17
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/main.m27
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py84
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py1
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py113
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/TestLibCxxAtomic.py52
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/main.cpp26
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/TestDataFormatterLibcxxListLoop.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/TestDataFormatterLibccMultiMap.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py89
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/TestDataFormatterStdIterator.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/Makefile15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py46
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/main.cpp20
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/TestDataFormatterSynthType.py56
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/main.cpp29
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/myIntSynthProvider.py36
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/TestDumpDynamic.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/TestNSArraySynthetic.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/TestFormattersOsType.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/parray/TestPrintArray.py70
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/parray/main.cpp29
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/Makefile9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/TestPrintObjectArray.py60
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/main.mm30
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/TestSetValueFromCString.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/TestStringPrinter.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py25
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/fooSynthProvider.py38
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/TestSyntheticFilterRecompute.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_arg/TestTypeSummaryListArg.py31
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/TestTypeSummaryListScript.py61
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/main.cpp15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/tslsformatters.py10
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/TestTypedefArray.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/dead-strip/TestDeadStrip.py8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py10
-rw-r--r--packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/exec/TestExec.py38
-rw-r--r--packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/fat_archives/TestFatArchives.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/format/TestFormats.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-assert/TestInferiorAssert.py36
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-changed/TestInferiorChanged.py8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py23
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py24
-rw-r--r--packages/Python/lldbsuite/test/functionalities/inline-stepping/TestInlineStepping.py8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/llvm/TestLLVM.py60
-rw-r--r--packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/longjmp/TestLongjmp.py15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/memory/cache/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/memory/cache/TestMemoryCache.py64
-rw-r--r--packages/Python/lldbsuite/test/functionalities/memory/cache/main.cpp14
-rw-r--r--packages/Python/lldbsuite/test/functionalities/multidebugger_commands/TestMultipleDebuggersCommands.py48
-rw-r--r--packages/Python/lldbsuite/test/functionalities/nested_alias/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/nested_alias/TestNestedAlias.py68
-rw-r--r--packages/Python/lldbsuite/test/functionalities/nested_alias/main.cpp22
-rw-r--r--packages/Python/lldbsuite/test/functionalities/object-file/TestImageListMultiArchitecture.py7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/paths/TestPaths.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/platform/TestPlatformCommand.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/plugins/commands/TestPluginCommands.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py164
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.c6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.corebin0 -> 40960 bytes
-rwxr-xr-xpackages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.outbin0 -> 2330 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/i386.corebin0 -> 28672 bytes
-rwxr-xr-xpackages/Python/lldbsuite/test/functionalities/postmortem/linux-core/i386.outbin0 -> 1971 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/main.c17
-rwxr-xr-xpackages/Python/lldbsuite/test/functionalities/postmortem/linux-core/make-core.sh40
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/s390x.corebin0 -> 16384 bytes
-rwxr-xr-xpackages/Python/lldbsuite/test/functionalities/postmortem/linux-core/s390x.outbin0 -> 2824 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/x86_64.corebin0 -> 40960 bytes
-rwxr-xr-xpackages/Python/lldbsuite/test/functionalities/postmortem/linux-core/x86_64.outbin0 -> 2575 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/TestWow64MiniDump.py76
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/fizzbuzz.cpp31
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/fizzbuzz_wow64.dmpbin0 -> 9280561 bytes
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/TestAttachDenied.py24
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py27
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py48
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/process_save_core/TestProcessSaveCore.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/ptr_refs/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/ptr_refs/TestPtrRefs.py43
-rw-r--r--packages/Python/lldbsuite/test/functionalities/ptr_refs/main.c27
-rw-r--r--packages/Python/lldbsuite/test/functionalities/register/TestRegisters.py17
-rw-r--r--packages/Python/lldbsuite/test/functionalities/rerun/TestRerun.py34
-rw-r--r--packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/set-data/TestSetData.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/signal/TestSendSignal.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/signal/handle-segv/TestHandleSegv.py8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/target_command/TestTargetCommand.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/break_after_join/TestBreakAfterJoin.py9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/break_after_join/main.cpp16
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py40
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/main.cpp14
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py15
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py27
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/create_during_step/main.cpp12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/main.cpp18
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py64
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/main.cpp12
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/multi_break/main.cpp14
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py134
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py21
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/step_out/main.cpp14
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py68
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp18
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/TestThreadSpecificBreakpoint.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/basic/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py118
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/basic/main.c37
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/TestTsanCPPGlobalLocation.py54
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/main.cpp38
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/global_location/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py54
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/global_location/main.c38
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/multiple/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py69
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m138
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/TestTsanThreadLeak.py40
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/main.c24
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/TestTsanThreadNumbers.py68
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/main.c58
-rw-r--r--packages/Python/lldbsuite/test/functionalities/tty/TestTerminal.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/type_completion/TestTypeCompletion.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/type_lookup/TestTypeLookup.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/ehframe/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/ehframe/TestEhFrameUnwind.py51
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/ehframe/main.c20
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/TestSigtrampUnwind.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/standard/TestStandardUnwind.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/value_md5_crash/TestValueMD5Crash.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/TestWatchLocation.py13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/main.cpp6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py13
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/main.cpp10
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py10
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/TestWatchpointCommands.py18
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py9
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py60
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/watchpoint_command.py14
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/TestWatchpointConditionCmd.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/TestWatchpointEvents.py8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/TestValueOfVectorVariable.py5
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/main.c2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchLocationWithWatchSet.py7
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_size/Makefile (renamed from packages/Python/lldbsuite/test/lang/c/inlines/Makefile)2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_size/TestWatchpointSizes.py117
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_size/main.c66
-rw-r--r--packages/Python/lldbsuite/test/help/TestApropos.py22
-rw-r--r--packages/Python/lldbsuite/test/help/TestHelp.py50
-rw-r--r--packages/Python/lldbsuite/test/issue_verification/TestInvalidDecorator.py.park13
-rw-r--r--packages/Python/lldbsuite/test/issue_verification/TestRerunTimeout.py.park8
-rw-r--r--packages/Python/lldbsuite/test/lang/c/anonymous/TestAnonymous.py20
-rw-r--r--packages/Python/lldbsuite/test/lang/c/array_types/TestArrayTypes.py12
-rw-r--r--packages/Python/lldbsuite/test/lang/c/bitfields/TestBitfields.py21
-rw-r--r--packages/Python/lldbsuite/test/lang/c/bitfields/main.c14
-rw-r--r--packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py18
-rw-r--r--packages/Python/lldbsuite/test/lang/c/const_variables/TestConstVariables.py7
-rw-r--r--packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py17
-rw-r--r--packages/Python/lldbsuite/test/lang/c/enum_types/main.c11
-rw-r--r--packages/Python/lldbsuite/test/lang/c/function_types/TestFunctionTypes.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py7
-rw-r--r--packages/Python/lldbsuite/test/lang/c/inlines/TestRedefinitionsInInlines.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/c/inlines/main.c19
-rw-r--r--packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py17
-rw-r--r--packages/Python/lldbsuite/test/lang/c/register_variables/Makefile2
-rw-r--r--packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py150
-rw-r--r--packages/Python/lldbsuite/test/lang/c/register_variables/test.c12
-rw-r--r--packages/Python/lldbsuite/test/lang/c/set_values/TestSetValues.py4
-rw-r--r--packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py7
-rw-r--r--packages/Python/lldbsuite/test/lang/c/step-target/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/lang/c/step-target/TestStepTarget.py113
-rw-r--r--packages/Python/lldbsuite/test/lang/c/step-target/main.c40
-rw-r--r--packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py16
-rw-r--r--packages/Python/lldbsuite/test/lang/c/strings/TestCStrings.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/c/struct_types/TestStructTypes.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/c/tls_globals/TestTlsGlobals.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/c/tls_globals/a.c6
-rw-r--r--packages/Python/lldbsuite/test/lang/c/tls_globals/main.c14
-rw-r--r--packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py7
-rw-r--r--packages/Python/lldbsuite/test/lang/c/unions/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/lang/c/unions/TestUnionMembers.py46
-rw-r--r--packages/Python/lldbsuite/test/lang/c/unions/main.c18
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/auto/TestCPPAuto.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/TestCPPBreakpointCommands.py4
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/call-function/TestCallCPPFunction.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/chained-calls/TestCppChainedCalls.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/char1632_t/TestChar1632T.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py17
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypes.py18
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypesDisassembly.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/const_this/Makefile8
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/const_this/TestConstThis.py4
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/const_this/main.cpp23
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/diamond/TestDiamond.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestCppValueCast.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestDynamicValue.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/exceptions/TestCPPExceptionBreakpoints.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/extern_c/Makefile3
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/extern_c/TestExternCSymbols.py4
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/extern_c/main.cpp29
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/TestFrameVariableAnonymousUnions.py8
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/gmodules/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py50
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h12
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py8
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/inlines/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/inlines/TestInlines.py52
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/inlines/inlines.cpp (renamed from packages/Python/lldbsuite/test/lang/c/inlines/inlines.c)2
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/inlines/inlines.h (renamed from packages/Python/lldbsuite/test/lang/c/inlines/inlines.h)0
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/lambdas/TestLambdas.py4
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/lambdas/main.cpp17
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/TestMembersAndLocalsWithSameName.py197
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/main.cpp73
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespace.py74
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespaceLookup.py17
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/Makefile19
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/TestNamespaceDefinitions.py57
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/a.cpp16
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/a.mk9
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/b.cpp12
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/b.mk9
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/foo.h18
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/main.cpp16
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/TestOverloadedFunctions.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/printf/TestPrintf.py4
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/printf/main.cpp21
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/rvalue-references/TestRvalueReferences.py7
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/scope/TestCppScope.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/signed_types/TestSignedTypes.py4
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/static_members/TestCPPStaticMembers.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/static_methods/TestCPPStaticMethods.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/stl/TestSTL.py8
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/stl/TestStdCXXDisassembly.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/template/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py87
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/template/main.cpp72
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/this/TestCPPThis.py11
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/unicode-literals/Makefile (renamed from packages/Python/lldbsuite/test/lang/cpp/rdar12991846/Makefile)0
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/unicode-literals/TestUnicodeLiterals.py (renamed from packages/Python/lldbsuite/test/lang/cpp/rdar12991846/TestRdar12991846.py)15
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/unicode-literals/main.cpp (renamed from packages/Python/lldbsuite/test/lang/cpp/rdar12991846/main.cpp)0
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/unsigned_types/TestUnsignedTypes.py2
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/virtual/TestVirtual.py22
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/virtual/main.cpp25
-rw-r--r--packages/Python/lldbsuite/test/lang/go/expressions/TestExpressions.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/go/formatters/TestGoFormatters.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/go/goroutines/TestGoroutines.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/go/runtime/TestGoLanguageRuntime2
-rw-r--r--packages/Python/lldbsuite/test/lang/go/types/TestGoASTContext.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/TestBitfieldIvars.py4
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/main.m52
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/blocks/TestObjCIvarsInBlocks.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/forward-decl/TestForwardDecl.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/foundation/TestConstStrings.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/foundation/TestFoundationDisassembly.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods2.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/foundation/TestObjectDescriptionAPI.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/foundation/TestRuntimeTypes.py4
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/foundation/TestSymbolTable.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/global_ptrs/TestGlobalObjects.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/hidden-ivars/TestHiddenIvars.py15
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/ivar-IMP/TestObjCiVarIMP.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/modules-auto-import/TestModulesAutoImport.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/modules-incomplete/TestIncompleteModules.py7
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/TestModulesInlineFunctions.py9
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/modules/TestObjCModules.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc++/TestObjCXX.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/TestObjCBaseClassSBType.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-checker/TestObjCCheckers.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-class-method/TestObjCClassMethod.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/TestObjCIvarOffsets.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-ivar-protocols/TestIvarProtocols.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/TestObjCIvarStripped.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-optimized/TestObjcOptimized.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-property/TestObjCProperty.py17
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-property/main.m13
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/TestRuntimeIvars.py6
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/Makefile3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/TestObjCStaticMethodStripped.py8
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-static-method/TestObjCStaticMethod.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-stepping/TestObjCStepping.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/TestObjCStructArgument.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-struct-return/TestObjCStructReturn.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/objc-super/TestObjCSuper.py5
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/print-obj/TestPrintObj.py2
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/radar-9691614/TestObjCMethodReturningBOOL.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/rdar-10967107/TestRdar10967107.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/rdar-11355592/TestRdar11355592.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/rdar-12408181/TestRdar12408181.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/real-definition/TestRealDefinition.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/self/TestObjCSelf.py3
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/TestObjCSingleEntryDictionary.py68
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/main.m7
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/variadic_methods/TestVariadicMethods.py4
-rw-r--r--packages/Python/lldbsuite/test/lang/objc/variadic_methods/main.m31
-rw-r--r--packages/Python/lldbsuite/test/lang/objcxx/objcxx-ivar-vector/TestIvarVector.py6
-rw-r--r--packages/Python/lldbsuite/test/linux/builtin_trap/TestBuiltinTrap.py4
-rw-r--r--packages/Python/lldbsuite/test/linux/thread/create_during_instruction_step/TestCreateDuringInstructionStep.py4
-rw-r--r--packages/Python/lldbsuite/test/lldbinline.py35
-rw-r--r--packages/Python/lldbsuite/test/lldbpexpect.py96
-rw-r--r--packages/Python/lldbsuite/test/lldbplatform.py44
-rw-r--r--packages/Python/lldbsuite/test/lldbplatformutil.py125
-rw-r--r--packages/Python/lldbsuite/test/lldbtest.py1064
-rw-r--r--packages/Python/lldbsuite/test/lldbutil.py47
-rw-r--r--packages/Python/lldbsuite/test/logging/TestLogging.py8
-rw-r--r--packages/Python/lldbsuite/test/macosx/add-dsym/TestAddDsymMidExecutionCommand.py2
-rw-r--r--packages/Python/lldbsuite/test/macosx/debug-info/apple_types/TestAppleTypesIsProduced.py2
-rw-r--r--packages/Python/lldbsuite/test/macosx/indirect_symbol/TestIndirectSymbols.py3
-rw-r--r--packages/Python/lldbsuite/test/macosx/nslog/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/macosx/nslog/TestDarwinNSLogOutput.py148
-rw-r--r--packages/Python/lldbsuite/test/macosx/nslog/main.m18
-rw-r--r--packages/Python/lldbsuite/test/macosx/order/TestOrderFile.py2
-rw-r--r--packages/Python/lldbsuite/test/macosx/queues/TestQueues.py3
-rw-r--r--packages/Python/lldbsuite/test/macosx/safe-to-func-call/TestSafeFuncCalls.py3
-rw-r--r--packages/Python/lldbsuite/test/macosx/universal/TestUniversal.py53
-rw-r--r--packages/Python/lldbsuite/test/macosx/universal/main.c14
-rw-r--r--packages/Python/lldbsuite/test/make/Makefile.rules37
-rw-r--r--packages/Python/lldbsuite/test/make/test_common.h42
-rw-r--r--packages/Python/lldbsuite/test/plugins/builder_base.py42
-rw-r--r--packages/Python/lldbsuite/test/plugins/builder_darwin.py4
-rw-r--r--packages/Python/lldbsuite/test/plugins/builder_linux.py (renamed from packages/Python/lldbsuite/test/plugins/builder_linux2.py)0
-rw-r--r--packages/Python/lldbsuite/test/python_api/breakpoint/TestBreakpointAPI.py3
-rw-r--r--packages/Python/lldbsuite/test/python_api/class_members/TestSBTypeClassMembers.py3
-rw-r--r--packages/Python/lldbsuite/test/python_api/debugger/TestDebuggerAPI.py3
-rw-r--r--packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py3
-rw-r--r--packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassembleRawData.py4
-rw-r--r--packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassemble_VST1_64.py5
-rw-r--r--packages/Python/lldbsuite/test/python_api/event/TestEvents.py19
-rw-r--r--packages/Python/lldbsuite/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py6
-rw-r--r--packages/Python/lldbsuite/test/python_api/findvalue_duplist/TestSBFrameFindValue.py3
-rw-r--r--packages/Python/lldbsuite/test/python_api/formatters/TestFormattersSBAPI.py3
-rw-r--r--packages/Python/lldbsuite/test/python_api/frame/TestFrames.py15
-rw-r--r--packages/Python/lldbsuite/test/python_api/frame/get-variables/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/python_api/frame/get-variables/TestGetVariables.py190
-rw-r--r--packages/Python/lldbsuite/test/python_api/frame/get-variables/main.c29
-rw-r--r--packages/Python/lldbsuite/test/python_api/frame/inlines/TestInlinedFrame.py8
-rw-r--r--packages/Python/lldbsuite/test/python_api/function_symbol/TestDisasmAPI.py3
-rw-r--r--packages/Python/lldbsuite/test/python_api/function_symbol/TestSymbolAPI.py3
-rw-r--r--packages/Python/lldbsuite/test/python_api/hello_world/TestHelloWorld.py23
-rw-r--r--packages/Python/lldbsuite/test/python_api/interpreter/TestCommandInterpreterAPI.py2
-rw-r--r--packages/Python/lldbsuite/test/python_api/lldbutil/frame/TestFrameUtils.py2
-rw-r--r--packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestLLDBIterator.py2
-rw-r--r--packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py4
-rw-r--r--packages/Python/lldbsuite/test/python_api/lldbutil/process/TestPrintStackTraces.py6
-rw-r--r--packages/Python/lldbsuite/test/python_api/module_section/TestModuleAndSection.py2
-rw-r--r--packages/Python/lldbsuite/test/python_api/objc_type/TestObjCType.py3
-rw-r--r--packages/Python/lldbsuite/test/python_api/process/TestProcessAPI.py20
-rw-r--r--packages/Python/lldbsuite/test/python_api/process/io/TestProcessIO.py8
-rw-r--r--packages/Python/lldbsuite/test/python_api/sbdata/TestSBData.py19
-rw-r--r--packages/Python/lldbsuite/test/python_api/sbtype_typeclass/TestSBTypeTypeClass.py6
-rw-r--r--packages/Python/lldbsuite/test/python_api/sbvalue_persist/TestSBValuePersist.py5
-rw-r--r--packages/Python/lldbsuite/test/python_api/section/TestSectionAPI.py3
-rw-r--r--packages/Python/lldbsuite/test/python_api/signals/TestSignalsAPI.py5
-rw-r--r--packages/Python/lldbsuite/test/python_api/symbol-context/TestSymbolContext.py9
-rw-r--r--packages/Python/lldbsuite/test/python_api/symbol-context/two-files/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/python_api/symbol-context/two-files/TestSymbolContextTwoFiles.py36
-rw-r--r--packages/Python/lldbsuite/test/python_api/symbol-context/two-files/decls.h11
-rw-r--r--packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file1.cpp13
-rw-r--r--packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file2.cpp6
-rw-r--r--packages/Python/lldbsuite/test/python_api/target/TestTargetAPI.py5
-rw-r--r--packages/Python/lldbsuite/test/python_api/thread/TestThreadAPI.py8
-rw-r--r--packages/Python/lldbsuite/test/python_api/type/TestTypeList.py7
-rw-r--r--packages/Python/lldbsuite/test/python_api/value/TestValueAPI.py20
-rw-r--r--packages/Python/lldbsuite/test/python_api/value/change_values/TestChangeValueAPI.py5
-rw-r--r--packages/Python/lldbsuite/test/python_api/value/linked_list/TestValueAPILinkedList.py3
-rw-r--r--packages/Python/lldbsuite/test/python_api/value/main.c4
-rw-r--r--packages/Python/lldbsuite/test/python_api/value_var_update/TestValueVarUpdate.py2
-rw-r--r--packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py6
-rw-r--r--packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py6
-rw-r--r--packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py11
-rw-r--r--packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py4
-rw-r--r--packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py9
-rw-r--r--packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py6
-rw-r--r--packages/Python/lldbsuite/test/settings/TestSettings.py12
-rw-r--r--packages/Python/lldbsuite/test/settings/quoting/TestQuoting.py19
-rw-r--r--packages/Python/lldbsuite/test/source-manager/TestSourceManager.py38
-rw-r--r--packages/Python/lldbsuite/test/terminal/TestSTTYBeforeAndAfter.py4
-rw-r--r--packages/Python/lldbsuite/test/test_categories.py22
-rw-r--r--packages/Python/lldbsuite/test/test_result.py45
-rw-r--r--packages/Python/lldbsuite/test/test_runner/__init__.py0
-rw-r--r--packages/Python/lldbsuite/test/test_runner/process_control.py (renamed from packages/Python/lldbsuite/test/test_runner/lib/process_control.py)0
-rw-r--r--packages/Python/lldbsuite/test/test_runner/test/__init__.py0
-rwxr-xr-xpackages/Python/lldbsuite/test/test_runner/test/test_process_control.py (renamed from packages/Python/lldbsuite/test/test_runner/test/process_control_tests.py)13
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/TestMiExit.py10
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/TestMiFile.py2
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/TestMiGdbSetShow.py20
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/TestMiLibraryLoaded.py2
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/TestMiPrompt.py2
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/breakpoint/TestMiBreak.py49
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py14
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/data/TestMiData.py2
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/interpreter/TestMiCliSupport.py2
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/interpreter/TestMiInterpreterExec.py6
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/signal/TestMiSignal.py2
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/stack/TestMiStack.py15
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/stack/main.cpp15
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py4
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/symbol/TestMiSymbol.py4
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/syntax/TestMiSyntax.py4
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/target/TestMiTarget.py4
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/TestMiThreadInfo.py39
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/test_threadinfo.cpp21
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py6
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiVar.py6
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestGDBRemoteMemoryRead.py12
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAttach.py3
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAuxvSupport.py4
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py2
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteKill.py3
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteProcessInfo.py7
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py4
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteSingleStep.py5
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py4
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py2
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_vCont.py10
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py25
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubReverseConnect.py2
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubSetSID.py4
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py155
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteAbort.py2
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteSegFault.py2
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py14
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py28
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/socket_packet_pump.py60
-rw-r--r--packages/Python/lldbsuite/test/types/TestFloatTypes.py5
-rw-r--r--packages/Python/lldbsuite/test/types/TestFloatTypesExpr.py6
-rw-r--r--packages/Python/lldbsuite/test/types/TestIntegerTypes.py7
-rw-r--r--packages/Python/lldbsuite/test/types/TestIntegerTypesExpr.py6
-rw-r--r--packages/Python/lldbsuite/test/warnings/uuid/TestAddDsymCommand.py2
-rw-r--r--packages/Python/lldbsuite/test_event/__init__.py0
-rw-r--r--packages/Python/lldbsuite/test_event/build_exception.py14
-rw-r--r--packages/Python/lldbsuite/test_event/dotest_channels.py (renamed from packages/Python/lldbsuite/test/dotest_channels.py)7
-rw-r--r--packages/Python/lldbsuite/test_event/event_builder.py475
-rw-r--r--packages/Python/lldbsuite/test_event/formatter/__init__.py162
-rw-r--r--packages/Python/lldbsuite/test_event/formatter/curses.py (renamed from packages/Python/lldbsuite/test/curses_results.py)35
-rw-r--r--packages/Python/lldbsuite/test_event/formatter/dump_formatter.py23
-rw-r--r--packages/Python/lldbsuite/test_event/formatter/pickled.py72
-rw-r--r--packages/Python/lldbsuite/test_event/formatter/results_formatter.py (renamed from packages/Python/lldbsuite/test/result_formatter.py)619
-rw-r--r--packages/Python/lldbsuite/test_event/formatter/xunit.py (renamed from packages/Python/lldbsuite/test/xunit_formatter.py)67
-rw-r--r--packages/Python/lldbsuite/test_event/test/resources/invalid_decorator/TestInvalidDecorator.py13
-rw-r--r--packages/Python/lldbsuite/test_event/test/src/TestCatchInvalidDecorator.py70
-rw-r--r--packages/Python/lldbsuite/test_event/test/src/event_collector.py85
-rw-r--r--resources/LLDB-Info.plist2
-rw-r--r--scripts/CMakeLists.txt2
-rw-r--r--scripts/Makefile17
-rw-r--r--scripts/Python/Makefile15
-rw-r--r--scripts/Python/finishSwigPythonLLDB.py63
-rw-r--r--scripts/Python/modules/Makefile20
-rw-r--r--scripts/Python/modules/readline/Makefile100
-rw-r--r--scripts/Python/modules/readline/readline.cpp34
-rw-r--r--scripts/Python/prepare_binding_Python.py4
-rw-r--r--scripts/Python/python-extensions.swig80
-rw-r--r--scripts/Python/python-typemaps.swig225
-rw-r--r--scripts/Python/python-wrapper.swig2
-rw-r--r--scripts/Python/use_lldb_suite.py9
-rwxr-xr-xscripts/Xcode/build-llvm.py373
-rw-r--r--scripts/Xcode/lldbbuild.py135
-rw-r--r--scripts/Xcode/package-clang-headers.py (renamed from scripts/package-clang-headers.py)4
-rw-r--r--scripts/build-llvm.pl407
-rw-r--r--scripts/finishSwigWrapperClasses.py11
-rw-r--r--scripts/interface/SBCommandReturnObject.i16
-rw-r--r--scripts/interface/SBDebugger.i10
-rw-r--r--scripts/interface/SBExpressionOptions.i14
-rw-r--r--scripts/interface/SBFileSpec.i5
-rw-r--r--scripts/interface/SBHostOS.i3
-rw-r--r--scripts/interface/SBMemoryRegionInfo.i58
-rw-r--r--scripts/interface/SBMemoryRegionInfoList.i38
-rw-r--r--scripts/interface/SBProcess.i14
-rw-r--r--scripts/interface/SBTarget.i54
-rw-r--r--scripts/interface/SBThread.i28
-rw-r--r--scripts/interface/SBValue.i23
-rw-r--r--scripts/lldb.swig4
-rwxr-xr-xscripts/prepare_bindings.py5
-rw-r--r--scripts/use_lldb_suite.py9
-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
-rw-r--r--test/CMakeLists.txt4
-rw-r--r--test/use_lldb_suite.py9
-rw-r--r--tools/Makefile30
-rw-r--r--tools/compact-unwind/compact-unwind-dumper.c348
-rw-r--r--tools/debugserver/Makefile13
-rw-r--r--tools/debugserver/debugserver.xcodeproj/project.pbxproj79
-rw-r--r--tools/debugserver/source/DNB.cpp56
-rw-r--r--tools/debugserver/source/DNB.h4
-rw-r--r--tools/debugserver/source/DNBDataRef.cpp5
-rw-r--r--tools/debugserver/source/MacOSX/CMakeLists.txt48
-rw-r--r--tools/debugserver/source/MacOSX/MachException.cpp1
-rw-r--r--tools/debugserver/source/MacOSX/MachProcess.h54
-rw-r--r--tools/debugserver/source/MacOSX/MachProcess.mm544
-rw-r--r--tools/debugserver/source/MacOSX/MachTask.h20
-rw-r--r--tools/debugserver/source/MacOSX/MachTask.mm85
-rw-r--r--tools/debugserver/source/MacOSX/Makefile54
-rw-r--r--tools/debugserver/source/MacOSX/i386/Makefile19
-rw-r--r--tools/debugserver/source/MacOSX/x86_64/Makefile19
-rw-r--r--tools/debugserver/source/Makefile46
-rw-r--r--tools/debugserver/source/RNBDefs.h21
-rw-r--r--tools/debugserver/source/RNBRemote.cpp251
-rw-r--r--tools/debugserver/source/RNBRemote.h2
-rw-r--r--tools/debugserver/source/debugserver.cpp11
-rw-r--r--tools/driver/Driver.cpp145
-rw-r--r--tools/driver/Driver.h6
-rw-r--r--tools/driver/Makefile36
-rw-r--r--tools/driver/Platform.cpp40
-rw-r--r--tools/driver/Platform.h15
-rw-r--r--tools/driver/lldb-Info.plist2
-rw-r--r--tools/lldb-mi/CMakeLists.txt5
-rw-r--r--tools/lldb-mi/MICmdCmdBreak.cpp26
-rw-r--r--tools/lldb-mi/MICmdCmdData.cpp9
-rw-r--r--tools/lldb-mi/MICmdCmdData.h2
-rw-r--r--tools/lldb-mi/MICmdCmdThread.cpp23
-rw-r--r--tools/lldb-mi/MICmdCmdThread.h4
-rw-r--r--tools/lldb-mi/MICmdCmdVar.cpp4
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp16
-rw-r--r--tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp3
-rw-r--r--tools/lldb-mi/MIUtilFileStd.cpp14
-rw-r--r--tools/lldb-mi/Makefile32
-rw-r--r--tools/lldb-mi/Platform.cpp49
-rw-r--r--tools/lldb-mi/Platform.h11
-rw-r--r--tools/lldb-server/Makefile25
-rw-r--r--tools/lldb-server/lldb-gdbserver.cpp105
-rw-r--r--tools/lldb-server/lldb-server.cpp36
-rw-r--r--unittests/CMakeLists.txt18
-rw-r--r--unittests/Core/CMakeLists.txt4
-rw-r--r--unittests/Core/DataExtractorTest.cpp39
-rw-r--r--unittests/Core/ScalarTest.cpp105
-rw-r--r--unittests/Editline/EditlineTest.cpp74
-rw-r--r--unittests/Host/CMakeLists.txt1
-rw-r--r--unittests/Host/FileSpecTest.cpp111
-rw-r--r--unittests/Host/SocketAddressTest.cpp7
-rw-r--r--unittests/Host/SocketTest.cpp12
-rw-r--r--unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp54
-rw-r--r--unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp2
-rw-r--r--unittests/ScriptInterpreter/Python/PythonTestSuite.cpp1
-rw-r--r--unittests/Symbol/CMakeLists.txt3
-rw-r--r--unittests/Symbol/TestClangASTContext.cpp315
-rw-r--r--unittests/SymbolFile/CMakeLists.txt1
-rw-r--r--unittests/SymbolFile/PDB/CMakeLists.txt12
-rw-r--r--unittests/SymbolFile/PDB/Inputs/test-dwarf.cpp14
-rw-r--r--unittests/SymbolFile/PDB/Inputs/test-dwarf.exebin0 -> 6144 bytes
-rw-r--r--unittests/SymbolFile/PDB/Inputs/test-pdb-alt.cpp9
-rw-r--r--unittests/SymbolFile/PDB/Inputs/test-pdb-nested.h9
-rw-r--r--unittests/SymbolFile/PDB/Inputs/test-pdb-types.cpp86
-rw-r--r--unittests/SymbolFile/PDB/Inputs/test-pdb-types.exebin0 -> 7168 bytes
-rw-r--r--unittests/SymbolFile/PDB/Inputs/test-pdb-types.pdbbin0 -> 143360 bytes
-rw-r--r--unittests/SymbolFile/PDB/Inputs/test-pdb.cpp15
-rw-r--r--unittests/SymbolFile/PDB/Inputs/test-pdb.exebin0 -> 7168 bytes
-rw-r--r--unittests/SymbolFile/PDB/Inputs/test-pdb.h13
-rw-r--r--unittests/SymbolFile/PDB/Inputs/test-pdb.pdbbin0 -> 110592 bytes
-rw-r--r--unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp583
-rw-r--r--unittests/Utility/CMakeLists.txt3
-rw-r--r--unittests/Utility/Inputs/TestModule.c10
-rw-r--r--unittests/Utility/Inputs/TestModule.sobin0 -> 5602 bytes
-rw-r--r--unittests/Utility/ModuleCacheTest.cpp179
-rwxr-xr-xwww/build.html82
-rwxr-xr-xwww/status.html396
-rw-r--r--www/test.html122
1612 files changed, 59348 insertions, 32458 deletions
diff --git a/.arcconfig b/.arcconfig
index eb16f4cea996..e8fa2aaf0bd4 100644
--- a/.arcconfig
+++ b/.arcconfig
@@ -1,4 +1,4 @@
{
"project_id" : "lldb",
- "conduit_uri" : "http://reviews.llvm.org/"
+ "conduit_uri" : "https://reviews.llvm.org/"
}
diff --git a/.gitignore b/.gitignore
index 06cb7040f33b..5ad21731aab5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,7 @@ DerivedData/
build/
pyproj/
llvm-build/
+ninja/
*xcuserdata
test/20*
__pycache__/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 82dd78c125a5..e092e0bd4abc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.4.3)
include(cmake/modules/LLDBStandalone.cmake)
include(cmake/modules/LLDBConfig.cmake)
@@ -31,7 +31,7 @@ add_subdirectory(lit)
if (NOT LLDB_DISABLE_PYTHON)
# Add a Post-Build Event to copy over Python files and create the symlink to liblldb.so for the Python API(hardlink on Windows)
add_custom_target( finish_swig ALL
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py "--srcRoot=${LLDB_SOURCE_DIR}" "--targetDir=${CMAKE_CURRENT_BINARY_DIR}/scripts" "--cfgBldDir=${CMAKE_CURRENT_BINARY_DIR}/scripts" "--prefix=${CMAKE_BINARY_DIR}" "--cmakeBuildConfiguration=${CMAKE_CFG_INTDIR}" -m
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py "--srcRoot=${LLDB_SOURCE_DIR}" "--targetDir=${CMAKE_CURRENT_BINARY_DIR}/scripts" "--cfgBldDir=${CMAKE_CURRENT_BINARY_DIR}/scripts" "--prefix=${CMAKE_BINARY_DIR}" "--cmakeBuildConfiguration=${CMAKE_CFG_INTDIR}" "--lldbLibDir=lib${LLVM_LIBDIR_SUFFIX}" -m
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/scripts/lldb.py
COMMENT "Python script sym-linking LLDB Python API")
diff --git a/Makefile b/Makefile
deleted file mode 100644
index e794ae8e9a86..000000000000
--- a/Makefile
+++ /dev/null
@@ -1,112 +0,0 @@
-##===- Makefile --------------------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-# If LLDB_LEVEL is not set, then we are the top-level Makefile. Otherwise, we
-# are being included from a subdirectory makefile.
-
-ifndef LLDB_LEVEL
-
-
-IS_TOP_LEVEL := 1
-LLDB_LEVEL := .
-DIRS := include scripts source lib tools
-
-PARALLEL_DIRS :=
-endif
-
-###
-# Common Makefile code, shared by all LLDB Makefiles.
-
-# Set LLVM source root level.
-LEVEL := $(LLDB_LEVEL)/../..
-
-# Include LLVM common makefile.
-include $(LEVEL)/Makefile.common
-
-# Set common LLDB build flags.
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/include
-CPP.Flags += -I$(PROJ_OBJ_DIR)/$(LLDB_LEVEL)/include
-CPP.Flags += -I$(LLVM_SRC_ROOT)/tools/clang/include
-CPP.Flags += -I$(LLVM_OBJ_ROOT)/tools/clang/include
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Utility
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/Utility
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/POSIX
-
-# Disable python and curses on mingw build
-ifeq ($(HOST_OS),MingW)
-CXXFLAGS += -DLLDB_DISABLE_PYTHON -DLLDB_DISABLE_CURSES
-endif
-
-ifeq (,$(findstring -DLLDB_DISABLE_PYTHON,$(CXXFLAGS)))
-# Set Python include directory
-PYTHON_CONFIG?= python-config
-PYTHON_INC_DIR = $(shell $(PYTHON_CONFIG) --includes)
-CPP.Flags += $(PYTHON_INC_DIR)
-endif
-
-ifeq ($(HOST_OS),Darwin)
-CPP.Flags += $(subst -I,-I$(SDKROOT),$(PYTHON_INC_DIR))
-CPP.Flags += -F$(SDKROOT)/System/Library/Frameworks
-CPP.Flags += -F$(SDKROOT)/System/Library/PrivateFrameworks
-CPP.Flags += -I$(SDKROOT)/usr/include/libxml2
-endif
-ifdef LLDB_VENDOR
-CPP.Flags += -DLLDB_VENDOR='"$(LLDB_VENDOR) "'
-endif
-
-# If building on a 32-bit system, make sure off_t can store offsets > 2GB
-ifneq "$(HOST_ARCH)" "x86_64"
-CPP.Flags += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
-endif
-
-# Disable -fstrict-aliasing. Darwin disables it by default (and LLVM doesn't
-# work with it enabled with GCC), Clang/llvm-gc don't support it yet, and newer
-# GCC's have false positive warnings with it on Linux (which prove a pain to
-# fix). For example:
-# http://gcc.gnu.org/PR41874
-# http://gcc.gnu.org/PR41838
-#
-# We can revisit this when LLVM/Clang support it.
-CXX.Flags += -fno-strict-aliasing
-
-# Do not warn about pragmas. In particular, we are looking to ignore the
-# "#pragma mark" construct which GCC warns about on platforms other than Darwin.
-EXTRA_OPTIONS += -Wno-unknown-pragmas
-
-# Drop -Wsign-compare, which we are not currently clean with.
-EXTRA_OPTIONS += -Wno-sign-compare
-
-###
-# LLDB Top Level specific stuff.
-
-ifeq ($(IS_TOP_LEVEL),1)
-
-test::
- @ $(MAKE) -C test
-
-#report::
-# @ $(MAKE) -C test report
-
-#clean::
-# @ $(MAKE) -C test clean
-
-tags::
- $(Verb) etags `find . -type f -name '*.h' -or -name '*.cpp' | \
- grep -v /lib/Headers | grep -v /test/`
-
-cscope.files:
- find tools lib include -name '*.cpp' \
- -or -name '*.def' \
- -or -name '*.td' \
- -or -name '*.h' > cscope.files
-
-.PHONY: test report clean cscope.files
-
-endif
diff --git a/cmake/LLDBDependencies.cmake b/cmake/LLDBDependencies.cmake
index 073fa28b2528..67d110e0a544 100644
--- a/cmake/LLDBDependencies.cmake
+++ b/cmake/LLDBDependencies.cmake
@@ -15,6 +15,7 @@ set( LLDB_USED_LIBS
# Plugins
lldbPluginDisassemblerLLVM
lldbPluginSymbolFileDWARF
+ lldbPluginSymbolFilePDB
lldbPluginSymbolFileSymtab
lldbPluginDynamicLoaderStatic
lldbPluginDynamicLoaderPosixDYLD
@@ -23,6 +24,7 @@ set( LLDB_USED_LIBS
lldbPluginCPlusPlusLanguage
lldbPluginGoLanguage
+ lldbPluginJavaLanguage
lldbPluginObjCLanguage
lldbPluginObjCPlusPlusLanguage
@@ -50,6 +52,7 @@ set( LLDB_USED_LIBS
lldbPluginAppleObjCRuntime
lldbPluginRenderScriptRuntime
lldbPluginLanguageRuntimeGo
+ lldbPluginLanguageRuntimeJava
lldbPluginCXXItaniumABI
lldbPluginABIMacOSX_arm
lldbPluginABIMacOSX_arm64
@@ -63,6 +66,7 @@ set( LLDB_USED_LIBS
lldbPluginABISysV_ppc64
lldbPluginABISysV_mips
lldbPluginABISysV_mips64
+ lldbPluginABISysV_s390x
lldbPluginInstructionARM
lldbPluginInstructionARM64
lldbPluginInstructionMIPS
@@ -72,6 +76,7 @@ set( LLDB_USED_LIBS
lldbPluginOSPython
lldbPluginMemoryHistoryASan
lldbPluginInstrumentationRuntimeAddressSanitizer
+ lldbPluginInstrumentationRuntimeThreadSanitizer
lldbPluginSystemRuntimeMacOSX
lldbPluginProcessElfCore
lldbPluginJITLoaderGDB
@@ -152,6 +157,11 @@ if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows" AND NOT __ANDROID_NDK__)
endif()
endif()
endif()
+
+if (NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB )
+ list(APPEND LLDB_SYSTEM_LIBS atomic)
+endif()
+
# On FreeBSD/NetBSD backtrace() is provided by libexecinfo, not libc.
if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR CMAKE_SYSTEM_NAME MATCHES "NetBSD")
list(APPEND LLDB_SYSTEM_LIBS execinfo)
@@ -172,7 +182,7 @@ if (LLVM_BUILD_STATIC)
endif()
endif()
-set( LLVM_LINK_COMPONENTS
+set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
interpreter
asmparser
@@ -190,6 +200,7 @@ set( LLVM_LINK_COMPONENTS
runtimedyld
option
support
+ coverage
)
if ( NOT LLDB_DISABLE_PYTHON )
diff --git a/cmake/modules/AddLLDB.cmake b/cmake/modules/AddLLDB.cmake
index 75c522f6522e..af16050769ad 100644
--- a/cmake/modules/AddLLDB.cmake
+++ b/cmake/modules/AddLLDB.cmake
@@ -68,7 +68,7 @@ macro(add_lldb_library name)
target_link_libraries(${name} ${cmake_2_8_12_PUBLIC} ${CLANG_USED_LIBS})
endif()
endif()
- llvm_config(${name} ${LLVM_LINK_COMPONENTS})
+ llvm_config(${name} ${LLVM_LINK_COMPONENTS} ${LLVM_PRIVATE_LINK_COMPONENTS})
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "liblldb")
if (PARAM_SHARED)
diff --git a/cmake/modules/LLDBConfig.cmake b/cmake/modules/LLDBConfig.cmake
index f5247a269822..d0700b0c22e3 100644
--- a/cmake/modules/LLDBConfig.cmake
+++ b/cmake/modules/LLDBConfig.cmake
@@ -1,3 +1,5 @@
+include(CheckCXXSymbolExists)
+
set(LLDB_PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
set(LLDB_SOURCE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/source")
set(LLDB_INCLUDE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/include")
@@ -245,6 +247,11 @@ if( MSVC )
)
endif()
+# Use the Unicode (UTF-16) APIs by default on Win32
+if (CMAKE_SYSTEM_NAME MATCHES "Windows")
+ add_definitions( /D _UNICODE /D UNICODE )
+endif()
+
set(LLDB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(LLDB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
@@ -331,28 +338,6 @@ if (HAVE_LIBDL)
list(APPEND system_libs ${CMAKE_DL_LIBS})
endif()
-if(LLDB_REQUIRES_EH)
- set(LLDB_REQUIRES_RTTI ON)
-else()
- if(LLVM_COMPILER_IS_GCC_COMPATIBLE)
- set(LLDB_COMPILE_FLAGS "${LLDB_COMPILE_FLAGS} -fno-exceptions")
- elseif(MSVC)
- add_definitions( -D_HAS_EXCEPTIONS=0 )
- set(LLDB_COMPILE_FLAGS "${LLDB_COMPILE_FLAGS} /EHs-c-")
- endif()
-endif()
-
-# Disable RTTI by default
-if(NOT LLDB_REQUIRES_RTTI)
- if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
- set(LLDB_COMPILE_FLAGS "${LLDB_COMPILE_FLAGS} -fno-rtti")
- elseif(MSVC)
- set(LLDB_COMPILE_FLAGS "${LLDB_COMPILE_FLAGS} /GR-")
- endif()
-endif()
-
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLDB_COMPILE_FLAGS}")
-
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
# Check for syscall used by lldb-server on linux.
# If these are not found, it will fall back to ptrace (slow) for memory reads.
@@ -410,3 +395,25 @@ if (NOT LLDB_DISABLE_CURSES)
list(APPEND system_libs ${CURSES_LIBRARIES})
include_directories(${CURSES_INCLUDE_DIR})
endif ()
+
+check_cxx_symbol_exists("__GLIBCXX__" "string" LLDB_USING_LIBSTDCXX)
+if(LLDB_USING_LIBSTDCXX)
+ # There doesn't seem to be an easy way to check the library version. Instead, we rely on the
+ # fact that std::set did not have the allocator constructor available until version 4.9
+ check_cxx_source_compiles("
+ #include <set>
+ std::set<int> s = std::set<int>(std::allocator<int>());
+ int main() { return 0; }"
+ LLDB_USING_LIBSTDCXX_4_9)
+ if (NOT LLDB_USING_LIBSTDCXX_4_9 AND NOT LLVM_ENABLE_EH)
+ message(WARNING
+ "You appear to be linking to libstdc++ version lesser than 4.9 without exceptions "
+ "enabled. These versions of the library have an issue, which causes occasional "
+ "lldb crashes. See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59656> for "
+ "details. Possible courses of action are:\n"
+ "- use libstdc++ version 4.9 or newer\n"
+ "- use libc++ (via LLVM_ENABLE_LIBCXX)\n"
+ "- enable exceptions (via LLVM_ENABLE_EH)\n"
+ "- ignore this warning and accept occasional instability")
+ endif()
+endif()
diff --git a/cmake/modules/LLDBStandalone.cmake b/cmake/modules/LLDBStandalone.cmake
index d3955f1cdf6b..d849602c57b6 100644
--- a/cmake/modules/LLDBStandalone.cmake
+++ b/cmake/modules/LLDBStandalone.cmake
@@ -2,64 +2,91 @@
# standalone project, using LLVM as an external library:
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
project(lldb)
- cmake_minimum_required(VERSION 2.8)
+ cmake_minimum_required(VERSION 2.8.12.2)
- option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF)
+ if (POLICY CMP0022)
+ cmake_policy(SET CMP0022 NEW) # automatic when 2.8.12 is required
+ endif()
- set(LLDB_PATH_TO_LLVM_SOURCE "" CACHE PATH
- "Path to LLVM source code. Not necessary if using an installed LLVM.")
- set(LLDB_PATH_TO_LLVM_BUILD "" CACHE PATH
- "Path to the directory where LLVM was built or installed.")
+ option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF)
- set(LLDB_PATH_TO_CLANG_SOURCE "" CACHE PATH
- "Path to Clang source code. Not necessary if using an installed Clang.")
- set(LLDB_PATH_TO_CLANG_BUILD "" CACHE PATH
- "Path to the directory where Clang was built or installed.")
+ # Rely on llvm-config.
+ set(CONFIG_OUTPUT)
+ find_program(LLVM_CONFIG "llvm-config")
+ if(LLVM_CONFIG)
+ message(STATUS "Found LLVM_CONFIG as ${LLVM_CONFIG}")
+ set(CONFIG_COMMAND ${LLVM_CONFIG}
+ "--assertion-mode"
+ "--bindir"
+ "--libdir"
+ "--includedir"
+ "--prefix"
+ "--src-root")
+ execute_process(
+ COMMAND ${CONFIG_COMMAND}
+ RESULT_VARIABLE HAD_ERROR
+ OUTPUT_VARIABLE CONFIG_OUTPUT
+ )
+ if(NOT HAD_ERROR)
+ string(REGEX REPLACE
+ "[ \t]*[\r\n]+[ \t]*" ";"
+ CONFIG_OUTPUT ${CONFIG_OUTPUT})
- if (LLDB_PATH_TO_LLVM_SOURCE)
- if (NOT EXISTS "${LLDB_PATH_TO_LLVM_SOURCE}/cmake/config-ix.cmake")
- message(FATAL_ERROR "Please set LLDB_PATH_TO_LLVM_SOURCE to the root "
- "directory of LLVM source code.")
else()
- get_filename_component(LLVM_MAIN_SRC_DIR ${LLDB_PATH_TO_LLVM_SOURCE}
- ABSOLUTE)
- set(LLVM_MAIN_INCLUDE_DIR "${LLVM_MAIN_SRC_DIR}/include")
- list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules")
+ string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}")
+ message(STATUS "${CONFIG_COMMAND_STR}")
+ message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}")
endif()
+ else()
+ message(FATAL_ERROR "llvm-config not found -- ${LLVM_CONFIG}")
endif()
- if (LLDB_PATH_TO_CLANG_SOURCE)
- get_filename_component(CLANG_MAIN_SRC_DIR ${LLDB_PATH_TO_CLANG_SOURCE}
- ABSOLUTE)
- set(CLANG_MAIN_INCLUDE_DIR "${CLANG_MAIN_SRC_DIR}/include")
- endif()
-
- list(APPEND CMAKE_MODULE_PATH "${LLDB_PATH_TO_LLVM_BUILD}/share/llvm/cmake")
-
- if (LLDB_PATH_TO_LLVM_BUILD)
- get_filename_component(PATH_TO_LLVM_BUILD ${LLDB_PATH_TO_LLVM_BUILD}
- ABSOLUTE)
- else()
- message(FATAL_ERROR "Please set LLDB_PATH_TO_LLVM_BUILD to the root "
- "directory of LLVM build or install site.")
+ list(GET CONFIG_OUTPUT 0 ENABLE_ASSERTIONS)
+ list(GET CONFIG_OUTPUT 1 TOOLS_BINARY_DIR)
+ list(GET CONFIG_OUTPUT 2 LIBRARY_DIR)
+ list(GET CONFIG_OUTPUT 3 INCLUDE_DIR)
+ list(GET CONFIG_OUTPUT 4 LLVM_OBJ_ROOT)
+ list(GET CONFIG_OUTPUT 5 MAIN_SRC_DIR)
+
+ if(NOT MSVC_IDE)
+ set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS}
+ CACHE BOOL "Enable assertions")
+ # Assertions should follow llvm-config's.
+ mark_as_advanced(LLVM_ENABLE_ASSERTIONS)
endif()
- if (LLDB_PATH_TO_CLANG_BUILD)
- get_filename_component(PATH_TO_CLANG_BUILD ${LLDB_PATH_TO_CLANG_BUILD}
- ABSOLUTE)
+ set(LLVM_TOOLS_BINARY_DIR ${TOOLS_BINARY_DIR} CACHE PATH "Path to llvm/bin")
+ set(LLVM_LIBRARY_DIR ${LIBRARY_DIR} CACHE PATH "Path to llvm/lib")
+ set(LLVM_MAIN_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include")
+ set(LLVM_DIR ${LLVM_OBJ_ROOT}/cmake/modules/CMakeFiles CACHE PATH "Path to LLVM build tree CMake files")
+ set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree")
+ set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree")
+
+ find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR}
+ NO_DEFAULT_PATH)
+
+ set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
+ set(LLVMCONFIG_FILE "${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
+ if(EXISTS ${LLVMCONFIG_FILE})
+ list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
+ include(${LLVMCONFIG_FILE})
else()
- message(FATAL_ERROR "Please set LLDB_PATH_TO_CLANG_BUILD to the root "
- "directory of Clang build or install site.")
+ message(FATAL_ERROR "Not found: ${LLVMCONFIG_FILE}")
endif()
-
- # These variables are used by add_llvm_library.
+ # They are used as destination of target generators.
set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX})
- set(LLVM_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
+ if(WIN32 OR CYGWIN)
+ # DLL platform -- put DLLs into bin.
+ set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
+ else()
+ set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
+ endif()
include(AddLLVM)
include(HandleLLVMOptions)
+ include(CheckAtomic)
if (PYTHON_EXECUTABLE STREQUAL "")
set(Python_ADDITIONAL_VERSIONS 3.5 3.4 3.3 3.2 3.1 3.0 2.7 2.6 2.5)
@@ -72,10 +99,12 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
else()
message("-- Found PythonInterp: ${PYTHON_EXECUTABLE}")
endif()
+
# Import CMake library targets from LLVM and Clang.
- include("${LLDB_PATH_TO_LLVM_BUILD}/share/llvm/cmake/LLVMConfig.cmake")
- if (EXISTS "${LLDB_PATH_TO_CLANG_BUILD}/share/clang/cmake/ClangConfig.cmake")
- include("${LLDB_PATH_TO_CLANG_BUILD}/share/clang/cmake/ClangConfig.cmake")
+ include("${LLVM_OBJ_ROOT}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm/LLVMConfig.cmake")
+ # cmake/clang/ClangConfig.cmake is not created when LLVM and Cland are built together.
+ if (EXISTS "${LLVM_OBJ_ROOT}/lib${LLVM_LIBDIR_SUFFIX}/cmake/clang/ClangConfig.cmake")
+ include("${LLVM_OBJ_ROOT}/lib${LLVM_LIBDIR_SUFFIX}/cmake/clang/ClangConfig.cmake")
endif()
set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
@@ -83,13 +112,19 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(LLVM_BINARY_DIR ${CMAKE_BINARY_DIR})
set(CMAKE_INCLUDE_CURRENT_DIR ON)
- include_directories("${PATH_TO_LLVM_BUILD}/include"
- "${LLVM_MAIN_INCLUDE_DIR}"
- "${PATH_TO_CLANG_BUILD}/include"
- "${CLANG_MAIN_INCLUDE_DIR}"
- "${CMAKE_CURRENT_SOURCE_DIR}/source")
- link_directories("${PATH_TO_LLVM_BUILD}/lib${LLVM_LIBDIR_SUFFIX}"
- "${PATH_TO_CLANG_BUILD}/lib${LLVM_LIBDIR_SUFFIX}")
+ include_directories("${LLVM_BINARY_DIR}/include" "${LLVM_MAIN_INCLUDE_DIR}")
+ # Next three include directories are needed when llvm-config is located in build directory.
+ # LLVM and Cland are assumed to be built together
+ if (EXISTS "${LLVM_OBJ_ROOT}/include")
+ include_directories("${LLVM_OBJ_ROOT}/include")
+ endif()
+ if (EXISTS "${LLVM_MAIN_SRC_DIR}/tools/clang/include")
+ include_directories("${LLVM_MAIN_SRC_DIR}/tools/clang/include")
+ endif()
+ if (EXISTS "${LLVM_OBJ_ROOT}/tools/clang/include")
+ include_directories("${LLVM_OBJ_ROOT}/tools/clang/include")
+ endif()
+ link_directories("${LLVM_LIBRARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX})
diff --git a/cmake/platforms/Android.cmake b/cmake/platforms/Android.cmake
index 98b695be6ef6..9aad65cbe13e 100644
--- a/cmake/platforms/Android.cmake
+++ b/cmake/platforms/Android.cmake
@@ -165,6 +165,15 @@ set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
################# BEGIN EVIL HACK ##################
+# In the android-arm NDK unwind.h and link.h contains 2 conflicting
+# typedef for _Unwind_Ptr. Force HAVE_UNWIND_BACKTRACE to 0 to prevent
+# LLVM from finding unwind.h what would break the build.
+if ( ANDROID_ABI STREQUAL "armeabi" )
+ set( HAVE_UNWIND_BACKTRACE 0 CACHE INTERNAL "Hack to disable the finding of unwind.h on Android arm" )
+endif()
+################# END EVIL HACK ####################
+
+################# BEGIN EVIL HACK ##################
# lldb-server links against libdl even though it's not being used and
# libdl.a is currently missing from the toolchain (b.android.com/178517).
# Therefore, in order to statically link lldb-server, we need a temporary
@@ -178,7 +187,8 @@ if( LLVM_BUILD_STATIC )
void * dlopen (const char *filename, int flag) { return 0; }
const char * dlerror (void) { return 0; }
void * dlsym (void *handle, const char *symbol) { return 0; }
-int dlclose (void *handle) { return 0; }")
+int dlclose (void *handle) { return 0; }
+int dladdr (const void *addr, Dl_info *info) { return 0; }")
set( flags "${CMAKE_C_FLAGS}" )
separate_arguments( flags )
execute_process( COMMAND ${CMAKE_C_COMPILER} ${flags} -c ${libdl}/libdl.c -o ${libdl}/libdl.o )
diff --git a/docs/lldb-for-gdb-users.txt b/docs/lldb-for-gdb-users.txt
index 216903a55db5..d505d639192d 100644
--- a/docs/lldb-for-gdb-users.txt
+++ b/docs/lldb-for-gdb-users.txt
@@ -222,7 +222,7 @@ Or you can attach to a process by name with:
(lldb) process attach -n Sketch
-the "attach by name" also supports the "-w" option which waits for the
+The "attach by name" also supports the "-w" option which waits for the
next process of that name to show up, and attaches to that. You can also
attach by PID:
diff --git a/docs/lldb-gdb-remote.txt b/docs/lldb-gdb-remote.txt
index 5c4a10c82b49..a882c4abda09 100644
--- a/docs/lldb-gdb-remote.txt
+++ b/docs/lldb-gdb-remote.txt
@@ -1508,6 +1508,28 @@ for this region.
// This packet asks the remote debug stub to send the details about libraries
// being added/removed from the process as a performance optimization.
//
+// There are three ways this packet can be used. All three return a dictionary of
+// binary images formatted the same way.
+//
+// On MacOS X 10.11, iOS 9, tvOS 9, watchOS 2 and earlier, the packet is used like
+// jGetLoadedDynamicLibrariesInfos:{"image_count":1,"image_list_address":140734800075128}
+// where the image_list_address is an array of {void* load_addr, void* mod_date, void* pathname}
+// in the inferior process memory (and image_count is the number of elements in this array).
+// lldb is using information from the dyld_all_image_infos structure to make these requests to
+// debugserver. This use is not supported on macOS 10.12, iOS 10, tvOS 10, watchOS 3 or newer.
+//
+// On macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer, there are two calls. One requests information
+// on all shared libraries:
+// jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}
+// And the second requests information about a list of shared libraries, given their load addresses:
+// jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]}
+//
+// The second call is both a performance optimization (instead of having lldb read the mach-o header/load commands
+// out of memory with generic read packets) but also adds additional information in the form of the
+// filename of the shared libraries (which is not available in the mach-o header/load commands.)
+//
+// An example using the Mac OS X 10.11 style call:
+//
// LLDB SENDS: jGetLoadedDynamicLibrariesInfos:{"image_count":1,"image_list_address":140734800075128}
// STUB REPLIES: ${"images":[{"load_address":4294967296,"mod_date":0,"pathname":"/tmp/a.out","uuid":"02CF262C-ED6F-3965-9E14-63538B465CFF","mach_header":{"magic":4277009103,"cputype":16777223,"cpusubtype":18446744071562067971,"filetype":2},"segments":{"name":"__PAGEZERO","vmaddr":0,"vmsize":4294967296,"fileoff":0,"filesize":0,"maxprot":0},{"name":"__TEXT","vmaddr":4294967296,"vmsize":4096,"fileoff":0,"filesize":4096,"maxprot":7},{"name":"__LINKEDIT","vmaddr":4294971392,"vmsize":4096,"fileoff":4096,"filesize":152,"maxprot":7}}]}#00
//
@@ -1562,26 +1584,12 @@ for this region.
// quite a bit to provide all the information that the DynamicLoaderMacOSX
// would need to work correctly on this platform.
//
-// On Mac OS X / iOS, when libraries are added or removed, a stub
-// function is called which lldb puts a breakpoint on. The arguments
-// to the stub function include the number of libraries being added
-// or removed and the address where the list of libraries can be
-// found. The information at this address is the load address of the
-// library, the filename, and the mod date of the library if available.
-// DynamicLoaderMacOSX then parses the load commands in the Mach-O header
-// at the load address before it can decide what action to take.
-//
-// The purpose of this packet is to eliminate all of the memory reads needed
-// to read the Mach-O header and load commands for these libraries.
-// On a typical GUI app, there can be a couple hundred shared libraries
-// which results in megabytes of read packets. That same information can
-// be returned in a couple hundred kilobytes in JSON format from the remote
-// debugserver.
-//
-//
// PRIORITY TO IMPLEMENT
-// Low. If this packet is absent, lldb will read the Mach-O headers/load
-// commands out of memory.
+// On Mac OS X 10.11, iOS 9, tvOS 9, watchOS 2 and older: Low. If this packet is absent,
+// lldb will read the Mach-O headers/load commands out of memory.
+// On macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer: High. If this packet is absent,
+// lldb will not know anything about shared libraries in the inferior, or where the main
+// executable loaded.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
@@ -1649,6 +1657,26 @@ the previous FP and PC), and follow the backchain. Most backtraces on MacOSX and
iOS now don't require us to read any memory!
//----------------------------------------------------------------------
+// "jGetSharedCacheInfo"
+//
+// BRIEF
+// This packet asks the remote debug stub to send the details about the inferior's
+// shared cache. The shared cache is a collection of common libraries/frameworks that
+// are mapped into every process at the same address on Darwin systems, and can be
+// identified by a load address and UUID.
+//
+//
+// LLDB SENDS: jGetSharedCacheInfo:{}
+// STUB REPLIES: ${"shared_cache_base_address":140735683125248,"shared_cache_uuid":"DDB8D70C-C9A2-3561-B2C8-BE48A4F33F96","no_shared_cache":false,"shared_cache_private_cache":false]}#00
+//
+// PRIORITY TO IMPLEMENT
+// Low. When both lldb and the inferior process are running on the same computer, and lldb
+// and the inferior process have the same shared cache, lldb may (as an optimization) read
+// the shared cache out of its own memory instead of using gdb-remote read packets to read
+// them from the inferior process.
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
// "qQueryGDBServer"
//
// BRIEF
diff --git a/examples/python/crashlog.py b/examples/python/crashlog.py
index 60a6a1f50f00..a557b604afb4 100755
--- a/examples/python/crashlog.py
+++ b/examples/python/crashlog.py
@@ -452,7 +452,7 @@ class CrashLog(symbolication.Symbolicator):
for image in self.images:
if image.identifier == identifier:
return image
- regex_text = '^.*\.%s$' % (identifier)
+ regex_text = '^.*\.%s$' % (re.escape(identifier))
regex = re.compile(regex_text)
for image in self.images:
if regex.match(image.identifier):
diff --git a/examples/python/scripted_step.py b/examples/python/scripted_step.py
index 8affb9e83220..6be397188720 100644
--- a/examples/python/scripted_step.py
+++ b/examples/python/scripted_step.py
@@ -184,3 +184,28 @@ class StepCheckingCondition:
def should_step (self):
return True
+# Here's an example that steps out of the current frame, gathers some information
+# and then continues. The information in this case is rax. Currently the thread
+# plans are not a safe place to call lldb command-line commands, so the information
+# is gathered through SB API calls.
+
+class FinishPrintAndContinue:
+ def __init__ (self, thread_plan, dict):
+ self.thread_plan = thread_plan
+ self.step_out_thread_plan = thread_plan.QueueThreadPlanForStepOut(0, True)
+ self.thread = self.thread_plan.GetThread()
+
+ def explains_stop (self, event):
+ return False
+
+ def should_stop (self, event):
+ if self.step_out_thread_plan.IsPlanComplete():
+ frame_0 = self.thread.frames[0]
+ rax_value = frame_0.FindRegister("rax")
+ if rax_value.GetError().Success():
+ print "RAX on exit: ", rax_value.GetValue()
+ else:
+ print "Couldn't get rax value:", rax_value.GetError().GetCString()
+
+ self.thread_plan.SetPlanComplete(True)
+ return False
diff --git a/examples/python/shadow.py b/examples/python/shadow.py
new file mode 100644
index 000000000000..d1a5878fcef8
--- /dev/null
+++ b/examples/python/shadow.py
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+
+import lldb
+import shlex
+
+@lldb.command("shadow")
+def check_shadow_command(debugger, command, exe_ctx, result, dict):
+ '''Check the currently selected stack frame for shadowed variables'''
+ process = exe_ctx.GetProcess()
+ state = process.GetState()
+ if state != lldb.eStateStopped:
+ print >>result, "process must be stopped, state is %s" % lldb.SBDebugger.StateAsCString(state)
+ return
+ frame = exe_ctx.GetFrame()
+ if not frame:
+ print >>result, "invalid frame"
+ return
+ # Parse command line args
+ command_args = shlex.split(command)
+ # TODO: add support for using arguments that are passed to this command...
+
+ # Make a dictionary of variable name to "SBBlock and SBValue"
+ shadow_dict = {}
+
+ num_shadowed_variables = 0
+ # Get the deepest most block from the current frame
+ block = frame.GetBlock()
+ # Iterate through the block and all of its parents
+ while block.IsValid():
+ # Get block variables from the current block only
+ block_vars = block.GetVariables(frame, True, True, True, 0)
+ # Iterate through all variables in the current block
+ for block_var in block_vars:
+ # Since we can have multiple shadowed variables, we our variable
+ # name dictionary to have an array or "block + variable" pairs so
+ # We can correctly print out all shadowed variables and whow which
+ # blocks they come from
+ block_var_name = block_var.GetName()
+ if block_var_name in shadow_dict:
+ shadow_dict[block_var_name].append(block_var)
+ else:
+ shadow_dict[block_var_name] = [block_var]
+ # Get the parent block and continue
+ block = block.GetParent()
+
+ num_shadowed_variables = 0
+ if shadow_dict:
+ for name in shadow_dict.keys():
+ shadow_vars = shadow_dict[name]
+ if len(shadow_vars) > 1:
+ print '"%s" is shadowed by the following declarations:' % (name)
+ num_shadowed_variables += 1
+ for shadow_var in shadow_vars:
+ print >>result, str(shadow_var.GetDeclaration())
+ if num_shadowed_variables == 0:
+ print >>result, 'no variables are shadowed'
+
diff --git a/examples/python/symbolication.py b/examples/python/symbolication.py
index 2f2a274dbc41..88846c99b3a4 100755
--- a/examples/python/symbolication.py
+++ b/examples/python/symbolication.py
@@ -448,7 +448,7 @@ class Symbolicator:
if image.identifier == identifier:
images.append(image)
if len(images) == 0:
- regex_text = '^.*\.%s$' % (identifier)
+ regex_text = '^.*\.%s$' % (re.escape(identifier))
regex = re.compile(regex_text)
for image in self.images:
if regex.match(image.identifier):
diff --git a/examples/synthetic/gnu_libstdcpp.py b/examples/synthetic/gnu_libstdcpp.py
index b6bf42235acd..9f26282be01f 100644
--- a/examples/synthetic/gnu_libstdcpp.py
+++ b/examples/synthetic/gnu_libstdcpp.py
@@ -237,11 +237,12 @@ class StdVectorSynthProvider:
def get_child_at_index(self, index):
if index >= self.num_children():
return None
- byte_offset = index / 8
- bit_offset = index % 8
- element_size = self.start_p.GetType().GetPointeeType().GetByteSize()
- data = self.start_p.GetPointeeData(byte_offset / element_size)
- bit = data.GetUnsignedInt8(lldb.SBError(), byte_offset % element_size) & (1 << bit_offset)
+ element_type = self.start_p.GetType().GetPointeeType()
+ element_bits = 8 * element_type.GetByteSize()
+ element_offset = (index / element_bits) * element_type.GetByteSize()
+ bit_offset = index % element_bits
+ element = self.start_p.CreateChildAtOffset('['+str(index)+']',element_offset,element_type)
+ bit = element.GetValueAsUnsigned(0) & (1 << bit_offset)
if bit != 0:
value_expr = "(bool)true"
else:
diff --git a/include/Makefile b/include/Makefile
deleted file mode 100644
index 02acdce10271..000000000000
--- a/include/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-##===- include/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 := ..
-DIRS := lldb
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/include/lldb/API/LLDB.h b/include/lldb/API/LLDB.h
index eed10d08c6cc..b6278160dbc0 100644
--- a/include/lldb/API/LLDB.h
+++ b/include/lldb/API/LLDB.h
@@ -43,6 +43,8 @@
#include "lldb/API/SBLaunchInfo.h"
#include "lldb/API/SBLineEntry.h"
#include "lldb/API/SBListener.h"
+#include "lldb/API/SBMemoryRegionInfo.h"
+#include "lldb/API/SBMemoryRegionInfoList.h"
#include "lldb/API/SBModule.h"
#include "lldb/API/SBModuleSpec.h"
#include "lldb/API/SBPlatform.h"
diff --git a/include/lldb/API/SBCommandReturnObject.h b/include/lldb/API/SBCommandReturnObject.h
index b45eb9c14c04..2b7cce5ded59 100644
--- a/include/lldb/API/SBCommandReturnObject.h
+++ b/include/lldb/API/SBCommandReturnObject.h
@@ -83,7 +83,9 @@ public:
bool
GetDescription (lldb::SBStream &description);
-
+
+ // deprecated, these two functions do not take
+ // ownership of file handle
void
SetImmediateOutputFile (FILE *fh);
@@ -91,6 +93,12 @@ public:
SetImmediateErrorFile (FILE *fh);
void
+ SetImmediateOutputFile (FILE *fh, bool transfer_ownership);
+
+ void
+ SetImmediateErrorFile (FILE *fh, bool transfer_ownership);
+
+ void
PutCString(const char* string, int len = -1);
size_t
diff --git a/include/lldb/API/SBDefines.h b/include/lldb/API/SBDefines.h
index d81bba5a2e23..4a95903ec92c 100644
--- a/include/lldb/API/SBDefines.h
+++ b/include/lldb/API/SBDefines.h
@@ -59,6 +59,8 @@ class LLDB_API SBLanguageRuntime;
class LLDB_API SBLaunchInfo;
class LLDB_API SBLineEntry;
class LLDB_API SBListener;
+class LLDB_API SBMemoryRegionInfo;
+class LLDB_API SBMemoryRegionInfoList;
class LLDB_API SBModule;
class LLDB_API SBModuleSpec;
class LLDB_API SBModuleSpecList;
diff --git a/include/lldb/API/SBExpressionOptions.h b/include/lldb/API/SBExpressionOptions.h
index ed2f9187b3e0..051ed7220ac8 100644
--- a/include/lldb/API/SBExpressionOptions.h
+++ b/include/lldb/API/SBExpressionOptions.h
@@ -110,6 +110,19 @@ public:
void
SetPrefix (const char *prefix);
+
+ void
+ SetAutoApplyFixIts(bool b = true);
+
+ bool
+ GetAutoApplyFixIts();
+
+ bool
+ GetTopLevel ();
+
+ void
+ SetTopLevel (bool b = true);
+
protected:
diff --git a/include/lldb/API/SBFileSpec.h b/include/lldb/API/SBFileSpec.h
index d6f38f5b2d74..2f9d6bab89f3 100644
--- a/include/lldb/API/SBFileSpec.h
+++ b/include/lldb/API/SBFileSpec.h
@@ -60,6 +60,9 @@ public:
bool
GetDescription (lldb::SBStream &description) const;
+ void
+ AppendPathComponent (const char *file_or_directory);
+
private:
friend class SBAttachInfo;
friend class SBBlock;
diff --git a/include/lldb/API/SBHostOS.h b/include/lldb/API/SBHostOS.h
index d9bc97365632..a3675856a136 100644
--- a/include/lldb/API/SBHostOS.h
+++ b/include/lldb/API/SBHostOS.h
@@ -28,6 +28,9 @@ public:
static lldb::SBFileSpec
GetLLDBPath (lldb::PathType path_type);
+ static lldb::SBFileSpec
+ GetUserHomeDirectory ();
+
static void
ThreadCreated (const char *name);
diff --git a/include/lldb/API/SBInstruction.h b/include/lldb/API/SBInstruction.h
index 2bacc2b97746..cb0b2a32a829 100644
--- a/include/lldb/API/SBInstruction.h
+++ b/include/lldb/API/SBInstruction.h
@@ -18,6 +18,8 @@
// There's a lot to be fixed here, but need to wait for underlying insn implementation
// to be revised & settle down first.
+class InstructionImpl;
+
namespace lldb {
class LLDB_API SBInstruction
@@ -81,14 +83,17 @@ public:
protected:
friend class SBInstructionList;
- SBInstruction (const lldb::InstructionSP &inst_sp);
+ SBInstruction(const lldb::DisassemblerSP &disasm_sp, const lldb::InstructionSP &inst_sp);
void
- SetOpaque (const lldb::InstructionSP &inst_sp);
+ SetOpaque(const lldb::DisassemblerSP &disasm_sp, const lldb::InstructionSP& inst_sp);
+
+ lldb::InstructionSP
+ GetOpaque();
private:
- lldb::InstructionSP m_opaque_sp;
+ std::shared_ptr<InstructionImpl> m_opaque_sp;
};
diff --git a/include/lldb/API/SBLaunchInfo.h b/include/lldb/API/SBLaunchInfo.h
index 68c0f386acde..38d598aec456 100644
--- a/include/lldb/API/SBLaunchInfo.h
+++ b/include/lldb/API/SBLaunchInfo.h
@@ -145,7 +145,7 @@ public:
GetShellExpandArguments ();
void
- SetShellExpandArguments (bool glob);
+ SetShellExpandArguments (bool expand);
uint32_t
GetResumeCount ();
diff --git a/include/lldb/API/SBListener.h b/include/lldb/API/SBListener.h
index 924f8109f638..e74d318ea118 100644
--- a/include/lldb/API/SBListener.h
+++ b/include/lldb/API/SBListener.h
@@ -106,8 +106,6 @@ protected:
friend class SBLaunchInfo;
friend class SBTarget;
- SBListener (lldb_private::Listener &listener);
-
SBListener (const lldb::ListenerSP &listener_sp);
lldb::ListenerSP
@@ -124,20 +122,11 @@ private:
lldb_private::Listener *
get() const;
- lldb_private::Listener &
- ref() const;
-
- lldb_private::Listener &
- operator *();
-
- const lldb_private::Listener &
- operator *() const;
-
void
- reset(lldb_private::Listener *listener, bool transfer_ownership);
+ reset(lldb::ListenerSP listener_sp);
lldb::ListenerSP m_opaque_sp;
- lldb_private::Listener *m_opaque_ptr;
+ lldb_private::Listener *m_unused_ptr;
};
} // namespace lldb
diff --git a/include/lldb/API/SBMemoryRegionInfo.h b/include/lldb/API/SBMemoryRegionInfo.h
new file mode 100644
index 000000000000..fadd0760891b
--- /dev/null
+++ b/include/lldb/API/SBMemoryRegionInfo.h
@@ -0,0 +1,117 @@
+//===-- SBMemoryRegionInfo.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_SBMemoryRegionInfo_h_
+#define LLDB_SBMemoryRegionInfo_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBData.h"
+
+namespace lldb {
+
+class LLDB_API SBMemoryRegionInfo
+{
+public:
+
+ SBMemoryRegionInfo ();
+
+ SBMemoryRegionInfo (const lldb::SBMemoryRegionInfo &rhs);
+
+ ~SBMemoryRegionInfo ();
+
+ const lldb::SBMemoryRegionInfo &
+ operator = (const lldb::SBMemoryRegionInfo &rhs);
+
+ void
+ Clear();
+
+ //------------------------------------------------------------------
+ /// Get the base address of this memory range.
+ ///
+ /// @return
+ /// The base address of this memory range.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetRegionBase ();
+
+ //------------------------------------------------------------------
+ /// Get the end address of this memory range.
+ ///
+ /// @return
+ /// The base address of this memory range.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetRegionEnd ();
+
+ //------------------------------------------------------------------
+ /// Check if this memory address is marked readable to the process.
+ ///
+ /// @return
+ /// true if this memory address is marked readable
+ //------------------------------------------------------------------
+ bool
+ IsReadable ();
+
+ //------------------------------------------------------------------
+ /// Check if this memory address is marked writable to the process.
+ ///
+ /// @return
+ /// true if this memory address is marked writable
+ //------------------------------------------------------------------
+ bool
+ IsWritable ();
+
+ //------------------------------------------------------------------
+ /// Check if this memory address is marked executable to the process.
+ ///
+ /// @return
+ /// true if this memory address is marked executable
+ //------------------------------------------------------------------
+ bool
+ IsExecutable ();
+
+ //------------------------------------------------------------------
+ /// Check if this memory address is mapped into the process address
+ /// space.
+ ///
+ /// @return
+ /// true if this memory address is in the process address space.
+ //------------------------------------------------------------------
+ bool
+ IsMapped ();
+
+ bool
+ operator == (const lldb::SBMemoryRegionInfo &rhs) const;
+
+ bool
+ operator != (const lldb::SBMemoryRegionInfo &rhs) const;
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+private:
+
+ friend class SBProcess;
+ friend class SBMemoryRegionInfoList;
+
+ lldb_private::MemoryRegionInfo &
+ ref();
+
+ const lldb_private::MemoryRegionInfo &
+ ref() const;
+
+ SBMemoryRegionInfo (const lldb_private::MemoryRegionInfo *lldb_object_ptr);
+
+ lldb::MemoryRegionInfoUP m_opaque_ap;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBMemoryRegionInfo_h_
diff --git a/include/lldb/API/SBMemoryRegionInfoList.h b/include/lldb/API/SBMemoryRegionInfoList.h
new file mode 100644
index 000000000000..7723820897d8
--- /dev/null
+++ b/include/lldb/API/SBMemoryRegionInfoList.h
@@ -0,0 +1,63 @@
+//===-- SBMemoryRegionInfoList.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_SBMemoryRegionInfoList_h_
+#define LLDB_SBMemoryRegionInfoList_h_
+
+#include "lldb/API/SBDefines.h"
+
+class MemoryRegionInfoListImpl;
+
+namespace lldb {
+
+class LLDB_API SBMemoryRegionInfoList
+{
+public:
+
+ SBMemoryRegionInfoList ();
+
+ SBMemoryRegionInfoList (const lldb::SBMemoryRegionInfoList &rhs);
+
+ const SBMemoryRegionInfoList &
+ operator = (const SBMemoryRegionInfoList &rhs);
+
+ ~SBMemoryRegionInfoList ();
+
+ uint32_t
+ GetSize () const;
+
+ bool
+ GetMemoryRegionAtIndex (uint32_t idx, SBMemoryRegionInfo &region_info);
+
+ void
+ Append (lldb::SBMemoryRegionInfo &region);
+
+ void
+ Append (lldb::SBMemoryRegionInfoList &region_list);
+
+ void
+ Clear ();
+
+protected:
+
+ const MemoryRegionInfoListImpl *
+ operator->() const;
+
+ const MemoryRegionInfoListImpl &
+ operator*() const;
+
+private:
+
+ std::unique_ptr<MemoryRegionInfoListImpl> m_opaque_ap;
+
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBMemoryRegionInfoList_h_
diff --git a/include/lldb/API/SBProcess.h b/include/lldb/API/SBProcess.h
index 1a9cc8022880..a8881ad898c0 100644
--- a/include/lldb/API/SBProcess.h
+++ b/include/lldb/API/SBProcess.h
@@ -393,6 +393,34 @@ public:
lldb::SBError
SaveCore(const char *file_name);
+ //------------------------------------------------------------------
+ /// Query the address load_addr and store the details of the memory
+ /// region that contains it in the supplied SBMemoryRegionInfo object.
+ /// To iterate over all memory regions use GetMemoryRegionList.
+ ///
+ /// @param[in] load_addr
+ /// The address to be queried.
+ ///
+ /// @param[out] region_info
+ /// A reference to an SBMemoryRegionInfo object that will contain
+ /// the details of the memory region containing load_addr.
+ ///
+ /// @return
+ /// An error object describes any errors that occurred while
+ /// querying load_addr.
+ //------------------------------------------------------------------
+ lldb::SBError
+ GetMemoryRegionInfo (lldb::addr_t load_addr, lldb::SBMemoryRegionInfo &region_info);
+
+ //------------------------------------------------------------------
+ /// Return the list of memory regions within the process.
+ ///
+ /// @return
+ /// A list of all witin the process memory regions.
+ //------------------------------------------------------------------
+ lldb::SBMemoryRegionInfoList
+ GetMemoryRegions();
+
protected:
friend class SBAddress;
friend class SBBreakpoint;
diff --git a/include/lldb/API/SBStream.h b/include/lldb/API/SBStream.h
index e62723c2f37e..717979977d16 100644
--- a/include/lldb/API/SBStream.h
+++ b/include/lldb/API/SBStream.h
@@ -76,6 +76,7 @@ protected:
friend class SBInstruction;
friend class SBInstructionList;
friend class SBLineEntry;
+ friend class SBMemoryRegionInfo;
friend class SBModule;
friend class SBModuleSpec;
friend class SBModuleSpecList;
diff --git a/include/lldb/API/SBStringList.h b/include/lldb/API/SBStringList.h
index e0e58f765c6d..bc8ff935eda3 100644
--- a/include/lldb/API/SBStringList.h
+++ b/include/lldb/API/SBStringList.h
@@ -45,6 +45,9 @@ public:
const char *
GetStringAtIndex (size_t idx);
+ const char *
+ GetStringAtIndex (size_t idx) const;
+
void
Clear ();
diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h
index 723c433b521a..0bcabd043c9c 100644
--- a/include/lldb/API/SBTarget.h
+++ b/include/lldb/API/SBTarget.h
@@ -621,6 +621,9 @@ public:
BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line);
lldb::SBBreakpoint
+ BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line, lldb::addr_t offset);
+
+ lldb::SBBreakpoint
BreakpointCreateByName(const char *symbol_name, const char *module_name = nullptr);
// This version uses name_type_mask = eFunctionNameTypeAuto
@@ -658,6 +661,15 @@ public:
const SBFileSpecList &comp_unit_list);
lldb::SBBreakpoint
+ BreakpointCreateByNames (const char *symbol_name[],
+ uint32_t num_names,
+ uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
+ lldb::LanguageType symbol_language,
+ lldb::addr_t offset,
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &comp_unit_list);
+
+ lldb::SBBreakpoint
BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = nullptr);
lldb::SBBreakpoint
@@ -682,6 +694,12 @@ public:
const SBFileSpecList &source_file);
lldb::SBBreakpoint
+ BreakpointCreateBySourceRegex (const char *source_regex,
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &source_file,
+ const SBStringList &func_names);
+
+ lldb::SBBreakpoint
BreakpointCreateForException (lldb::LanguageType language,
bool catch_bp,
bool throw_bp);
diff --git a/include/lldb/API/SBThread.h b/include/lldb/API/SBThread.h
index 2c45fa8d5120..c1ce216f9be6 100644
--- a/include/lldb/API/SBThread.h
+++ b/include/lldb/API/SBThread.h
@@ -82,6 +82,9 @@ public:
bool
GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream);
+ SBThreadCollection
+ GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type);
+
size_t
GetStopDescription (char *dst, size_t dst_len);
@@ -116,6 +119,12 @@ public:
StepInto (const char *target_name, lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
void
+ StepInto (const char *target_name,
+ uint32_t end_line,
+ SBError &error,
+ lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
+
+ void
StepOut ();
void
@@ -141,6 +150,9 @@ public:
SBError
ReturnFromFrame (SBFrame &frame, SBValue &return_value);
+ SBError
+ UnwindInnermostExpression();
+
//--------------------------------------------------------------------------
/// LLDB currently supports process centric debugging which means when any
/// thread in a process stops, all other threads are stopped. The Suspend()
diff --git a/include/lldb/API/SBThreadCollection.h b/include/lldb/API/SBThreadCollection.h
index 996ee3cd22aa..79f977454497 100644
--- a/include/lldb/API/SBThreadCollection.h
+++ b/include/lldb/API/SBThreadCollection.h
@@ -58,6 +58,7 @@ protected:
private:
friend class SBProcess;
+ friend class SBThread;
lldb::ThreadCollectionSP m_opaque_sp;
};
diff --git a/include/lldb/API/SBValue.h b/include/lldb/API/SBValue.h
index a7e015064f96..b9f1e6f5c93f 100644
--- a/include/lldb/API/SBValue.h
+++ b/include/lldb/API/SBValue.h
@@ -125,6 +125,12 @@ public:
bool
IsSynthetic ();
+
+ bool
+ IsSyntheticChildrenGenerated ();
+
+ void
+ SetSyntheticChildrenGenerated (bool);
const char *
GetLocation ();
diff --git a/include/lldb/Breakpoint/BreakpointList.h b/include/lldb/Breakpoint/BreakpointList.h
index f4837e1ce956..5ddde7d837c4 100644
--- a/include/lldb/Breakpoint/BreakpointList.h
+++ b/include/lldb/Breakpoint/BreakpointList.h
@@ -13,10 +13,11 @@
// C Includes
// C++ Includes
#include <list>
+#include <mutex>
+
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/Breakpoint.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -116,7 +117,7 @@ public:
size_t
GetSize() const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_breakpoints.size();
}
@@ -193,7 +194,7 @@ public:
/// The locker object that is set.
//------------------------------------------------------------------
void
- GetListMutex (lldb_private::Mutex::Locker &locker);
+ GetListMutex(std::unique_lock<std::recursive_mutex> &lock);
protected:
typedef std::list<lldb::BreakpointSP> bp_collection;
@@ -204,19 +205,20 @@ protected:
bp_collection::const_iterator
GetBreakpointIDConstIterator(lldb::break_id_t breakID) const;
- Mutex &
- GetMutex () const
+ std::recursive_mutex &
+ GetMutex() const
{
return m_mutex;
}
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
bp_collection m_breakpoints; // The breakpoint list, currently a list.
lldb::break_id_t m_next_break_id;
bool m_is_internal;
public:
- typedef LockingAdaptedIterable<bp_collection, lldb::BreakpointSP, list_adapter> BreakpointIterable;
+ typedef LockingAdaptedIterable<bp_collection, lldb::BreakpointSP, list_adapter, std::recursive_mutex>
+ BreakpointIterable;
BreakpointIterable
Breakpoints()
{
diff --git a/include/lldb/Breakpoint/BreakpointLocation.h b/include/lldb/Breakpoint/BreakpointLocation.h
index 58d144cfb668..42eca73dbb22 100644
--- a/include/lldb/Breakpoint/BreakpointLocation.h
+++ b/include/lldb/Breakpoint/BreakpointLocation.h
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <memory>
+#include <mutex>
// Other libraries and framework includes
// Project includes
@@ -20,7 +21,6 @@
#include "lldb/Breakpoint/StoppointLocation.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/UserID.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -460,7 +460,8 @@ private:
std::unique_ptr<BreakpointOptions> m_options_ap; ///< Breakpoint options pointer, nullptr if we're using our breakpoint's options.
lldb::BreakpointSiteSP m_bp_site_sp; ///< Our breakpoint site (it may be shared by more than one location.)
lldb::UserExpressionSP m_user_expression_sp; ///< The compiled expression to use in testing our condition.
- Mutex m_condition_mutex; ///< Guards parsing and evaluation of the condition, which could be evaluated by multiple processes.
+ std::mutex m_condition_mutex; ///< Guards parsing and evaluation of the condition, which could be evaluated by
+ /// multiple processes.
size_t m_condition_hash; ///< For testing whether the condition source code changed.
void
diff --git a/include/lldb/Breakpoint/BreakpointLocationCollection.h b/include/lldb/Breakpoint/BreakpointLocationCollection.h
index 004f8395122b..1a016544fa4c 100644
--- a/include/lldb/Breakpoint/BreakpointLocationCollection.h
+++ b/include/lldb/Breakpoint/BreakpointLocationCollection.h
@@ -13,6 +13,8 @@
// C Includes
// C++ Includes
#include <vector>
+#include <mutex>
+
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
@@ -201,7 +203,8 @@ private:
collection::const_iterator
GetIDPairConstIterator(lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const;
- collection m_break_loc_collection;
+ collection m_break_loc_collection;
+ mutable std::mutex m_collection_mutex;
public:
typedef AdaptedIterable<collection, lldb::BreakpointLocationSP, vector_adapter> BreakpointLocationCollectionIterable;
diff --git a/include/lldb/Breakpoint/BreakpointLocationList.h b/include/lldb/Breakpoint/BreakpointLocationList.h
index 81526089b427..1fbfa43a40f4 100644
--- a/include/lldb/Breakpoint/BreakpointLocationList.h
+++ b/include/lldb/Breakpoint/BreakpointLocationList.h
@@ -13,13 +13,13 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
#include <vector>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Utility/Iterable.h"
namespace lldb_private {
@@ -270,7 +270,7 @@ protected:
Breakpoint &m_owner;
collection m_locations; // Vector of locations, sorted by ID
addr_map m_address_to_location;
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
lldb::break_id_t m_next_id;
BreakpointLocationCollection *m_new_location_recorder;
diff --git a/include/lldb/Breakpoint/BreakpointResolver.h b/include/lldb/Breakpoint/BreakpointResolver.h
index 198abed841b2..b117e668a1bd 100644
--- a/include/lldb/Breakpoint/BreakpointResolver.h
+++ b/include/lldb/Breakpoint/BreakpointResolver.h
@@ -60,7 +60,7 @@ public:
/// @result
/// Returns breakpoint location id.
//------------------------------------------------------------------
- BreakpointResolver (Breakpoint *bkpt, unsigned char resolverType);
+ BreakpointResolver (Breakpoint *bkpt, unsigned char resolverType, lldb::addr_t offset = 0);
//------------------------------------------------------------------
/// The Destructor is virtual, all significant breakpoint resolvers derive
@@ -78,6 +78,29 @@ public:
SetBreakpoint (Breakpoint *bkpt);
//------------------------------------------------------------------
+ /// This updates the offset for this breakpoint. All the locations currently
+ /// set for this breakpoint will have their offset adjusted when this is called.
+ ///
+ /// @param[in] offset
+ /// The offset to add to all locations.
+ //------------------------------------------------------------------
+ void
+ SetOffset (lldb::addr_t offset);
+
+ //------------------------------------------------------------------
+ /// This updates the offset for this breakpoint. All the locations currently
+ /// set for this breakpoint will have their offset adjusted when this is called.
+ ///
+ /// @param[in] offset
+ /// The offset to add to all locations.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetOffset () const
+ {
+ return m_offset;
+ }
+
+ //------------------------------------------------------------------
/// In response to this method the resolver scans all the modules in the breakpoint's
/// target, and adds any new locations it finds.
///
@@ -145,8 +168,12 @@ protected:
/// matching addresses to unique entries, and skip the prologue if asked to do so, and then set
/// breakpoint locations in this breakpoint for all the resultant addresses.
void SetSCMatchesByLine (SearchFilter &filter, SymbolContextList &sc_list, bool skip_prologue, const char *log_ident);
+
+ lldb::BreakpointLocationSP
+ AddLocation(Address loc_addr, bool *new_location = NULL);
Breakpoint *m_breakpoint; // This is the breakpoint we add locations to.
+ lldb::addr_t m_offset; // A random offset the user asked us to add to any breakpoints we set.
private:
// Subclass identifier (for llvm isa/dyn_cast)
diff --git a/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/include/lldb/Breakpoint/BreakpointResolverFileLine.h
index 2dde1546f126..cea192b5edbf 100644
--- a/include/lldb/Breakpoint/BreakpointResolverFileLine.h
+++ b/include/lldb/Breakpoint/BreakpointResolverFileLine.h
@@ -31,6 +31,7 @@ public:
BreakpointResolverFileLine (Breakpoint *bkpt,
const FileSpec &resolver,
uint32_t line_no,
+ lldb::addr_t m_offset,
bool check_inlines,
bool skip_prologue,
bool exact_match);
diff --git a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
index a8d7a50b5d93..ce67c2dc98ec 100644
--- a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
+++ b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
@@ -12,9 +12,11 @@
// C Includes
// C++ Includes
+#include <set>
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Core/ConstString.h"
namespace lldb_private {
@@ -30,6 +32,7 @@ class BreakpointResolverFileRegex :
public:
BreakpointResolverFileRegex (Breakpoint *bkpt,
RegularExpression &regex,
+ const std::unordered_set<std::string> &func_name_set,
bool exact_match);
~BreakpointResolverFileRegex() override;
@@ -48,6 +51,9 @@ public:
void
Dump (Stream *s) const override;
+
+ void
+ AddFunctionName(const char *func_name);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const BreakpointResolverFileRegex *) { return true; }
@@ -61,7 +67,8 @@ public:
protected:
friend class Breakpoint;
RegularExpression m_regex; // This is the line expression that we are looking for.
- bool m_exact_match;
+ bool m_exact_match; // If true, then if the source we match is in a comment, we won't set a location there.
+ std::unordered_set<std::string> m_function_names; // Limit the search to functions in the comp_unit passed in.
private:
DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileRegex);
diff --git a/include/lldb/Breakpoint/BreakpointResolverName.h b/include/lldb/Breakpoint/BreakpointResolverName.h
index aaae9c1a12cf..a11359dd0094 100644
--- a/include/lldb/Breakpoint/BreakpointResolverName.h
+++ b/include/lldb/Breakpoint/BreakpointResolverName.h
@@ -18,6 +18,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Core/Module.h"
namespace lldb_private {
@@ -37,6 +38,7 @@ public:
uint32_t name_type_mask,
lldb::LanguageType language,
Breakpoint::MatchType type,
+ lldb::addr_t offset,
bool skip_prologue);
// This one takes an array of names. It is always MatchType = Exact.
@@ -45,6 +47,7 @@ public:
size_t num_names,
uint32_t name_type_mask,
lldb::LanguageType language,
+ lldb::addr_t offset,
bool skip_prologue);
// This one takes a C++ array of names. It is always MatchType = Exact.
@@ -52,18 +55,21 @@ public:
std::vector<std::string> names,
uint32_t name_type_mask,
lldb::LanguageType language,
+ lldb::addr_t offset,
bool skip_prologue);
// Creates a function breakpoint by regular expression. Takes over control of the lifespan of func_regex.
BreakpointResolverName (Breakpoint *bkpt,
RegularExpression &func_regex,
lldb::LanguageType language,
+ lldb::addr_t offset,
bool skip_prologue);
BreakpointResolverName (Breakpoint *bkpt,
const char *class_name,
const char *method,
Breakpoint::MatchType type,
+ lldb::addr_t offset,
bool skip_prologue);
~BreakpointResolverName() override;
@@ -95,26 +101,7 @@ public:
protected:
BreakpointResolverName(const BreakpointResolverName &rhs);
- struct LookupInfo
- {
- ConstString name;
- ConstString lookup_name;
- uint32_t name_type_mask; // See FunctionNameType
- bool match_name_after_lookup;
-
- LookupInfo () :
- name(),
- lookup_name(),
- name_type_mask (0),
- match_name_after_lookup (false)
- {
- }
-
- void
- Prune (SymbolContextList &sc_list,
- size_t start_idx) const;
- };
- std::vector<LookupInfo> m_lookups;
+ std::vector<Module::LookupInfo> m_lookups;
ConstString m_class_name;
RegularExpression m_regex;
Breakpoint::MatchType m_match_type;
diff --git a/include/lldb/Breakpoint/BreakpointSite.h b/include/lldb/Breakpoint/BreakpointSite.h
index 6cebcab8e2db..27a23527d9fa 100644
--- a/include/lldb/Breakpoint/BreakpointSite.h
+++ b/include/lldb/Breakpoint/BreakpointSite.h
@@ -14,12 +14,12 @@
// C++ Includes
#include <list>
+#include <mutex>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-forward.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Core/UserID.h"
#include "lldb/Breakpoint/StoppointLocation.h"
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
@@ -297,7 +297,7 @@ private:
// Consider adding an optimization where if there is only one
// owner, we don't store a list. The usual case will be only one owner...
BreakpointLocationCollection m_owners; ///< This has the BreakpointLocations that share this breakpoint site.
- Mutex m_owners_mutex; ///< This mutex protects the owners collection.
+ std::recursive_mutex m_owners_mutex; ///< This mutex protects the owners collection.
static lldb::break_id_t
GetNextID();
diff --git a/include/lldb/Breakpoint/BreakpointSiteList.h b/include/lldb/Breakpoint/BreakpointSiteList.h
index d7bb8fd777ef..e681aa3599f7 100644
--- a/include/lldb/Breakpoint/BreakpointSiteList.h
+++ b/include/lldb/Breakpoint/BreakpointSiteList.h
@@ -12,12 +12,13 @@
// C Includes
// C++ Includes
-#include <map>
#include <functional>
+#include <map>
+#include <mutex>
+
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointSite.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -189,16 +190,17 @@ public:
size_t
GetSize() const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_bp_site_list.size();
}
bool
IsEmpty() const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_bp_site_list.empty();
}
+
protected:
typedef std::map<lldb::addr_t, lldb::BreakpointSiteSP> collection;
@@ -208,7 +210,7 @@ protected:
collection::const_iterator
GetIDConstIterator(lldb::break_id_t breakID) const;
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
collection m_bp_site_list; // The breakpoint site list.
};
diff --git a/include/lldb/Breakpoint/WatchpointList.h b/include/lldb/Breakpoint/WatchpointList.h
index d16cb25e3b7d..7369623d1ce2 100644
--- a/include/lldb/Breakpoint/WatchpointList.h
+++ b/include/lldb/Breakpoint/WatchpointList.h
@@ -13,12 +13,13 @@
// C Includes
// C++ Includes
#include <list>
+#include <mutex>
#include <vector>
+
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -217,7 +218,7 @@ public:
size_t
GetSize() const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_watchpoints.size();
}
@@ -250,7 +251,7 @@ public:
/// The locker object that is set.
//------------------------------------------------------------------
void
- GetListMutex (lldb_private::Mutex::Locker &locker);
+ GetListMutex(std::unique_lock<std::recursive_mutex> &lock);
protected:
typedef std::list<lldb::WatchpointSP> wp_collection;
@@ -266,7 +267,7 @@ protected:
GetIDConstIterator(lldb::watch_id_t watchID) const;
wp_collection m_watchpoints;
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
lldb::watch_id_t m_next_wp_id;
};
diff --git a/include/lldb/Core/ArchSpec.h b/include/lldb/Core/ArchSpec.h
index 13ff436cf08f..be760637c03e 100644
--- a/include/lldb/Core/ArchSpec.h
+++ b/include/lldb/Core/ArchSpec.h
@@ -69,9 +69,33 @@ public:
eMIPSABI_O32 = 0x00002000,
eMIPSABI_N32 = 0x00004000,
eMIPSABI_N64 = 0x00008000,
+ eMIPSABI_O64 = 0x00020000,
+ eMIPSABI_EABI32 = 0x00040000,
+ eMIPSABI_EABI64 = 0x00080000,
eMIPSABI_mask = 0x000ff000
};
+ // MIPS Floating point ABI Values
+ enum MIPS_ABI_FP
+ {
+ eMIPS_ABI_FP_ANY = 0x00000000,
+ eMIPS_ABI_FP_DOUBLE = 0x00100000, // hard float / -mdouble-float
+ eMIPS_ABI_FP_SINGLE = 0x00200000, // hard float / -msingle-float
+ eMIPS_ABI_FP_SOFT = 0x00300000, // soft float
+ eMIPS_ABI_FP_OLD_64 = 0x00400000, // -mips32r2 -mfp64
+ eMIPS_ABI_FP_XX = 0x00500000, // -mfpxx
+ eMIPS_ABI_FP_64 = 0x00600000, // -mips32r2 -mfp64
+ eMIPS_ABI_FP_64A = 0x00700000, // -mips32r2 -mfp64 -mno-odd-spreg
+ eMIPS_ABI_FP_mask = 0x00700000
+ };
+
+ // ARM specific e_flags
+ enum ARMeflags
+ {
+ eARM_abi_soft_float = 0x00000200,
+ eARM_abi_hard_float = 0x00000400
+ };
+
enum Core
{
eCore_arm_generic,
@@ -144,6 +168,8 @@ public:
eCore_ppc64_generic,
eCore_ppc64_ppc970_64,
+ eCore_s390x_generic,
+
eCore_sparc_generic,
eCore_sparc9_generic,
@@ -280,6 +306,24 @@ public:
const char *
GetArchitectureName () const;
+ //-----------------------------------------------------------------
+ /// if MIPS architecture return true.
+ ///
+ /// @return a boolean value.
+ //-----------------------------------------------------------------
+ bool
+ IsMIPS() const;
+
+ //------------------------------------------------------------------
+ /// Returns a string representing current architecture as a target CPU
+ /// for tools like compiler, disassembler etc.
+ ///
+ /// @return A string representing target CPU for the current
+ /// architecture.
+ //------------------------------------------------------------------
+ std::string
+ GetClangTargetCPU ();
+
//------------------------------------------------------------------
/// Clears the object state.
///
@@ -605,6 +649,22 @@ public:
bool &os_version_different,
bool &env_different);
+ //------------------------------------------------------------------
+ /// Detect whether this architecture uses thumb code exclusively
+ ///
+ /// Some embedded ARM chips (e.g. the ARM Cortex M0-7 line) can
+ /// only execute the Thumb instructions, never Arm. We should normally
+ /// pick up arm/thumbness from their the processor status bits (cpsr/xpsr)
+ /// or hints on each function - but when doing bare-boards low level
+ /// debugging (especially common with these embedded processors), we may
+ /// not have those things easily accessible.
+ ///
+ /// @return true if this is an arm ArchSpec which can only execute Thumb
+ /// instructions
+ //------------------------------------------------------------------
+ bool
+ IsAlwaysThumbInstructions () const;
+
uint32_t
GetFlags () const
{
diff --git a/include/lldb/Core/Broadcaster.h b/include/lldb/Core/Broadcaster.h
index 8e59a41805ec..33172fa73780 100644
--- a/include/lldb/Core/Broadcaster.h
+++ b/include/lldb/Core/Broadcaster.h
@@ -12,16 +12,17 @@
// C Includes
// C++ Includes
+#include <functional>
+#include <list>
#include <map>
+#include <mutex>
#include <string>
#include <vector>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
-//#include "lldb/Core/Flags.h"
#include "lldb/Core/ConstString.h"
-#include "lldb/Core/Listener.h"
namespace lldb_private {
@@ -75,48 +76,58 @@ public:
}
bool operator< (const BroadcastEventSpec &rhs) const;
- const BroadcastEventSpec &operator= (const BroadcastEventSpec &rhs);
+ BroadcastEventSpec &operator=(const BroadcastEventSpec &rhs);
private:
ConstString m_broadcaster_class;
uint32_t m_event_bits;
};
-class BroadcasterManager
+class BroadcasterManager :
+ public std::enable_shared_from_this<BroadcasterManager>
{
public:
friend class Listener;
+protected:
BroadcasterManager ();
-
+public:
+ // Listeners hold onto weak pointers to their broadcaster managers. So they must be
+ // made into shared pointers, which you do with MakeBroadcasterManager.
+
+ static lldb::BroadcasterManagerSP
+ MakeBroadcasterManager();
+
~BroadcasterManager() = default;
uint32_t
- RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec);
+ RegisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec);
bool
- UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec);
+ UnregisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec);
- Listener *
+ lldb::ListenerSP
GetListenerForEventSpec (BroadcastEventSpec event_spec) const;
void
SignUpListenersForBroadcaster (Broadcaster &broadcaster);
void
- RemoveListener (Listener &Listener);
+ RemoveListener (const lldb::ListenerSP &listener_sp);
+
+ void
+ RemoveListener (Listener *listener);
-protected:
void Clear();
private:
- typedef std::pair<BroadcastEventSpec, Listener *> event_listener_key;
- typedef std::map<BroadcastEventSpec, Listener *> collection;
- typedef std::set<Listener *> listener_collection;
+ typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key;
+ typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection;
+ typedef std::set<lldb::ListenerSP> listener_collection;
collection m_event_map;
listener_collection m_listeners;
-
- Mutex m_manager_mutex;
+
+ mutable std::recursive_mutex m_manager_mutex;
// A couple of comparator classes for find_if:
@@ -161,10 +172,9 @@ private:
class ListenerMatchesAndSharedBits
{
public:
- ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec,
- const Listener &listener) :
+ explicit ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec, const lldb::ListenerSP listener_sp) :
m_broadcaster_spec (broadcaster_spec),
- m_listener (&listener)
+ m_listener_sp (listener_sp)
{
}
@@ -174,19 +184,19 @@ private:
{
return (input.first.GetBroadcasterClass() == m_broadcaster_spec.GetBroadcasterClass()
&& (input.first.GetEventBits() & m_broadcaster_spec.GetEventBits()) != 0
- && input.second == m_listener);
+ && input.second == m_listener_sp);
}
private:
BroadcastEventSpec m_broadcaster_spec;
- const Listener *m_listener;
+ const lldb::ListenerSP m_listener_sp;
};
class ListenerMatches
{
public:
- ListenerMatches (const Listener &in_listener) :
- m_listener (&in_listener)
+ explicit ListenerMatches (const lldb::ListenerSP in_listener_sp) :
+ m_listener_sp (in_listener_sp)
{
}
@@ -194,15 +204,44 @@ private:
bool operator () (const event_listener_key input) const
{
- if (input.second == m_listener)
+ if (input.second == m_listener_sp)
return true;
else
return false;
}
private:
- const Listener *m_listener;
+ const lldb::ListenerSP m_listener_sp;
+ };
+ class ListenerMatchesPointer
+ {
+ public:
+ ListenerMatchesPointer (const Listener *in_listener) :
+ m_listener (in_listener)
+ {
+ }
+
+ ~ListenerMatchesPointer() = default;
+
+ bool operator () (const event_listener_key input) const
+ {
+ if (input.second.get() == m_listener)
+ return true;
+ else
+ return false;
+ }
+
+ bool operator () (const lldb::ListenerSP input) const
+ {
+ if (input.get() == m_listener)
+ return true;
+ else
+ return false;
+ }
+
+ private:
+ const Listener *m_listener;
};
};
@@ -241,6 +280,8 @@ private:
//----------------------------------------------------------------------
class Broadcaster
{
+friend class Listener;
+friend class Event;
public:
//------------------------------------------------------------------
/// Construct with a broadcaster with a name.
@@ -249,7 +290,7 @@ public:
/// A NULL terminated C string that contains the name of the
/// broadcaster object.
//------------------------------------------------------------------
- Broadcaster (BroadcasterManager *manager, const char *name);
+ Broadcaster (lldb::BroadcasterManagerSP manager_sp, const char *name);
//------------------------------------------------------------------
/// Destructor.
@@ -279,22 +320,43 @@ public:
///
//------------------------------------------------------------------
void
- BroadcastEvent (lldb::EventSP &event_sp);
+ BroadcastEvent (lldb::EventSP &event_sp)
+ {
+ m_broadcaster_sp->BroadcastEvent(event_sp);
+ }
void
- BroadcastEventIfUnique (lldb::EventSP &event_sp);
+ BroadcastEventIfUnique (lldb::EventSP &event_sp)
+ {
+ m_broadcaster_sp->BroadcastEventIfUnique(event_sp);
+ }
void
- BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);
+ BroadcastEvent(uint32_t event_type, const lldb::EventDataSP &event_data_sp)
+ {
+ m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp);
+ }
void
- BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr);
+ BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr)
+ {
+ m_broadcaster_sp->BroadcastEvent(event_type, event_data);
+ }
void
- Clear();
+ BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr)
+ {
+ m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data);
+ }
+
+ void
+ Clear()
+ {
+ m_broadcaster_sp->Clear();
+ }
virtual void
- AddInitialEventsToListener (Listener *listener, uint32_t requested_events);
+ AddInitialEventsToListener (const lldb::ListenerSP &listener_sp, uint32_t requested_events);
//------------------------------------------------------------------
/// Listen for any events specified by \a event_mask.
@@ -319,7 +381,10 @@ public:
/// The actual event bits that were acquired by \a listener.
//------------------------------------------------------------------
uint32_t
- AddListener (Listener* listener, uint32_t event_mask);
+ AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask)
+ {
+ return m_broadcaster_sp->AddListener(listener_sp, event_mask);
+ }
//------------------------------------------------------------------
/// Get the NULL terminated C string name of this Broadcaster
@@ -329,7 +394,10 @@ public:
/// The NULL terminated C string name of this Broadcaster.
//------------------------------------------------------------------
const ConstString &
- GetBroadcasterName ();
+ GetBroadcasterName ()
+ {
+ return m_broadcaster_name;
+ }
//------------------------------------------------------------------
/// Get the event name(s) for one or more event bits.
@@ -341,7 +409,10 @@ public:
/// The NULL terminated C string name of this Broadcaster.
//------------------------------------------------------------------
bool
- GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const;
+ GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const
+ {
+ return m_broadcaster_sp->GetEventNames(s, event_mask, prefix_with_broadcaster_name);
+ }
//------------------------------------------------------------------
/// Set the name for an event bit.
@@ -356,20 +427,20 @@ public:
void
SetEventName (uint32_t event_mask, const char *name)
{
- m_event_names[event_mask] = name;
+ m_broadcaster_sp->SetEventName(event_mask, name);
}
const char *
GetEventName (uint32_t event_mask) const
{
- const auto pos = m_event_names.find (event_mask);
- if (pos != m_event_names.end())
- return pos->second.c_str();
- return nullptr;
+ return m_broadcaster_sp->GetEventName(event_mask);
}
bool
- EventTypeHasListeners (uint32_t event_type);
+ EventTypeHasListeners (uint32_t event_type)
+ {
+ return m_broadcaster_sp->EventTypeHasListeners(event_type);
+ }
//------------------------------------------------------------------
/// Removes a Listener from this broadcasters list and frees the
@@ -390,7 +461,10 @@ public:
/// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
//------------------------------------------------------------------
bool
- RemoveListener (Listener* listener, uint32_t event_mask = UINT32_MAX);
+ RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX)
+ {
+ return m_broadcaster_sp->RemoveListener(listener_sp, event_mask);
+ }
//------------------------------------------------------------------
/// Provides a simple mechanism to temporarily redirect events from
@@ -414,17 +488,26 @@ public:
/// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
//------------------------------------------------------------------
bool
- HijackBroadcaster (Listener *listener, uint32_t event_mask = UINT32_MAX);
+ HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX)
+ {
+ return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask);
+ }
bool
- IsHijackedForEvent (uint32_t event_mask);
+ IsHijackedForEvent (uint32_t event_mask)
+ {
+ return m_broadcaster_sp->IsHijackedForEvent(event_mask);
+ }
//------------------------------------------------------------------
/// Restore the state of the Broadcaster from a previous hijack attempt.
///
//------------------------------------------------------------------
void
- RestoreBroadcaster ();
+ RestoreBroadcaster ()
+ {
+ m_broadcaster_sp->RestoreBroadcaster();
+ }
// This needs to be filled in if you are going to register the broadcaster with the broadcaster
// manager and do broadcaster class matching.
@@ -432,35 +515,158 @@ public:
// with the BroadcasterManager, so that it is clearer how to add one.
virtual ConstString &GetBroadcasterClass() const;
- BroadcasterManager *GetManager();
+ lldb::BroadcasterManagerSP GetManager();
protected:
- void
- PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique);
+ // BroadcasterImpl contains the actual Broadcaster implementation. The Broadcaster makes a BroadcasterImpl
+ // which lives as long as it does. The Listeners & the Events hold a weak pointer to the BroadcasterImpl,
+ // so that they can survive if a Broadcaster they were listening to is destroyed w/o their being able to
+ // unregister from it (which can happen if the Broadcasters & Listeners are being destroyed on separate threads
+ // simultaneously.
+ // The Broadcaster itself can't be shared out as a weak pointer, because some things that are broadcasters
+ // (e.g. the Target and the Process) are shared in their own right.
+ //
+ // For the most part, the Broadcaster functions dispatch to the BroadcasterImpl, and are documented in the
+ // public Broadcaster API above.
+
+
+ class BroadcasterImpl
+ {
+ friend class Listener;
+ friend class Broadcaster;
+ public:
+ BroadcasterImpl (Broadcaster &broadcaster);
+
+ ~BroadcasterImpl() = default;
+
+ void
+ BroadcastEvent (lldb::EventSP &event_sp);
+
+ void
+ BroadcastEventIfUnique (lldb::EventSP &event_sp);
+ void
+ BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);
+
+ void
+ BroadcastEvent(uint32_t event_type, const lldb::EventDataSP &event_data_sp);
+
+ void
+ BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr);
+
+ void
+ Clear();
+
+ uint32_t
+ AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask);
+
+ const char *
+ GetBroadcasterName () const
+ {
+ return m_broadcaster.GetBroadcasterName().AsCString();
+ }
+
+ Broadcaster *
+ GetBroadcaster();
+
+ bool
+ GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const;
+
+ void
+ SetEventName (uint32_t event_mask, const char *name)
+ {
+ m_event_names[event_mask] = name;
+ }
+
+ const char *
+ GetEventName (uint32_t event_mask) const
+ {
+ const auto pos = m_event_names.find (event_mask);
+ if (pos != m_event_names.end())
+ return pos->second.c_str();
+ return nullptr;
+ }
+
+ bool
+ EventTypeHasListeners (uint32_t event_type);
+
+ bool
+ RemoveListener (lldb_private::Listener *listener, uint32_t event_mask = UINT32_MAX);
+
+ bool
+ RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX);
+
+ bool
+ HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX);
+
+ bool
+ IsHijackedForEvent (uint32_t event_mask);
+
+ void
+ RestoreBroadcaster ();
+
+ protected:
+ void
+ PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique);
+
+ const char *
+ GetHijackingListenerName();
+
+ //------------------------------------------------------------------
+ //
+ //------------------------------------------------------------------
+ typedef std::list< std::pair<lldb::ListenerWP,uint32_t> > collection;
+ typedef std::map<uint32_t, std::string> event_names_map;
+
+ void
+ ListenerIterator (std::function <bool (const lldb::ListenerSP &listener_sp, uint32_t &event_mask)> const &callback);
+
+
+ Broadcaster &m_broadcaster; ///< The broadcsater that this implements
+ event_names_map m_event_names; ///< Optionally define event names for readability and logging for each event bit
+ collection m_listeners; ///< A list of Listener / event_mask pairs that are listening to this broadcaster.
+ std::recursive_mutex m_listeners_mutex; ///< A mutex that protects \a m_listeners.
+ std::vector<lldb::ListenerSP> m_hijacking_listeners; // A simple mechanism to intercept events from a broadcaster
+ std::vector<uint32_t> m_hijacking_masks; // At some point we may want to have a stack or Listener
+ // collections, but for now this is just for private hijacking.
+
+ private:
+ //------------------------------------------------------------------
+ // For Broadcaster only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (BroadcasterImpl);
+ };
+
+ typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP;
+ typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP;
+
+ BroadcasterImplSP
+ GetBroadcasterImpl()
+ {
+ return m_broadcaster_sp;
+ }
+
+ const char *
+ GetHijackingListenerName()
+ {
+ return m_broadcaster_sp->GetHijackingListenerName();
+ }
//------------------------------------------------------------------
// Classes that inherit from Broadcaster can see and modify these
//------------------------------------------------------------------
- typedef std::vector< std::pair<Listener*,uint32_t> > collection;
- typedef std::map<uint32_t, std::string> event_names_map;
- // Prefix the name of our member variables with "m_broadcaster_"
- // since this is a class that gets subclassed.
- const ConstString m_broadcaster_name; ///< The name of this broadcaster object.
- event_names_map m_event_names; ///< Optionally define event names for readability and logging for each event bit
- collection m_listeners; ///< A list of Listener / event_mask pairs that are listening to this broadcaster.
- Mutex m_listeners_mutex; ///< A mutex that protects \a m_listeners.
- std::vector<Listener *> m_hijacking_listeners; // A simple mechanism to intercept events from a broadcaster
- std::vector<uint32_t> m_hijacking_masks; // At some point we may want to have a stack or Listener
- // collections, but for now this is just for private hijacking.
- BroadcasterManager *m_manager;
+
private:
//------------------------------------------------------------------
// For Broadcaster only
//------------------------------------------------------------------
+ BroadcasterImplSP m_broadcaster_sp;
+ lldb::BroadcasterManagerSP m_manager_sp;
+ const ConstString m_broadcaster_name; ///< The name of this broadcaster object.
+
DISALLOW_COPY_AND_ASSIGN (Broadcaster);
};
} // namespace lldb_private
-#endif // liblldb_Broadcaster_h_
+#endif // liblldb_Broadcaster_h_
diff --git a/include/lldb/Core/Communication.h b/include/lldb/Core/Communication.h
index d29aaca9c2ea..8913f1631a8b 100644
--- a/include/lldb/Core/Communication.h
+++ b/include/lldb/Core/Communication.h
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <atomic>
+#include <mutex>
#include <string>
// Other libraries and framework includes
@@ -21,7 +22,6 @@
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/HostThread.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/lldb-private.h"
namespace lldb_private {
@@ -358,10 +358,10 @@ protected:
HostThread m_read_thread; ///< The read thread handle in case we need to cancel the thread.
std::atomic<bool> m_read_thread_enabled;
std::atomic<bool> m_read_thread_did_exit;
- std::string m_bytes; ///< A buffer to cache bytes read in the ReadThread function.
- Mutex m_bytes_mutex; ///< A mutex to protect multi-threaded access to the cached bytes.
- Mutex m_write_mutex; ///< Don't let multiple threads write at the same time...
- Mutex m_synchronize_mutex;
+ std::string m_bytes; ///< A buffer to cache bytes read in the ReadThread function.
+ std::recursive_mutex m_bytes_mutex; ///< A mutex to protect multi-threaded access to the cached bytes.
+ std::mutex m_write_mutex; ///< Don't let multiple threads write at the same time...
+ std::mutex m_synchronize_mutex;
ReadThreadBytesReceived m_callback;
void *m_callback_baton;
bool m_close_on_eof;
diff --git a/include/lldb/Core/ConstString.h b/include/lldb/Core/ConstString.h
index 6e234da0a595..c678168790a8 100644
--- a/include/lldb/Core/ConstString.h
+++ b/include/lldb/Core/ConstString.h
@@ -291,12 +291,37 @@ public:
}
//------------------------------------------------------------------
+ /// Equal to operator
+ ///
+ /// Returns true if this string is equal to the string in \a rhs.
+ /// If case sensitive equality is tested, this operation is very
+ /// fast as it results in a pointer comparison since all strings
+ /// are in a uniqued in a global string pool.
+ ///
+ /// @param[in] rhs
+ /// The Left Hand Side const ConstString object reference.
+ ///
+ /// @param[in] rhs
+ /// The Right Hand Side const ConstString object reference.
+ ///
+ /// @param[in] case_sensitive
+ /// Case sensitivity. If true, case sensitive equality
+ /// will be tested, otherwise character case will be ignored
+ ///
+ /// @return
+ /// @li \b true if this object is equal to \a rhs.
+ /// @li \b false if this object is not equal to \a rhs.
+ //------------------------------------------------------------------
+ static bool
+ Equals(const ConstString &lhs, const ConstString &rhs, const bool case_sensitive = true);
+
+ //------------------------------------------------------------------
/// Compare two string objects.
///
/// Compares the C string values contained in \a lhs and \a rhs and
/// returns an integer result.
///
- /// NOTE: only call this function when you want a true string
+ /// NOTE: only call this function when you want a true string
/// comparison. If you want string equality use the, use the ==
/// operator as it is much more efficient. Also if you want string
/// inequality, use the != operator for the same reasons.
@@ -307,13 +332,17 @@ public:
/// @param[in] rhs
/// The Right Hand Side const ConstString object reference.
///
+ /// @param[in] case_sensitive
+ /// Case sensitivity of compare. If true, case sensitive compare
+ /// will be performed, otherwise character case will be ignored
+ ///
/// @return
/// @li -1 if lhs < rhs
/// @li 0 if lhs == rhs
/// @li 1 if lhs > rhs
//------------------------------------------------------------------
static int
- Compare (const ConstString& lhs, const ConstString& rhs);
+ Compare(const ConstString &lhs, const ConstString &rhs, const bool case_sensitive = true);
//------------------------------------------------------------------
/// Dump the object description to a stream.
diff --git a/include/lldb/Core/DataExtractor.h b/include/lldb/Core/DataExtractor.h
index d5cb5e8ba4bc..51ecade2d374 100644
--- a/include/lldb/Core/DataExtractor.h
+++ b/include/lldb/Core/DataExtractor.h
@@ -763,8 +763,10 @@ public:
///
/// @param[in] bitfield_bit_offset
/// The bit offset of the bitfield value in the extracted
- /// integer (the number of bits to shift the integer to the
- /// right).
+ /// integer. For little-endian data, this is the offset of
+ /// the LSB of the bitfield from the LSB of the integer.
+ /// For big-endian data, this is the offset of the MSB of the
+ /// bitfield from the MSB of the integer.
///
/// @return
/// The unsigned bitfield integer value that was extracted, or
@@ -805,8 +807,10 @@ public:
///
/// @param[in] bitfield_bit_offset
/// The bit offset of the bitfield value in the extracted
- /// integer (the number of bits to shift the integer to the
- /// right).
+ /// integer. For little-endian data, this is the offset of
+ /// the LSB of the bitfield from the LSB of the integer.
+ /// For big-endian data, this is the offset of the MSB of the
+ /// bitfield from the MSB of the integer.
///
/// @return
/// The signed bitfield integer value that was extracted, or
diff --git a/include/lldb/Core/Debugger.h b/include/lldb/Core/Debugger.h
index 4ca648ca296e..7a969457eef6 100644
--- a/include/lldb/Core/Debugger.h
+++ b/include/lldb/Core/Debugger.h
@@ -16,6 +16,7 @@
// C++ Includes
#include <memory>
#include <map>
+#include <mutex>
#include <vector>
// Other libraries and framework includes
@@ -53,8 +54,7 @@ namespace lldb_private {
class Debugger :
public std::enable_shared_from_this<Debugger>,
public UserID,
- public Properties,
- public BroadcasterManager
+ public Properties
{
friend class SourceManager; // For GetSourceFileCache.
@@ -159,10 +159,10 @@ public:
return *m_command_interpreter_ap;
}
- Listener &
+ lldb::ListenerSP
GetListener ()
{
- return m_listener;
+ return m_listener_sp;
}
// This returns the Debugger's scratch source manager. It won't be able to look up files in debug
@@ -392,6 +392,12 @@ public:
Target *GetSelectedOrDummyTarget(bool prefer_dummy = false);
Target *GetDummyTarget();
+ lldb::BroadcasterManagerSP
+ GetBroadcasterManager()
+ {
+ return m_broadcaster_manager_sp;
+ }
+
protected:
friend class CommandInterpreter;
friend class REPL;
@@ -446,15 +452,20 @@ protected:
void
InstanceInitialize ();
-
+
lldb::StreamFileSP m_input_file_sp;
lldb::StreamFileSP m_output_file_sp;
lldb::StreamFileSP m_error_file_sp;
+
+ lldb::BroadcasterManagerSP m_broadcaster_manager_sp; // The debugger acts as a broadcaster manager of last resort.
+ // It needs to get constructed before the target_list or any other
+ // member that might want to broadcast through the debugger.
+
TerminalState m_terminal_state;
TargetList m_target_list;
PlatformList m_platform_list;
- Listener m_listener;
+ lldb::ListenerSP m_listener_sp;
std::unique_ptr<SourceManager> m_source_manager_ap; // This is a scratch source manager that we return if we have no targets.
SourceManager::SourceFileCache m_source_file_cache; // All the source managers for targets created in this debugger used this shared
// source file cache.
@@ -472,6 +483,7 @@ protected:
HostThread m_io_handler_thread;
Broadcaster m_sync_broadcaster;
lldb::ListenerSP m_forward_listener_sp;
+ std::once_flag m_clear_once;
//----------------------------------------------------------------------
// Events for m_sync_broadcaster
diff --git a/include/lldb/Core/EmulateInstruction.h b/include/lldb/Core/EmulateInstruction.h
index c5e60022fc96..36fff43bf6bc 100644
--- a/include/lldb/Core/EmulateInstruction.h
+++ b/include/lldb/Core/EmulateInstruction.h
@@ -384,6 +384,11 @@ public:
const RegisterInfo *reg_info,
const RegisterValue &reg_value);
+ // Type to represent the condition of an instruction. The UINT32 value is reserved for the
+ // unconditional case and all other value can be used in an architecture dependent way.
+ typedef uint32_t InstructionCondition;
+ static const InstructionCondition UnconditionalCondition = UINT32_MAX;
+
EmulateInstruction (const ArchSpec &arch);
~EmulateInstruction() override = default;
@@ -403,8 +408,8 @@ public:
virtual bool
EvaluateInstruction (uint32_t evaluate_options) = 0;
- virtual bool
- IsInstructionConditional() { return false; }
+ virtual InstructionCondition
+ GetInstructionCondition() { return UnconditionalCondition; }
virtual bool
TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) = 0;
diff --git a/include/lldb/Core/Event.h b/include/lldb/Core/Event.h
index e8867c0e7e77..1ae0fc83b27e 100644
--- a/include/lldb/Core/Event.h
+++ b/include/lldb/Core/Event.h
@@ -20,6 +20,7 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Host/Predicate.h"
+#include "lldb/Core/Broadcaster.h"
namespace lldb_private {
@@ -113,20 +114,66 @@ private:
DISALLOW_COPY_AND_ASSIGN (EventDataBytes);
};
+class EventDataReceipt : public EventData
+{
+public:
+ EventDataReceipt() :
+ EventData(),
+ m_predicate(false)
+ {
+ }
+
+ ~EventDataReceipt() override
+ {
+ }
+
+ static const ConstString &
+ GetFlavorString ()
+ {
+ static ConstString g_flavor("Process::ProcessEventData");
+ return g_flavor;
+ }
+
+ const ConstString &
+ GetFlavor () const override
+ {
+ return GetFlavorString();
+ }
+
+ bool
+ WaitForEventReceived (const TimeValue *abstime = nullptr, bool *timed_out = nullptr)
+ {
+ return m_predicate.WaitForValueEqualTo(true, abstime, timed_out);
+ }
+
+private:
+ Predicate<bool> m_predicate;
+
+ void
+ DoOnRemoval (Event *event_ptr) override
+ {
+ m_predicate.SetValue(true, eBroadcastAlways);
+ }
+};
+
//----------------------------------------------------------------------
// lldb::Event
//----------------------------------------------------------------------
class Event
{
- friend class Broadcaster;
friend class Listener;
friend class EventData;
+ friend class Broadcaster::BroadcasterImpl;
public:
Event(Broadcaster *broadcaster, uint32_t event_type, EventData *data = nullptr);
+ Event(Broadcaster *broadcaster, uint32_t event_type, const lldb::EventDataSP &event_data_sp);
+
Event(uint32_t event_type, EventData *data = nullptr);
+ Event(uint32_t event_type, const lldb::EventDataSP &event_data_sp);
+
~Event ();
void
@@ -135,19 +182,19 @@ public:
EventData *
GetData ()
{
- return m_data_ap.get();
+ return m_data_sp.get();
}
const EventData *
GetData () const
{
- return m_data_ap.get();
+ return m_data_sp.get();
}
void
SetData (EventData *new_data)
{
- m_data_ap.reset (new_data);
+ m_data_sp.reset (new_data);
}
uint32_t
@@ -165,19 +212,27 @@ public:
Broadcaster *
GetBroadcaster () const
{
- return m_broadcaster;
+ Broadcaster::BroadcasterImplSP broadcaster_impl_sp = m_broadcaster_wp.lock();
+ if (broadcaster_impl_sp)
+ return broadcaster_impl_sp->GetBroadcaster();
+ else
+ return nullptr;
}
bool
BroadcasterIs (Broadcaster *broadcaster)
{
- return broadcaster == m_broadcaster;
+ Broadcaster::BroadcasterImplSP broadcaster_impl_sp = m_broadcaster_wp.lock();
+ if (broadcaster_impl_sp)
+ return broadcaster_impl_sp->GetBroadcaster() == broadcaster;
+ else
+ return false;
}
void
Clear()
{
- m_data_ap.reset();
+ m_data_sp.reset();
}
private:
@@ -194,12 +249,12 @@ private:
void
SetBroadcaster (Broadcaster *broadcaster)
{
- m_broadcaster = broadcaster;
+ m_broadcaster_wp = broadcaster->GetBroadcasterImpl();
}
- Broadcaster * m_broadcaster; // The broadcaster that sent this event
- uint32_t m_type; // The bit describing this event
- std::unique_ptr<EventData> m_data_ap; // User specific data for this event
+ Broadcaster::BroadcasterImplWP m_broadcaster_wp; // The broadcaster that sent this event
+ uint32_t m_type; // The bit describing this event
+ lldb::EventDataSP m_data_sp; // User specific data for this event
DISALLOW_COPY_AND_ASSIGN (Event);
diff --git a/include/lldb/Core/History.h b/include/lldb/Core/History.h
index fbb7bd8b0c1a..164d1bfb651b 100644
--- a/include/lldb/Core/History.h
+++ b/include/lldb/Core/History.h
@@ -14,13 +14,13 @@
#include <stdint.h>
// C++ Includes
+#include <mutex>
#include <stack>
#include <string>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -34,11 +34,7 @@ class HistorySource
public:
typedef const void * HistoryEvent;
- HistorySource () :
- m_mutex (Mutex::eMutexTypeRecursive),
- m_events ()
- {
- }
+ HistorySource() : m_mutex(), m_events() {}
virtual
~HistorySource()
@@ -50,20 +46,20 @@ public:
// onto the end of the history stack.
virtual HistoryEvent
- CreateHistoryEvent () = 0;
-
+ CreateHistoryEvent () = 0;
+
virtual void
DeleteHistoryEvent (HistoryEvent event) = 0;
-
+
virtual void
DumpHistoryEvent (Stream &strm, HistoryEvent event) = 0;
virtual size_t
GetHistoryEventCount() = 0;
-
+
virtual HistoryEvent
GetHistoryEventAtIndex (uint32_t idx) = 0;
-
+
virtual HistoryEvent
GetCurrentHistoryEvent () = 0;
@@ -71,16 +67,16 @@ public:
virtual int
CompareHistoryEvents (const HistoryEvent lhs,
const HistoryEvent rhs) = 0;
-
+
virtual bool
IsCurrentHistoryEvent (const HistoryEvent event) = 0;
private:
typedef std::stack<HistoryEvent> collection;
- Mutex m_mutex;
+ std::recursive_mutex m_mutex;
collection m_events;
-
+
DISALLOW_COPY_AND_ASSIGN (HistorySource);
};
diff --git a/include/lldb/Core/IOHandler.h b/include/lldb/Core/IOHandler.h
index 3eba1c3cc9d8..1844df365158 100644
--- a/include/lldb/Core/IOHandler.h
+++ b/include/lldb/Core/IOHandler.h
@@ -15,6 +15,7 @@
// C++ Includes
#include <memory>
+#include <mutex>
#include <string>
#include <vector>
@@ -28,7 +29,6 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/StringList.h"
#include "lldb/Core/ValueObjectList.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/Predicate.h"
namespace curses
@@ -709,75 +709,70 @@ namespace lldb_private {
class IOHandlerStack
{
public:
- IOHandlerStack () :
- m_stack(),
- m_mutex(Mutex::eMutexTypeRecursive),
- m_top (nullptr)
- {
- }
-
+ IOHandlerStack() : m_stack(), m_mutex(), m_top(nullptr) {}
+
~IOHandlerStack() = default;
-
+
size_t
- GetSize () const
+ GetSize() const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_stack.size();
}
-
+
void
- Push (const lldb::IOHandlerSP& sp)
+ Push(const lldb::IOHandlerSP &sp)
{
if (sp)
{
- Mutex::Locker locker (m_mutex);
- sp->SetPopped (false);
- m_stack.push_back (sp);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ sp->SetPopped(false);
+ m_stack.push_back(sp);
// Set m_top the non-locking IsTop() call
m_top = sp.get();
}
}
-
+
bool
- IsEmpty () const
+ IsEmpty() const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_stack.empty();
}
-
+
lldb::IOHandlerSP
- Top ()
+ Top()
{
lldb::IOHandlerSP sp;
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_stack.empty())
sp = m_stack.back();
}
return sp;
}
-
+
void
- Pop ()
+ Pop()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_stack.empty())
{
- lldb::IOHandlerSP sp (m_stack.back());
+ lldb::IOHandlerSP sp(m_stack.back());
m_stack.pop_back();
- sp->SetPopped (true);
+ sp->SetPopped(true);
}
// Set m_top the non-locking IsTop() call
m_top = (m_stack.empty() ? nullptr : m_stack.back().get());
}
- Mutex &
+ std::recursive_mutex &
GetMutex()
{
return m_mutex;
}
-
+
bool
IsTop (const lldb::IOHandlerSP &io_handler_sp) const
{
@@ -785,13 +780,12 @@ namespace lldb_private {
}
bool
- CheckTopIOHandlerTypes (IOHandler::Type top_type, IOHandler::Type second_top_type)
+ CheckTopIOHandlerTypes(IOHandler::Type top_type, IOHandler::Type second_top_type)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const size_t num_io_handlers = m_stack.size();
- return (num_io_handlers >= 2 &&
- m_stack[num_io_handlers-1]->GetType() == top_type &&
- m_stack[num_io_handlers-2]->GetType() == second_top_type);
+ return (num_io_handlers >= 2 && m_stack[num_io_handlers - 1]->GetType() == top_type &&
+ m_stack[num_io_handlers - 2]->GetType() == second_top_type);
}
ConstString
@@ -818,9 +812,9 @@ namespace lldb_private {
protected:
typedef std::vector<lldb::IOHandlerSP> collection;
collection m_stack;
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
IOHandler *m_top;
-
+
private:
DISALLOW_COPY_AND_ASSIGN (IOHandlerStack);
};
diff --git a/include/lldb/Core/Listener.h b/include/lldb/Core/Listener.h
index b11c1644507b..1057cf35c6db 100644
--- a/include/lldb/Core/Listener.h
+++ b/include/lldb/Core/Listener.h
@@ -14,18 +14,21 @@
// C++ Includes
#include <list>
#include <map>
+#include <mutex>
#include <string>
#include <vector>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
-#include "lldb/Host/Predicate.h"
+#include "lldb/Core/Broadcaster.h"
+#include "lldb/Host/Condition.h"
#include "lldb/Core/Event.h"
namespace lldb_private {
-class Listener
+class Listener :
+ public std::enable_shared_from_this<Listener>
{
public:
typedef bool (*HandleBroadcastCallback) (lldb::EventSP &event_sp, void *baton);
@@ -36,8 +39,16 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
+ //
+ // Listeners have to be constructed into shared pointers - at least if you want them to listen to
+ // Broadcasters,
+protected:
Listener (const char *name);
+public:
+ static lldb::ListenerSP
+ MakeListener(const char *name);
+
~Listener ();
void
@@ -53,11 +64,11 @@ public:
}
uint32_t
- StartListeningForEventSpec (BroadcasterManager &manager,
+ StartListeningForEventSpec (lldb::BroadcasterManagerSP manager_sp,
const BroadcastEventSpec &event_spec);
bool
- StopListeningForEventSpec (BroadcasterManager &manager,
+ StopListeningForEventSpec (lldb::BroadcasterManagerSP manager_sp,
const BroadcastEventSpec &event_spec);
uint32_t
@@ -133,12 +144,15 @@ private:
void *callback_user_data;
};
- typedef std::multimap<Broadcaster*, BroadcasterInfo> broadcaster_collection;
+ typedef std::multimap<Broadcaster::BroadcasterImplWP,
+ BroadcasterInfo,
+ std::owner_less<Broadcaster::BroadcasterImplWP>> broadcaster_collection;
typedef std::list<lldb::EventSP> event_collection;
- typedef std::vector<BroadcasterManager *> broadcaster_manager_collection;
+ typedef std::vector<lldb::BroadcasterManagerWP> broadcaster_manager_collection;
bool
- FindNextEventInternal(Broadcaster *broadcaster, // nullptr for any broadcaster
+ FindNextEventInternal(Mutex::Locker& lock,
+ Broadcaster *broadcaster, // nullptr for any broadcaster
const ConstString *sources, // nullptr for any event
uint32_t num_sources,
uint32_t event_type_mask,
@@ -162,17 +176,17 @@ private:
std::string m_name;
broadcaster_collection m_broadcasters;
- Mutex m_broadcasters_mutex; // Protects m_broadcasters
+ std::recursive_mutex m_broadcasters_mutex; // Protects m_broadcasters
event_collection m_events;
Mutex m_events_mutex; // Protects m_broadcasters and m_events
- Predicate<bool> m_cond_wait;
+ Condition m_events_condition;
broadcaster_manager_collection m_broadcaster_managers;
void
BroadcasterWillDestruct (Broadcaster *);
void
- BroadcasterManagerWillDestruct (BroadcasterManager *manager);
+ BroadcasterManagerWillDestruct (lldb::BroadcasterManagerSP manager_sp);
// broadcaster_collection::iterator
diff --git a/include/lldb/Core/Logging.h b/include/lldb/Core/Logging.h
index ca04c84b21a6..da8c0d8f5bb6 100644
--- a/include/lldb/Core/Logging.h
+++ b/include/lldb/Core/Logging.h
@@ -49,6 +49,7 @@
#define LIBLLDB_LOG_JIT_LOADER (1u << 27)
#define LIBLLDB_LOG_LANGUAGE (1u << 28)
#define LIBLLDB_LOG_DATAFORMATTERS (1u << 29)
+#define LIBLLDB_LOG_DEMANGLE (1u << 30)
#define LIBLLDB_LOG_ALL (UINT32_MAX)
#define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\
LIBLLDB_LOG_THREAD |\
diff --git a/include/lldb/Core/MappedHash.h b/include/lldb/Core/MappedHash.h
index 5a52ab2b8b2d..b7cf3b02e01e 100644
--- a/include/lldb/Core/MappedHash.h
+++ b/include/lldb/Core/MappedHash.h
@@ -47,6 +47,9 @@ public:
static uint32_t
HashString (uint32_t hash_function, const char *s)
{
+ if (!s)
+ return 0;
+
switch (hash_function)
{
case MappedHash::eHashFunctionDJB:
@@ -434,6 +437,9 @@ public:
bool
Find (const char *name, Pair &pair) const
{
+ if (!name || !name[0])
+ return false;
+
if (IsValid ())
{
const uint32_t bucket_count = m_header.bucket_count;
diff --git a/include/lldb/Core/Module.h b/include/lldb/Core/Module.h
index 35b182aa9801..46fa330fb19c 100644
--- a/include/lldb/Core/Module.h
+++ b/include/lldb/Core/Module.h
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <atomic>
+#include <mutex>
#include <string>
#include <vector>
@@ -22,11 +23,11 @@
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/UUID.h"
#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/PathMappingList.h"
+#include "llvm/ADT/DenseSet.h"
namespace lldb_private {
@@ -67,7 +68,7 @@ public:
static Module *
GetAllocatedModuleAtIndex (size_t idx);
- static Mutex *
+ static std::recursive_mutex &
GetAllocationModuleCollectionMutex();
//------------------------------------------------------------------
@@ -498,6 +499,7 @@ public:
const ConstString &type_name,
bool exact_match,
size_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeList& types);
lldb::TypeSP
@@ -984,8 +986,8 @@ public:
// SymbolVendor, SymbolFile and ObjectFile member objects should
// lock the module mutex to avoid deadlocks.
//------------------------------------------------------------------
- Mutex &
- GetMutex () const
+ std::recursive_mutex &
+ GetMutex() const
{
return m_mutex;
}
@@ -1046,65 +1048,96 @@ public:
bool
RemapSourceFile (const char *path, std::string &new_path) const;
- //------------------------------------------------------------------
- /// Prepare to do a function name lookup.
- ///
- /// Looking up functions by name can be a tricky thing. LLDB requires
- /// that accelerator tables contain full names for functions as well
- /// as function basenames which include functions, class methods and
- /// class functions. When the user requests that an action use a
- /// function by name, we are sometimes asked to automatically figure
- /// out what a name could possibly map to. A user might request a
- /// breakpoint be set on "count". If no options are supplied to limit
- /// the scope of where to search for count, we will by default match
- /// any function names named "count", all class and instance methods
- /// named "count" (no matter what the namespace or contained context)
- /// and any selectors named "count". If a user specifies "a::b" we
- /// will search for the basename "b", and then prune the results that
- /// don't match "a::b" (note that "c::a::b" and "d::e::a::b" will
- /// match a query of "a::b".
- ///
- /// @param[in] name
- /// The user supplied name to use in the lookup
- ///
- /// @param[in] name_type_mask
- /// The mask of bits from lldb::FunctionNameType enumerations
- /// that tell us what kind of name we are looking for.
- ///
- /// @param[out] language
- /// If known, the language to use for determining the
- /// lookup_name_type_mask.
- ///
- /// @param[out] lookup_name
- /// The actual name that will be used when calling
- /// SymbolVendor::FindFunctions() or Symtab::FindFunctionSymbols()
- ///
- /// @param[out] lookup_name_type_mask
- /// The actual name mask that should be used in the calls to
- /// SymbolVendor::FindFunctions() or Symtab::FindFunctionSymbols()
- ///
- /// @param[out] match_name_after_lookup
- /// A boolean that indicates if we need to iterate through any
- /// match results obtained from SymbolVendor::FindFunctions() or
- /// Symtab::FindFunctionSymbols() to see if the name contains
- /// \a name. For example if \a name is "a::b", this function will
- /// return a \a lookup_name of "b", with \a match_name_after_lookup
- /// set to true to indicate any matches will need to be checked
- /// to make sure they contain \a name.
- //------------------------------------------------------------------
- static void
- PrepareForFunctionNameLookup (const ConstString &name,
- uint32_t name_type_mask,
- lldb::LanguageType language,
- ConstString &lookup_name,
- uint32_t &lookup_name_type_mask,
- bool &match_name_after_lookup);
+ //----------------------------------------------------------------------
+ /// @class LookupInfo Module.h "lldb/Core/Module.h"
+ /// @brief A class that encapsulates name lookup information.
+ ///
+ /// Users can type a wide variety of partial names when setting
+ /// breakpoints by name or when looking for functions by name.
+ /// SymbolVendor and SymbolFile objects are only required to implement
+ /// name lookup for function basenames and for fully mangled names.
+ /// This means if the user types in a partial name, we must reduce this
+ /// to a name lookup that will work with all SymbolFile objects. So we
+ /// might reduce a name lookup to look for a basename, and then prune
+ /// out any results that don't match.
+ ///
+ /// The "m_name" member variable represents the name as it was typed
+ /// by the user. "m_lookup_name" will be the name we actually search
+ /// for through the symbol or objects files. Lanaguage is included in
+ /// case we need to filter results by language at a later date. The
+ /// "m_name_type_mask" member variable tells us what kinds of names we
+ /// are looking for and can help us prune out unwanted results.
+ ///
+ /// Function lookups are done in Module.cpp, ModuleList.cpp and in
+ /// BreakpointResolverName.cpp and they all now use this class to do
+ /// lookups correctly.
+ //----------------------------------------------------------------------
+ class LookupInfo
+ {
+ public:
+ LookupInfo() :
+ m_name(),
+ m_lookup_name(),
+ m_language(lldb::eLanguageTypeUnknown),
+ m_name_type_mask(0),
+ m_match_name_after_lookup(false)
+ {
+ }
+
+ LookupInfo(const ConstString &name, uint32_t name_type_mask, lldb::LanguageType language);
+
+ const ConstString &
+ GetName() const
+ {
+ return m_name;
+ }
+
+ void
+ SetName(const ConstString &name)
+ {
+ m_name = name;
+ }
+
+ const ConstString &
+ GetLookupName() const
+ {
+ return m_lookup_name;
+ }
+
+ void
+ SetLookupName(const ConstString &name)
+ {
+ m_lookup_name = name;
+ }
+
+ uint32_t
+ GetNameTypeMask() const
+ {
+ return m_name_type_mask;
+ }
+
+ void
+ SetNameTypeMask(uint32_t mask)
+ {
+ m_name_type_mask = mask;
+ }
+
+ void
+ Prune(SymbolContextList &sc_list, size_t start_idx) const;
+
+ protected:
+ ConstString m_name; ///< What the user originally typed
+ ConstString m_lookup_name; ///< The actual name will lookup when calling in the object or symbol file
+ lldb::LanguageType m_language; ///< Limit matches to only be for this language
+ uint32_t m_name_type_mask; ///< One or more bits from lldb::FunctionNameType that indicate what kind of names we are looking for
+ bool m_match_name_after_lookup; ///< If \b true, then demangled names that match will need to contain "m_name" in order to be considered a match
+ };
protected:
//------------------------------------------------------------------
// Member Variables
//------------------------------------------------------------------
- mutable Mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments.
+ mutable std::recursive_mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments.
TimeValue m_mod_time; ///< The modification time for this module when it was created.
ArchSpec m_arch; ///< The architecture for this module.
UUID m_uuid; ///< Each module is assumed to have a unique identifier to help match it up to debug symbols.
@@ -1194,6 +1227,7 @@ private:
const CompilerDeclContext *parent_decl_ctx,
bool append,
size_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap& types);
DISALLOW_COPY_AND_ASSIGN (Module);
diff --git a/include/lldb/Core/ModuleList.h b/include/lldb/Core/ModuleList.h
index a0dd43263a2c..38a91b0bf0ee 100644
--- a/include/lldb/Core/ModuleList.h
+++ b/include/lldb/Core/ModuleList.h
@@ -14,13 +14,14 @@
// C++ Includes
#include <functional>
#include <list>
+#include <mutex>
#include <vector>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Utility/Iterable.h"
+#include "llvm/ADT/DenseSet.h"
namespace lldb_private {
@@ -163,13 +164,13 @@ public:
void
LogUUIDAndPaths (Log *log, const char *prefix_cstr);
-
- Mutex &
- GetMutex () const
+
+ std::recursive_mutex &
+ GetMutex() const
{
return m_modules_mutex;
}
-
+
size_t
GetIndexForModule (const Module *module) const;
@@ -450,6 +451,7 @@ public:
const ConstString &name,
bool name_is_fully_qualified,
size_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files,
TypeList& types) const;
bool
@@ -591,12 +593,12 @@ protected:
// Member variables.
//------------------------------------------------------------------
collection m_modules; ///< The collection of modules.
- mutable Mutex m_modules_mutex;
+ mutable std::recursive_mutex m_modules_mutex;
Notifier* m_notifier;
public:
- typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter> ModuleIterable;
+ typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter, std::recursive_mutex> ModuleIterable;
ModuleIterable
Modules()
{
diff --git a/include/lldb/Core/ModuleSpec.h b/include/lldb/Core/ModuleSpec.h
index 95de7f375736..245cb2365b2e 100644
--- a/include/lldb/Core/ModuleSpec.h
+++ b/include/lldb/Core/ModuleSpec.h
@@ -12,6 +12,7 @@
// C Includes
// C++ Includes
+#include <mutex>
#include <vector>
// Other libraries and framework includes
@@ -20,7 +21,6 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/UUID.h"
#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/PathMappingList.h"
namespace lldb_private {
@@ -447,30 +447,24 @@ protected:
class ModuleSpecList
{
public:
- ModuleSpecList () :
- m_specs(),
- m_mutex(Mutex::eMutexTypeRecursive)
- {
- }
+ ModuleSpecList() : m_specs(), m_mutex() {}
- ModuleSpecList (const ModuleSpecList &rhs) :
- m_specs(),
- m_mutex(Mutex::eMutexTypeRecursive)
+ ModuleSpecList(const ModuleSpecList &rhs) : m_specs(), m_mutex()
{
- 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_specs = rhs.m_specs;
}
~ModuleSpecList() = default;
ModuleSpecList &
- operator = (const ModuleSpecList &rhs)
+ operator=(const ModuleSpecList &rhs)
{
if (this != &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_specs = rhs.m_specs;
}
return *this;
@@ -479,29 +473,29 @@ public:
size_t
GetSize() const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_specs.size();
}
void
- Clear ()
+ Clear()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_specs.clear();
}
void
- Append (const ModuleSpec &spec)
+ Append(const ModuleSpec &spec)
{
- Mutex::Locker locker(m_mutex);
- m_specs.push_back (spec);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_specs.push_back(spec);
}
void
- Append (const ModuleSpecList &rhs)
+ Append(const ModuleSpecList &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_specs.insert(m_specs.end(), rhs.m_specs.begin(), rhs.m_specs.end());
}
@@ -514,9 +508,9 @@ public:
}
bool
- GetModuleSpecAtIndex (size_t i, ModuleSpec &module_spec) const
+ GetModuleSpecAtIndex(size_t i, ModuleSpec &module_spec) const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (i < m_specs.size())
{
module_spec = m_specs[i];
@@ -527,11 +521,11 @@ public:
}
bool
- FindMatchingModuleSpec (const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const
+ FindMatchingModuleSpec(const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
bool exact_arch_match = true;
- for (auto spec: m_specs)
+ for (auto spec : m_specs)
{
if (spec.Matches(module_spec, exact_arch_match))
{
@@ -539,12 +533,12 @@ public:
return true;
}
}
-
+
// If there was an architecture, retry with a compatible arch
if (module_spec.GetArchitecturePtr())
{
exact_arch_match = false;
- for (auto spec: m_specs)
+ for (auto spec : m_specs)
{
if (spec.Matches(module_spec, exact_arch_match))
{
@@ -556,41 +550,41 @@ public:
match_module_spec.Clear();
return false;
}
-
+
size_t
- FindMatchingModuleSpecs (const ModuleSpec &module_spec, ModuleSpecList &matching_list) const
+ FindMatchingModuleSpecs(const ModuleSpec &module_spec, ModuleSpecList &matching_list) const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
bool exact_arch_match = true;
const size_t initial_match_count = matching_list.GetSize();
- for (auto spec: m_specs)
+ for (auto spec : m_specs)
{
if (spec.Matches(module_spec, exact_arch_match))
- matching_list.Append (spec);
+ matching_list.Append(spec);
}
-
+
// If there was an architecture, retry with a compatible arch if no matches were found
if (module_spec.GetArchitecturePtr() && (initial_match_count == matching_list.GetSize()))
{
exact_arch_match = false;
- for (auto spec: m_specs)
+ for (auto spec : m_specs)
{
if (spec.Matches(module_spec, exact_arch_match))
- matching_list.Append (spec);
+ matching_list.Append(spec);
}
}
return matching_list.GetSize() - initial_match_count;
}
void
- Dump (Stream &strm)
+ Dump(Stream &strm)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t idx = 0;
- for (auto spec: m_specs)
+ for (auto spec : m_specs)
{
strm.Printf("[%u] ", idx);
- spec.Dump (strm);
+ spec.Dump(strm);
strm.EOL();
++idx;
}
@@ -599,7 +593,7 @@ public:
protected:
typedef std::vector<ModuleSpec> collection; ///< The module collection type.
collection m_specs; ///< The collection of modules.
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
};
} // namespace lldb_private
diff --git a/include/lldb/Core/RangeMap.h b/include/lldb/Core/RangeMap.h
index 28d3083979d6..eb68859aed3f 100644
--- a/include/lldb/Core/RangeMap.h
+++ b/include/lldb/Core/RangeMap.h
@@ -202,7 +202,13 @@ namespace lldb_private {
{
m_entries.push_back (entry);
}
-
+
+ void
+ Append (B base, S size)
+ {
+ m_entries.emplace_back(base, size);
+ }
+
bool
RemoveEntrtAtIndex (uint32_t idx)
{
@@ -471,7 +477,13 @@ namespace lldb_private {
{
m_entries.push_back (entry);
}
-
+
+ void
+ Append (B base, S size)
+ {
+ m_entries.emplace_back(base, size);
+ }
+
bool
RemoveEntrtAtIndex (uint32_t idx)
{
@@ -1123,7 +1135,7 @@ namespace lldb_private {
// Calculate the byte size of ranges with zero byte sizes by finding
// the next entry with a base address > the current base address
void
- CalculateSizesOfZeroByteSizeRanges ()
+ CalculateSizesOfZeroByteSizeRanges (S full_size = 0)
{
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert (IsSorted());
@@ -1148,6 +1160,8 @@ namespace lldb_private {
break;
}
}
+ if (next == end && full_size > curr_base)
+ pos->SetByteSize (full_size - curr_base);
}
}
}
@@ -1181,7 +1195,13 @@ namespace lldb_private {
{
return ((i < m_entries.size()) ? &m_entries[i] : nullptr);
}
-
+
+ Entry *
+ GetMutableEntryAtIndex (size_t i)
+ {
+ return ((i < m_entries.size()) ? &m_entries[i] : nullptr);
+ }
+
// Clients must ensure that "i" is a valid index prior to calling this function
const Entry &
GetEntryRef (size_t i) const
@@ -1305,6 +1325,42 @@ namespace lldb_private {
return nullptr;
}
+ const Entry*
+ FindEntryStartsAt (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (!m_entries.empty())
+ {
+ auto begin = m_entries.begin(), end = m_entries.end();
+ auto pos = std::lower_bound (begin, end, Entry(addr, 1), BaseLessThan);
+ if (pos != end && pos->base == addr)
+ return &(*pos);
+ }
+ return nullptr;
+ }
+
+ const Entry *
+ FindEntryThatContainsOrFollows(B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert(IsSorted());
+#endif
+ if (!m_entries.empty())
+ {
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos =
+ std::lower_bound(m_entries.begin(), end, addr, [](const Entry &lhs, B rhs_base) -> bool {
+ return lhs.GetRangeEnd() <= rhs_base;
+ });
+
+ if (pos != end)
+ return &(*pos);
+ }
+ return nullptr;
+ }
+
Entry *
Back()
{
diff --git a/include/lldb/Core/RegisterValue.h b/include/lldb/Core/RegisterValue.h
index 030b849212c4..0626b5f2c857 100644
--- a/include/lldb/Core/RegisterValue.h
+++ b/include/lldb/Core/RegisterValue.h
@@ -354,9 +354,6 @@ namespace lldb_private {
lldb::Format format,
uint32_t reg_name_right_align_at = 0) const;
- void *
- GetBytes ();
-
const void *
GetBytes () const;
diff --git a/include/lldb/Core/Scalar.h b/include/lldb/Core/Scalar.h
index a476cd3bd867..be2176e2b50e 100644
--- a/include/lldb/Core/Scalar.h
+++ b/include/lldb/Core/Scalar.h
@@ -16,6 +16,8 @@
#define NUM_OF_WORDS_INT128 2
#define BITWIDTH_INT128 128
+#define NUM_OF_WORDS_INT256 4
+#define BITWIDTH_INT256 256
namespace lldb_private {
@@ -41,7 +43,9 @@ public:
e_double,
e_long_double,
e_uint128,
- e_sint128
+ e_sint128,
+ e_uint256,
+ e_sint256
};
//------------------------------------------------------------------
@@ -91,6 +95,12 @@ public:
else
m_type = e_uint128;
break;
+ case 256:
+ if(m_integer.isSignedIntN(BITWIDTH_INT256))
+ m_type = e_sint256;
+ else
+ m_type = e_uint256;
+ break;
}
}
Scalar(const Scalar& rhs);
@@ -110,7 +120,7 @@ public:
bool
ClearBit(uint32_t bit);
- void *
+ const void *
GetBytes() const;
size_t
@@ -152,6 +162,9 @@ public:
bool
MakeSigned ();
+ bool
+ MakeUnsigned ();
+
static const char *
GetValueTypeAsCString (Scalar::Type value_type);
@@ -221,9 +234,6 @@ public:
Scalar::Type
GetType() const { return m_type; }
- void
- SetType(const RegisterInfo*);
-
//----------------------------------------------------------------------
// Returns a casted value of the current contained data without
// modifying the current value. FAIL_VALUE will be returned if the type
@@ -232,22 +242,10 @@ public:
int
SInt(int fail_value = 0) const;
- // Return the raw unsigned integer without any casting or conversion
- unsigned int
- RawUInt () const;
-
- // Return the raw unsigned long without any casting or conversion
- unsigned long
- RawULong () const;
-
- // Return the raw unsigned long long without any casting or conversion
- unsigned long long
- RawULongLong () const;
-
unsigned char
UChar(unsigned char fail_value = 0) const;
- char
+ signed char
SChar(char fail_value = 0) const;
unsigned short
@@ -277,6 +275,12 @@ public:
llvm::APInt
UInt128(const llvm::APInt& fail_value) const;
+ llvm::APInt
+ SInt256(llvm::APInt& fail_value) const;
+
+ llvm::APInt
+ UInt256(const llvm::APInt& fail_value) const;
+
float
Float(float fail_value = 0.0f) const;
@@ -286,9 +290,6 @@ public:
long double
LongDouble(long double fail_value = 0.0) const;
- uint64_t
- GetRawBits64 (uint64_t fail_value) const;
-
Error
SetValueFromCString (const char *s, lldb::Encoding encoding, size_t byte_size);
diff --git a/include/lldb/Core/SearchFilter.h b/include/lldb/Core/SearchFilter.h
index 3d5e1fb39b43..5c76fb5aad30 100644
--- a/include/lldb/Core/SearchFilter.h
+++ b/include/lldb/Core/SearchFilter.h
@@ -94,7 +94,6 @@ public:
class SearchFilter
{
public:
-
//------------------------------------------------------------------
/// The basic constructor takes a Target, which gives the space to search.
///
@@ -108,7 +107,7 @@ public:
virtual
~SearchFilter ();
- const SearchFilter&
+ SearchFilter&
operator=(const SearchFilter& rhs);
//------------------------------------------------------------------
@@ -294,7 +293,6 @@ class SearchFilterByModule :
public SearchFilter
{
public:
-
//------------------------------------------------------------------
/// The basic constructor takes a Target, which gives the space to search,
/// and the module to restrict the search to.
@@ -312,7 +310,7 @@ public:
~SearchFilterByModule() override;
- const SearchFilterByModule&
+ SearchFilterByModule&
operator=(const SearchFilterByModule& rhs);
bool
@@ -354,7 +352,6 @@ class SearchFilterByModuleList :
public SearchFilter
{
public:
-
//------------------------------------------------------------------
/// The basic constructor takes a Target, which gives the space to search,
/// and the module list to restrict the search to.
@@ -372,7 +369,7 @@ public:
~SearchFilterByModuleList() override;
- const SearchFilterByModuleList&
+ SearchFilterByModuleList&
operator=(const SearchFilterByModuleList& rhs);
bool
@@ -414,7 +411,6 @@ class SearchFilterByModuleListAndCU :
public SearchFilterByModuleList
{
public:
-
//------------------------------------------------------------------
/// The basic constructor takes a Target, which gives the space to search,
/// and the module list to restrict the search to.
@@ -433,7 +429,7 @@ public:
~SearchFilterByModuleListAndCU() override;
- const SearchFilterByModuleListAndCU&
+ SearchFilterByModuleListAndCU&
operator=(const SearchFilterByModuleListAndCU& rhs);
bool
diff --git a/include/lldb/Core/Section.h b/include/lldb/Core/Section.h
index 8c92f1ba667e..0837e326f97b 100644
--- a/include/lldb/Core/Section.h
+++ b/include/lldb/Core/Section.h
@@ -273,7 +273,19 @@ public:
{
m_thread_specific = b;
}
-
+
+ //------------------------------------------------------------------
+ /// Get the permissions as OR'ed bits from lldb::Permissions
+ //------------------------------------------------------------------
+ uint32_t
+ GetPermissions() const;
+
+ //------------------------------------------------------------------
+ /// Set the permissions using bits OR'ed from lldb::Permissions
+ //------------------------------------------------------------------
+ void
+ SetPermissions(uint32_t permissions);
+
ObjectFile *
GetObjectFile ()
{
@@ -356,12 +368,15 @@ protected:
lldb::offset_t m_file_size; // Object file size (can be smaller than m_byte_size for zero filled sections...)
uint32_t m_log2align; // log_2(align) of the section (i.e. section has to be aligned to 2^m_log2align)
SectionList m_children; // Child sections
- bool m_fake:1, // If true, then this section only can contain the address if one of its
+ bool m_fake : 1, // If true, then this section only can contain the address if one of its
// children contains an address. This allows for gaps between the children
// that are contained in the address range for this section, but do not produce
// hits unless the children contain the address.
- m_encrypted:1, // Set to true if the contents are encrypted
- m_thread_specific:1;// This section is thread specific
+ m_encrypted : 1, // Set to true if the contents are encrypted
+ m_thread_specific : 1, // This section is thread specific
+ m_readable : 1, // If this section has read permissions
+ m_writable : 1, // If this section has write permissions
+ m_executable : 1; // If this section has executable permissions
uint32_t m_target_byte_size; // Some architectures have non-8-bit byte size. This is specified as
// as a multiple number of a host bytes
private:
diff --git a/include/lldb/Core/StreamCallback.h b/include/lldb/Core/StreamCallback.h
index e5a9da7512bb..9e91eb94a74c 100644
--- a/include/lldb/Core/StreamCallback.h
+++ b/include/lldb/Core/StreamCallback.h
@@ -10,11 +10,11 @@
#ifndef liblldb_StreamCallback_h_
#define liblldb_StreamCallback_h_
+#include <mutex>
#include <string>
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -37,8 +37,8 @@ private:
lldb::LogOutputCallback m_callback;
void *m_baton;
collection m_accumulated_data;
- Mutex m_collection_mutex;
-
+ std::mutex m_collection_mutex;
+
StreamString &FindStreamForThread(lldb::tid_t cur_tid);
};
diff --git a/include/lldb/Core/StreamTee.h b/include/lldb/Core/StreamTee.h
index 7ab619b3bb79..6059e0e1f8e9 100644
--- a/include/lldb/Core/StreamTee.h
+++ b/include/lldb/Core/StreamTee.h
@@ -12,50 +12,37 @@
#include <limits.h>
+#include <mutex>
+
#include "lldb/Core/Stream.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
class StreamTee : public Stream
{
public:
- StreamTee () :
- Stream (),
- m_streams_mutex (Mutex::eMutexTypeRecursive),
- m_streams ()
- {
- }
+ StreamTee() : Stream(), m_streams_mutex(), m_streams() {}
- StreamTee (lldb::StreamSP &stream_sp):
- Stream (),
- m_streams_mutex (Mutex::eMutexTypeRecursive),
- m_streams ()
+ StreamTee(lldb::StreamSP &stream_sp) : Stream(), m_streams_mutex(), m_streams()
{
// No need to lock mutex during construction
if (stream_sp)
- m_streams.push_back (stream_sp);
+ m_streams.push_back(stream_sp);
}
-
- StreamTee (lldb::StreamSP &stream_sp, lldb::StreamSP &stream_2_sp) :
- Stream (),
- m_streams_mutex (Mutex::eMutexTypeRecursive),
- m_streams ()
+ StreamTee(lldb::StreamSP &stream_sp, lldb::StreamSP &stream_2_sp) : Stream(), m_streams_mutex(), m_streams()
{
// No need to lock mutex during construction
if (stream_sp)
- m_streams.push_back (stream_sp);
+ m_streams.push_back(stream_sp);
if (stream_2_sp)
- m_streams.push_back (stream_2_sp);
+ m_streams.push_back(stream_2_sp);
}
-
- StreamTee (const StreamTee &rhs) :
- Stream (rhs),
- m_streams_mutex (Mutex::eMutexTypeRecursive),
- m_streams() // Don't copy until we lock down "rhs"
+
+ StreamTee(const StreamTee &rhs) : Stream(rhs), m_streams_mutex(), m_streams()
{
- Mutex::Locker locker (rhs.m_streams_mutex);
+ // Don't copy until we lock down "rhs"
+ std::lock_guard<std::recursive_mutex> guard(rhs.m_streams_mutex);
m_streams = rhs.m_streams;
}
@@ -64,21 +51,22 @@ public:
}
StreamTee &
- operator = (const StreamTee &rhs)
+ operator=(const StreamTee &rhs)
{
- if (this != &rhs) {
+ if (this != &rhs)
+ {
Stream::operator=(rhs);
- Mutex::Locker lhs_locker (m_streams_mutex);
- Mutex::Locker rhs_locker (rhs.m_streams_mutex);
- m_streams = rhs.m_streams;
+ std::lock_guard<std::recursive_mutex> lhs_locker(m_streams_mutex);
+ std::lock_guard<std::recursive_mutex> rhs_locker(rhs.m_streams_mutex);
+ m_streams = rhs.m_streams;
}
return *this;
}
void
- Flush () override
+ Flush() override
{
- Mutex::Locker locker (m_streams_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_streams_mutex);
collection::iterator pos, end;
for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos)
{
@@ -88,17 +76,17 @@ public:
// to valid values.
Stream *strm = pos->get();
if (strm)
- strm->Flush ();
+ strm->Flush();
}
}
size_t
- Write (const void *s, size_t length) override
+ Write(const void *s, size_t length) override
{
- Mutex::Locker locker (m_streams_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_streams_mutex);
if (m_streams.empty())
return 0;
-
+
size_t min_bytes_written = SIZE_MAX;
collection::iterator pos, end;
for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos)
@@ -110,7 +98,7 @@ public:
Stream *strm = pos->get();
if (strm)
{
- const size_t bytes_written = strm->Write (s, length);
+ const size_t bytes_written = strm->Write(s, length);
if (min_bytes_written > bytes_written)
min_bytes_written = bytes_written;
}
@@ -121,39 +109,39 @@ public:
}
size_t
- AppendStream (const lldb::StreamSP &stream_sp)
+ AppendStream(const lldb::StreamSP &stream_sp)
{
size_t new_idx = m_streams.size();
- Mutex::Locker locker (m_streams_mutex);
- m_streams.push_back (stream_sp);
+ std::lock_guard<std::recursive_mutex> guard(m_streams_mutex);
+ m_streams.push_back(stream_sp);
return new_idx;
}
size_t
- GetNumStreams () const
+ GetNumStreams() const
{
size_t result = 0;
{
- Mutex::Locker locker (m_streams_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_streams_mutex);
result = m_streams.size();
}
return result;
}
lldb::StreamSP
- GetStreamAtIndex (uint32_t idx)
+ GetStreamAtIndex(uint32_t idx)
{
lldb::StreamSP stream_sp;
- Mutex::Locker locker (m_streams_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_streams_mutex);
if (idx < m_streams.size())
stream_sp = m_streams[idx];
return stream_sp;
}
void
- SetStreamAtIndex (uint32_t idx, const lldb::StreamSP& stream_sp)
+ SetStreamAtIndex(uint32_t idx, const lldb::StreamSP &stream_sp)
{
- Mutex::Locker locker (m_streams_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_streams_mutex);
// Resize our stream vector as necessary to fit as many streams
// as needed. This also allows this class to be used with hard
// coded indexes that can be used contain many streams, not all
@@ -162,10 +150,10 @@ public:
m_streams.resize(idx + 1);
m_streams[idx] = stream_sp;
}
-
+
protected:
typedef std::vector<lldb::StreamSP> collection;
- mutable Mutex m_streams_mutex;
+ mutable std::recursive_mutex m_streams_mutex;
collection m_streams;
};
diff --git a/include/lldb/Core/ThreadSafeSTLMap.h b/include/lldb/Core/ThreadSafeSTLMap.h
index 4235edc92ade..4a885ff1a480 100644
--- a/include/lldb/Core/ThreadSafeSTLMap.h
+++ b/include/lldb/Core/ThreadSafeSTLMap.h
@@ -13,11 +13,11 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-defines.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -31,11 +31,7 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- ThreadSafeSTLMap() :
- m_collection (),
- m_mutex (Mutex::eMutexTypeRecursive)
- {
- }
+ ThreadSafeSTLMap() : m_collection(), m_mutex() {}
~ThreadSafeSTLMap()
{
@@ -44,22 +40,22 @@ public:
bool
IsEmpty() const
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_collection.empty();
}
-
+
void
Clear()
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_collection.clear();
}
size_t
- Erase (const _Key& key)
+ Erase(const _Key &key)
{
- Mutex::Locker locker(m_mutex);
- return EraseNoLock (key);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return EraseNoLock(key);
}
size_t
@@ -69,10 +65,10 @@ public:
}
bool
- GetValueForKey (const _Key& key, _Tp &value) const
+ GetValueForKey(const _Key &key, _Tp &value) const
{
- Mutex::Locker locker(m_mutex);
- return GetValueForKeyNoLock (key, value);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return GetValueForKeyNoLock(key, value);
}
// Call this if you have already manually locked the mutex using the
@@ -90,10 +86,10 @@ public:
}
bool
- GetFirstKeyForValue (const _Tp &value, _Key& key) const
+ GetFirstKeyForValue(const _Tp &value, _Key &key) const
{
- Mutex::Locker locker(m_mutex);
- return GetFirstKeyForValueNoLock (value, key);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return GetFirstKeyForValueNoLock(value, key);
}
bool
@@ -112,13 +108,10 @@ public:
}
bool
- LowerBound (const _Key& key,
- _Key& match_key,
- _Tp &match_value,
- bool decrement_if_not_equal) const
+ LowerBound(const _Key &key, _Key &match_key, _Tp &match_value, bool decrement_if_not_equal) const
{
- Mutex::Locker locker(m_mutex);
- return LowerBoundNoLock (key, match_key, match_value, decrement_if_not_equal);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return LowerBoundNoLock(key, match_key, match_value, decrement_if_not_equal);
}
bool
@@ -149,10 +142,10 @@ public:
}
void
- SetValueForKey (const _Key& key, const _Tp &value)
+ SetValueForKey(const _Key &key, const _Tp &value)
{
- Mutex::Locker locker(m_mutex);
- SetValueForKeyNoLock (key, value);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ SetValueForKeyNoLock(key, value);
}
// Call this if you have already manually locked the mutex using the
@@ -163,15 +156,15 @@ public:
m_collection[key] = value;
}
- Mutex &
- GetMutex ()
+ std::recursive_mutex &
+ GetMutex()
{
return m_mutex;
}
private:
collection m_collection;
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
//------------------------------------------------------------------
// For ThreadSafeSTLMap only
diff --git a/include/lldb/Core/ThreadSafeSTLVector.h b/include/lldb/Core/ThreadSafeSTLVector.h
new file mode 100644
index 000000000000..dd90d49afcb8
--- /dev/null
+++ b/include/lldb/Core/ThreadSafeSTLVector.h
@@ -0,0 +1,99 @@
+//===-- ThreadSafeSTLVector.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_ThreadSafeSTLVector_h_
+#define liblldb_ThreadSafeSTLVector_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+#include <mutex>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-defines.h"
+
+namespace lldb_private {
+
+ template <typename _Object>
+ class ThreadSafeSTLVector
+ {
+ public:
+ typedef std::vector<_Object> collection;
+ typedef typename collection::iterator iterator;
+ typedef typename collection::const_iterator const_iterator;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ThreadSafeSTLVector() : m_collection(), m_mutex() {}
+
+ ~ThreadSafeSTLVector() = default;
+
+ bool
+ IsEmpty() const
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_collection.empty();
+ }
+
+ void
+ Clear()
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_collection.clear();
+ }
+
+ size_t
+ GetCount()
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_collection.size();
+ }
+
+ void
+ AppendObject (_Object& object)
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_collection.push_back(object);
+ }
+
+ _Object
+ GetObject (size_t index)
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_collection.at(index);
+ }
+
+ void
+ SetObject (size_t index, const _Object& object)
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_collection.at(index) = object;
+ }
+
+ std::recursive_mutex &
+ GetMutex()
+ {
+ return m_mutex;
+ }
+
+ private:
+ collection m_collection;
+ mutable std::recursive_mutex m_mutex;
+
+ //------------------------------------------------------------------
+ // For ThreadSafeSTLVector only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (ThreadSafeSTLVector);
+ };
+
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadSafeSTLVector_h_
diff --git a/include/lldb/Core/ThreadSafeValue.h b/include/lldb/Core/ThreadSafeValue.h
index 42a5a5c6725a..cad36a0c1637 100644
--- a/include/lldb/Core/ThreadSafeValue.h
+++ b/include/lldb/Core/ThreadSafeValue.h
@@ -11,10 +11,12 @@
#define liblldb_ThreadSafeValue_h_
// C Includes
+
// C++ Includes
+#include <mutex>
+
// Other libraries and framework includes
// Project includes
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -25,28 +27,20 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- ThreadSafeValue() :
- m_value (),
- m_mutex (Mutex::eMutexTypeRecursive)
- {
- }
+ ThreadSafeValue() : m_value(), m_mutex() {}
- ThreadSafeValue(const T& value) :
- m_value (value),
- m_mutex (Mutex::eMutexTypeRecursive)
- {
- }
+ ThreadSafeValue(const T &value) : m_value(value), m_mutex() {}
~ThreadSafeValue()
{
}
T
- GetValue () const
+ GetValue() const
{
T value;
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
value = m_value;
}
return value;
@@ -61,9 +55,9 @@ public:
}
void
- SetValue (const T& value)
+ SetValue(const T &value)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_value = value;
}
@@ -75,15 +69,15 @@ public:
m_value = value;
}
- Mutex &
- GetMutex ()
+ std::recursive_mutex &
+ GetMutex()
{
return m_mutex;
}
private:
T m_value;
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
//------------------------------------------------------------------
// For ThreadSafeValue only
diff --git a/include/lldb/Core/Timer.h b/include/lldb/Core/Timer.h
index ffaeba6fce9b..4d89700644cc 100644
--- a/include/lldb/Core/Timer.h
+++ b/include/lldb/Core/Timer.h
@@ -50,9 +50,6 @@ public:
//--------------------------------------------------------------
~Timer();
- static void
- Initialize ();
-
void
Dump ();
@@ -89,8 +86,6 @@ protected:
static std::atomic<bool> g_quiet;
static std::atomic<unsigned> g_display_depth;
- static std::mutex g_file_mutex;
- static FILE* g_file;
private:
Timer();
diff --git a/include/lldb/Core/UserSettingsController.h b/include/lldb/Core/UserSettingsController.h
index 7e72b89ad8e6..6c395c81c37b 100644
--- a/include/lldb/Core/UserSettingsController.h
+++ b/include/lldb/Core/UserSettingsController.h
@@ -24,7 +24,6 @@
#include "lldb/Core/StringList.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Interpreter/OptionValue.h"
namespace lldb_private {
@@ -89,6 +88,20 @@ public:
lldb::OptionValuePropertiesSP
GetSubProperty (const ExecutionContext *exe_ctx,
const ConstString &name);
+
+ // We sometimes need to introduce a setting to enable experimental features,
+ // but then we don't want the setting for these to cause errors when the setting
+ // goes away. Add a sub-topic of the settings using this experimental name, and
+ // two things will happen. One is that settings that don't find the name will not
+ // be treated as errors. Also, if you decide to keep the settings just move them into
+ // the containing properties, and we will auto-forward the experimental settings to the
+ // real one.
+ static const char *
+ GetExperimentalSettingsName();
+
+ static bool
+ IsSettingExperimental(const char *setting);
+
protected:
lldb::OptionValuePropertiesSP m_collection_sp;
};
diff --git a/include/lldb/Core/Value.h b/include/lldb/Core/Value.h
index a6d934afd294..7539b550dc42 100644
--- a/include/lldb/Core/Value.h
+++ b/include/lldb/Core/Value.h
@@ -169,9 +169,8 @@ public:
m_context = p;
if (m_context_type == eContextTypeRegisterInfo) {
RegisterInfo *reg_info = GetRegisterInfo();
- if (reg_info->encoding == lldb::eEncodingVector)
- SetValueType(eValueTypeVector);
- else
+ if (reg_info->encoding == lldb::eEncodingVector &&
+ m_vector.byte_order != lldb::eByteOrderInvalid)
SetValueType(eValueTypeScalar);
}
}
diff --git a/include/lldb/Core/ValueObject.h b/include/lldb/Core/ValueObject.h
index c066cc7d3661..bef158feb39d 100644
--- a/include/lldb/Core/ValueObject.h
+++ b/include/lldb/Core/ValueObject.h
@@ -699,10 +699,16 @@ public:
GetSyntheticExpressionPathChild(const char* expression, bool can_create);
virtual lldb::ValueObjectSP
- GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create);
+ GetSyntheticChildAtOffset(uint32_t offset,
+ const CompilerType& type,
+ bool can_create,
+ ConstString name_const_str = ConstString());
virtual lldb::ValueObjectSP
- GetSyntheticBase (uint32_t offset, const CompilerType& type, bool can_create);
+ GetSyntheticBase (uint32_t offset,
+ const CompilerType& type,
+ bool can_create,
+ ConstString name_const_str = ConstString());
virtual lldb::ValueObjectSP
GetDynamicValue (lldb::DynamicValueType valueType);
@@ -787,10 +793,10 @@ public:
return false;
}
- bool
+ virtual bool
IsSyntheticChildrenGenerated ();
- void
+ virtual void
SetSyntheticChildrenGenerated (bool b);
virtual SymbolContextScope *
@@ -1028,35 +1034,32 @@ protected:
class ChildrenManager
{
public:
- ChildrenManager() :
- m_mutex(Mutex::eMutexTypeRecursive),
- m_children(),
- m_children_count(0)
- {}
-
+ ChildrenManager() : m_mutex(), m_children(), m_children_count(0) {}
+
bool
- HasChildAtIndex (size_t idx)
+ HasChildAtIndex(size_t idx)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return (m_children.find(idx) != m_children.end());
}
-
- ValueObject*
- GetChildAtIndex (size_t idx)
+
+ ValueObject *
+ GetChildAtIndex(size_t idx)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const auto iter = m_children.find(idx);
return ((iter == m_children.end()) ? nullptr : iter->second);
}
-
+
void
- SetChildAtIndex (size_t idx, ValueObject* valobj)
+ SetChildAtIndex(size_t idx, ValueObject *valobj)
{
- ChildrenPair pair(idx,valobj); // we do not need to be mutex-protected to make a pair
- Mutex::Locker locker(m_mutex);
+ // we do not need to be mutex-protected to make a pair
+ ChildrenPair pair(idx, valobj);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_children.insert(pair);
}
-
+
void
SetChildrenCount (size_t count)
{
@@ -1068,20 +1071,20 @@ protected:
{
return m_children_count;
}
-
+
void
Clear(size_t new_count = 0)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_children_count = new_count;
m_children.clear();
}
-
+
private:
typedef std::map<size_t, ValueObject*> ChildrenMap;
typedef ChildrenMap::iterator ChildrenIterator;
typedef ChildrenMap::value_type ChildrenPair;
- Mutex m_mutex;
+ std::recursive_mutex m_mutex;
ChildrenMap m_children;
size_t m_children_count;
};
diff --git a/include/lldb/Core/ValueObjectConstResult.h b/include/lldb/Core/ValueObjectConstResult.h
index f63ee83284df..892df8c62cc5 100644
--- a/include/lldb/Core/ValueObjectConstResult.h
+++ b/include/lldb/Core/ValueObjectConstResult.h
@@ -97,7 +97,10 @@ public:
CreateChildAtIndex(size_t idx, bool synthetic_array_member, int32_t synthetic_index) override;
lldb::ValueObjectSP
- GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create) override;
+ GetSyntheticChildAtOffset(uint32_t offset,
+ const CompilerType& type,
+ bool can_create,
+ ConstString name_const_str = ConstString()) override;
lldb::ValueObjectSP
AddressOf(Error &error) override;
diff --git a/include/lldb/Core/ValueObjectConstResultCast.h b/include/lldb/Core/ValueObjectConstResultCast.h
index 395820dad6c7..84dd79213d02 100644
--- a/include/lldb/Core/ValueObjectConstResultCast.h
+++ b/include/lldb/Core/ValueObjectConstResultCast.h
@@ -47,7 +47,8 @@ public:
lldb::ValueObjectSP
GetSyntheticChildAtOffset(uint32_t offset,
const CompilerType& type,
- bool can_create) override;
+ bool can_create,
+ ConstString name_const_str = ConstString()) override;
lldb::ValueObjectSP
AddressOf (Error &error) override;
diff --git a/include/lldb/Core/ValueObjectConstResultChild.h b/include/lldb/Core/ValueObjectConstResultChild.h
index 356d175a64ae..e4a238a96c8f 100644
--- a/include/lldb/Core/ValueObjectConstResultChild.h
+++ b/include/lldb/Core/ValueObjectConstResultChild.h
@@ -53,7 +53,10 @@ public:
}
lldb::ValueObjectSP
- GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create) override;
+ GetSyntheticChildAtOffset(uint32_t offset,
+ const CompilerType& type,
+ bool can_create,
+ ConstString name_const_str = ConstString()) override;
lldb::ValueObjectSP
AddressOf (Error &error) override;
diff --git a/include/lldb/Core/ValueObjectConstResultImpl.h b/include/lldb/Core/ValueObjectConstResultImpl.h
index 36b82f00a240..848a221c3d05 100644
--- a/include/lldb/Core/ValueObjectConstResultImpl.h
+++ b/include/lldb/Core/ValueObjectConstResultImpl.h
@@ -39,7 +39,10 @@ public:
CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
lldb::ValueObjectSP
- GetSyntheticChildAtOffset (uint32_t offset, const CompilerType& type, bool can_create);
+ GetSyntheticChildAtOffset (uint32_t offset,
+ const CompilerType& type,
+ bool can_create,
+ ConstString name_const_str = ConstString());
lldb::ValueObjectSP
AddressOf (Error &error);
diff --git a/include/lldb/Core/ValueObjectDynamicValue.h b/include/lldb/Core/ValueObjectDynamicValue.h
index 80f37f104765..8a045c3b0db1 100644
--- a/include/lldb/Core/ValueObjectDynamicValue.h
+++ b/include/lldb/Core/ValueObjectDynamicValue.h
@@ -117,6 +117,12 @@ public:
void
SetPreferredDisplayLanguage (lldb::LanguageType);
+
+ bool
+ IsSyntheticChildrenGenerated () override;
+
+ void
+ SetSyntheticChildrenGenerated (bool b) override;
bool
GetDeclaration(Declaration &decl) override;
diff --git a/include/lldb/Core/ValueObjectSyntheticFilter.h b/include/lldb/Core/ValueObjectSyntheticFilter.h
index 05bc3781a3cc..38d9f7b5ade1 100644
--- a/include/lldb/Core/ValueObjectSyntheticFilter.h
+++ b/include/lldb/Core/ValueObjectSyntheticFilter.h
@@ -17,6 +17,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ThreadSafeSTLMap.h"
+#include "lldb/Core/ThreadSafeSTLVector.h"
#include "lldb/Core/ValueObject.h"
namespace lldb_private {
@@ -147,6 +148,12 @@ public:
SetPreferredDisplayLanguage (lldb::LanguageType);
bool
+ IsSyntheticChildrenGenerated () override;
+
+ void
+ SetSyntheticChildrenGenerated (bool b) override;
+
+ bool
GetDeclaration(Declaration &decl) override;
uint64_t
@@ -177,6 +184,7 @@ protected:
typedef ThreadSafeSTLMap<uint32_t, ValueObject*> ByIndexMap;
typedef ThreadSafeSTLMap<const char*, uint32_t> NameToIndexMap;
+ typedef ThreadSafeSTLVector<lldb::ValueObjectSP> SyntheticChildrenCache;
typedef ByIndexMap::iterator ByIndexIterator;
typedef NameToIndexMap::iterator NameToIndexIterator;
@@ -184,6 +192,7 @@ protected:
ByIndexMap m_children_byindex;
NameToIndexMap m_name_toindex;
uint32_t m_synthetic_children_count; // FIXME use the ValueObject's ChildrenManager instead of a special purpose solution
+ SyntheticChildrenCache m_synthetic_children_cache;
ConstString m_parent_type_name;
diff --git a/include/lldb/DataFormatters/DumpValueObjectOptions.h b/include/lldb/DataFormatters/DumpValueObjectOptions.h
index f65ee7b95845..e90bd1bcadcd 100644
--- a/include/lldb/DataFormatters/DumpValueObjectOptions.h
+++ b/include/lldb/DataFormatters/DumpValueObjectOptions.h
@@ -152,6 +152,9 @@ public:
DumpValueObjectOptions&
SetRevealEmptyAggregates (bool reveal = true);
+
+ DumpValueObjectOptions&
+ SetElementCount (uint32_t element_count = 0);
public:
uint32_t m_max_depth = UINT32_MAX;
@@ -163,6 +166,7 @@ public:
lldb::LanguageType m_varformat_language = lldb::eLanguageTypeUnknown;
PointerDepth m_max_ptr_depth;
DeclPrintingHelper m_decl_printing_helper;
+ uint32_t m_element_count = 0;
bool m_use_synthetic : 1;
bool m_scope_already_checked : 1;
bool m_flat_output : 1;
diff --git a/include/lldb/DataFormatters/FormatCache.h b/include/lldb/DataFormatters/FormatCache.h
index 9f1e078f7199..645fbc7ddf10 100644
--- a/include/lldb/DataFormatters/FormatCache.h
+++ b/include/lldb/DataFormatters/FormatCache.h
@@ -13,12 +13,12 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/ConstString.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
class FormatCache
@@ -82,8 +82,8 @@ private:
};
typedef std::map<ConstString,Entry> CacheMap;
CacheMap m_map;
- Mutex m_mutex;
-
+ std::recursive_mutex m_mutex;
+
uint64_t m_cache_hits;
uint64_t m_cache_misses;
diff --git a/include/lldb/DataFormatters/FormatManager.h b/include/lldb/DataFormatters/FormatManager.h
index 24ba5a7f0aa5..27dc31d259d0 100644
--- a/include/lldb/DataFormatters/FormatManager.h
+++ b/include/lldb/DataFormatters/FormatManager.h
@@ -15,6 +15,7 @@
#include <atomic>
#include <initializer_list>
#include <map>
+#include <mutex>
#include <vector>
// Other libraries and framework includes
@@ -289,7 +290,7 @@ private:
std::atomic<uint32_t> m_last_revision;
FormatCache m_format_cache;
- Mutex m_language_categories_mutex;
+ std::recursive_mutex m_language_categories_mutex;
LanguageCategories m_language_categories_map;
NamedSummariesMap m_named_summaries_map;
TypeCategoryMap m_categories_map;
diff --git a/include/lldb/DataFormatters/FormattersContainer.h b/include/lldb/DataFormatters/FormattersContainer.h
index dcd08211f19b..c4694463b676 100644
--- a/include/lldb/DataFormatters/FormattersContainer.h
+++ b/include/lldb/DataFormatters/FormattersContainer.h
@@ -15,6 +15,7 @@
#include <functional>
#include <map>
#include <memory>
+#include <mutex>
#include <string>
// Other libraries and framework includes
@@ -81,33 +82,27 @@ public:
typedef std::map<KeyType, ValueSP> MapType;
typedef typename MapType::iterator MapIterator;
typedef std::function<bool(KeyType, const ValueSP&)> ForEachCallback;
-
- FormatMap(IFormatChangeListener* lst) :
- m_map(),
- m_map_mutex(Mutex::eMutexTypeRecursive),
- listener(lst)
- {
- }
-
+
+ FormatMap(IFormatChangeListener *lst) : m_map(), m_map_mutex(), listener(lst) {}
+
void
- Add(KeyType name,
- const ValueSP& entry)
+ Add(KeyType name, const ValueSP &entry)
{
if (listener)
entry->GetRevision() = listener->GetCurrentRevision();
else
entry->GetRevision() = 0;
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
m_map[name] = entry;
if (listener)
listener->Changed();
}
-
+
bool
- Delete (KeyType name)
+ 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;
@@ -116,34 +111,33 @@ public:
listener->Changed();
return true;
}
-
+
void
- Clear ()
+ Clear()
{
- Mutex::Locker locker(m_map_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
m_map.clear();
if (listener)
listener->Changed();
}
-
+
bool
- Get(KeyType name,
- ValueSP& entry)
+ 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;
entry = iter->second;
return true;
}
-
+
void
- ForEach (ForEachCallback callback)
+ ForEach(ForEachCallback callback)
{
if (callback)
{
- 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++)
{
@@ -153,17 +147,17 @@ public:
}
}
}
-
+
uint32_t
GetCount ()
{
return m_map.size();
}
-
+
ValueSP
- GetValueAtIndex (size_t index)
+ GetValueAtIndex(size_t index)
{
- 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 (index > 0)
@@ -175,11 +169,11 @@ public:
}
return iter->second;
}
-
+
KeyType
- GetKeyAtIndex (size_t index)
+ GetKeyAtIndex(size_t index)
{
- 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 (index > 0)
@@ -191,24 +185,24 @@ public:
}
return iter->first;
}
-
+
protected:
- MapType m_map;
- Mutex m_map_mutex;
+ MapType m_map;
+ std::recursive_mutex m_map_mutex;
IFormatChangeListener* listener;
-
+
MapType&
map ()
{
return m_map;
}
-
- Mutex&
- mutex ()
+
+ std::recursive_mutex &
+ mutex()
{
return m_map_mutex;
}
-
+
friend class FormattersContainer<KeyType, ValueType>;
friend class FormatManager;
};
@@ -332,24 +326,23 @@ protected:
}
bool
- Delete_Impl (ConstString type, lldb::RegularExpressionSP *dummy)
- {
- Mutex& x_mutex = m_format_map.mutex();
- lldb_private::Mutex::Locker locker(x_mutex);
- MapIterator pos, end = m_format_map.map().end();
- for (pos = m_format_map.map().begin(); pos != end; pos++)
- {
- lldb::RegularExpressionSP regex = pos->first;
- if ( ::strcmp(type.AsCString(),regex->GetText()) == 0)
- {
- m_format_map.map().erase(pos);
- if (m_format_map.listener)
- m_format_map.listener->Changed();
- return true;
- }
- }
- return false;
- }
+ Delete_Impl(ConstString type, lldb::RegularExpressionSP *dummy)
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
+ MapIterator pos, end = m_format_map.map().end();
+ for (pos = m_format_map.map().begin(); pos != end; pos++)
+ {
+ lldb::RegularExpressionSP regex = pos->first;
+ if (::strcmp(type.AsCString(), regex->GetText()) == 0)
+ {
+ m_format_map.map().erase(pos);
+ if (m_format_map.listener)
+ m_format_map.listener->Changed();
+ return true;
+ }
+ }
+ return false;
+ }
bool
Get_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
@@ -385,36 +378,34 @@ protected:
}
bool
- Get_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
- {
- const char* key_cstr = key.AsCString();
- if (!key_cstr)
- return false;
- Mutex& x_mutex = m_format_map.mutex();
- lldb_private::Mutex::Locker locker(x_mutex);
- MapIterator pos, end = m_format_map.map().end();
- for (pos = m_format_map.map().begin(); pos != end; pos++)
- {
- lldb::RegularExpressionSP regex = pos->first;
- if (regex->Execute(key_cstr))
- {
- value = pos->second;
- return true;
- }
- }
- return false;
+ Get_Impl(ConstString key, MapValueType &value, lldb::RegularExpressionSP *dummy)
+ {
+ const char *key_cstr = key.AsCString();
+ if (!key_cstr)
+ return false;
+ std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
+ MapIterator pos, end = m_format_map.map().end();
+ for (pos = m_format_map.map().begin(); pos != end; pos++)
+ {
+ lldb::RegularExpressionSP regex = pos->first;
+ if (regex->Execute(key_cstr))
+ {
+ value = pos->second;
+ return true;
+ }
+ }
+ return false;
}
-
+
bool
- GetExact_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
+ GetExact_Impl(ConstString key, MapValueType &value, lldb::RegularExpressionSP *dummy)
{
- Mutex& x_mutex = m_format_map.mutex();
- lldb_private::Mutex::Locker locker(x_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
MapIterator pos, end = m_format_map.map().end();
for (pos = m_format_map.map().begin(); pos != end; pos++)
{
lldb::RegularExpressionSP regex = pos->first;
- if (strcmp(regex->GetText(),key.AsCString()) == 0)
+ if (strcmp(regex->GetText(), key.AsCString()) == 0)
{
value = pos->second;
return true;
diff --git a/include/lldb/DataFormatters/FormattersHelpers.h b/include/lldb/DataFormatters/FormattersHelpers.h
index 4627a61e94f1..0622230f6797 100644
--- a/include/lldb/DataFormatters/FormattersHelpers.h
+++ b/include/lldb/DataFormatters/FormattersHelpers.h
@@ -75,35 +75,7 @@ namespace lldb_private {
ScriptedSyntheticChildren::Flags flags,
bool regex = false);
#endif
-
- StackFrame*
- GetViableFrame (ExecutionContext exe_ctx);
-
- bool
- ExtractValueFromObjCExpression (ValueObject &valobj,
- const char* target_type,
- const char* selector,
- uint64_t &value);
-
- bool
- ExtractSummaryFromObjCExpression (ValueObject &valobj,
- const char* target_type,
- const char* selector,
- Stream &stream,
- lldb::LanguageType lang_type);
-
- lldb::ValueObjectSP
- CallSelectorOnObject (ValueObject &valobj,
- const char* return_type,
- const char* selector,
- uint64_t index);
-
- lldb::ValueObjectSP
- CallSelectorOnObject (ValueObject &valobj,
- const char* return_type,
- const char* selector,
- const char* key);
-
+
size_t
ExtractIndexFromString (const char* item_name);
diff --git a/include/lldb/DataFormatters/TypeCategory.h b/include/lldb/DataFormatters/TypeCategory.h
index 075d31d1cf6f..c6d7d7b0f878 100644
--- a/include/lldb/DataFormatters/TypeCategory.h
+++ b/include/lldb/DataFormatters/TypeCategory.h
@@ -14,6 +14,7 @@
// C++ Includes
#include <initializer_list>
#include <memory>
+#include <mutex>
#include <string>
#include <vector>
@@ -519,9 +520,9 @@ namespace lldb_private {
bool m_enabled;
IFormatChangeListener* m_change_listener;
-
- Mutex m_mutex;
-
+
+ std::recursive_mutex m_mutex;
+
ConstString m_name;
std::vector<lldb::LanguageType> m_languages;
diff --git a/include/lldb/DataFormatters/TypeCategoryMap.h b/include/lldb/DataFormatters/TypeCategoryMap.h
index 8afeaf87cec5..2cc589809a7c 100644
--- a/include/lldb/DataFormatters/TypeCategoryMap.h
+++ b/include/lldb/DataFormatters/TypeCategoryMap.h
@@ -15,6 +15,7 @@
#include <functional>
#include <list>
#include <map>
+#include <mutex>
// Other libraries and framework includes
// Project includes
@@ -131,8 +132,8 @@ namespace lldb_private {
return ptr.get() == other.get();
}
};
-
- Mutex m_map_mutex;
+
+ std::recursive_mutex m_map_mutex;
IFormatChangeListener* listener;
MapType m_map;
@@ -147,12 +148,13 @@ namespace lldb_private {
{
return m_active_categories;
}
-
- Mutex& mutex ()
+
+ std::recursive_mutex &
+ mutex()
{
return m_map_mutex;
}
-
+
friend class FormattersContainer<KeyType, ValueType>;
friend class FormatManager;
};
diff --git a/include/lldb/DataFormatters/TypeSynthetic.h b/include/lldb/DataFormatters/TypeSynthetic.h
index 90e5730288c4..ceb600aed69a 100644
--- a/include/lldb/DataFormatters/TypeSynthetic.h
+++ b/include/lldb/DataFormatters/TypeSynthetic.h
@@ -91,6 +91,11 @@ namespace lldb_private {
virtual lldb::ValueObjectSP
GetSyntheticValue () { return nullptr; }
+ // if this function returns a non-empty ConstString, then clients are expected to use the return
+ // as the name of the type of this ValueObject for display purposes
+ virtual ConstString
+ GetSyntheticTypeName () { return ConstString(); }
+
typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
@@ -607,6 +612,9 @@ namespace lldb_private {
lldb::ValueObjectSP
GetSyntheticValue() override;
+ ConstString
+ GetSyntheticTypeName () override;
+
typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
private:
diff --git a/include/lldb/DataFormatters/ValueObjectPrinter.h b/include/lldb/DataFormatters/ValueObjectPrinter.h
index 23d7ee2edf50..c7591b019685 100644
--- a/include/lldb/DataFormatters/ValueObjectPrinter.h
+++ b/include/lldb/DataFormatters/ValueObjectPrinter.h
@@ -153,6 +153,10 @@ protected:
void
PrintChildrenPostamble (bool print_dotdotdot);
+ lldb::ValueObjectSP
+ GenerateChild (ValueObject* synth_valobj,
+ size_t idx);
+
void
PrintChild (lldb::ValueObjectSP child_sp,
const DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
diff --git a/include/lldb/DataFormatters/VectorIterator.h b/include/lldb/DataFormatters/VectorIterator.h
index 3d96ee4c093b..0bacd51ca63e 100644
--- a/include/lldb/DataFormatters/VectorIterator.h
+++ b/include/lldb/DataFormatters/VectorIterator.h
@@ -38,9 +38,7 @@ namespace lldb_private {
size_t
GetIndexOfChildWithName(const ConstString &name) override;
-
- ~VectorIteratorSyntheticFrontEnd() override;
-
+
private:
ExecutionContextRef m_exe_ctx_ref;
ConstString m_item_name;
diff --git a/include/lldb/Expression/DWARFExpression.h b/include/lldb/Expression/DWARFExpression.h
index 3527c3b4b153..d984a419c5c9 100644
--- a/include/lldb/Expression/DWARFExpression.h
+++ b/include/lldb/Expression/DWARFExpression.h
@@ -10,11 +10,12 @@
#ifndef liblldb_DWARFExpression_h_
#define liblldb_DWARFExpression_h_
-#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/lldb-private.h"
+#include <functional>
class DWARFCompileUnit;
@@ -166,7 +167,14 @@ public:
bool
Update_DW_OP_addr (lldb::addr_t file_addr);
-
+
+ bool
+ ContainsThreadLocalStorage() const;
+
+ bool
+ LinkThreadLocalStorage(lldb::ModuleSP new_module_sp,
+ std::function<lldb::addr_t(lldb::addr_t file_addr)> const &link_address_callback);
+
//------------------------------------------------------------------
/// Make the expression parser read its location information from a
/// given data source. Does not change the offset and length
@@ -282,6 +290,7 @@ public:
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;
@@ -296,6 +305,7 @@ public:
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;
@@ -370,6 +380,7 @@ public:
const lldb::offset_t length,
const lldb::RegisterKind reg_set,
const Value* initial_value_ptr,
+ const Value* object_address_ptr,
Value& result,
Error *error_ptr);
diff --git a/include/lldb/Expression/DiagnosticManager.h b/include/lldb/Expression/DiagnosticManager.h
new file mode 100644
index 000000000000..c294bdecf2b2
--- /dev/null
+++ b/include/lldb/Expression/DiagnosticManager.h
@@ -0,0 +1,212 @@
+//===-- DiagnosticManager.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_DiagnosticManager_h
+#define lldb_DiagnosticManager_h
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-types.h"
+
+#include <string>
+#include <vector>
+
+namespace lldb_private
+{
+
+enum DiagnosticOrigin
+{
+ eDiagnosticOriginUnknown = 0,
+ eDiagnosticOriginLLDB,
+ eDiagnosticOriginClang,
+ eDiagnosticOriginGo,
+ eDiagnosticOriginSwift,
+ eDiagnosticOriginLLVM
+};
+
+enum DiagnosticSeverity
+{
+ eDiagnosticSeverityError,
+ eDiagnosticSeverityWarning,
+ eDiagnosticSeverityRemark
+};
+
+const uint32_t LLDB_INVALID_COMPILER_ID = UINT32_MAX;
+
+class Diagnostic
+{
+friend class DiagnosticManager;
+
+public:
+ DiagnosticOrigin getKind() const { return m_origin; }
+
+ static bool classof(const Diagnostic *diag)
+ {
+ DiagnosticOrigin kind = diag->getKind();
+ switch (kind)
+ {
+ case eDiagnosticOriginUnknown:
+ case eDiagnosticOriginLLDB:
+ case eDiagnosticOriginGo:
+ case eDiagnosticOriginLLVM:
+ return true;
+ case eDiagnosticOriginClang:
+ case eDiagnosticOriginSwift:
+ return false;
+ }
+ }
+
+ Diagnostic(const char *message, DiagnosticSeverity severity, DiagnosticOrigin origin, uint32_t compiler_id) :
+ m_message(message),
+ m_severity(severity),
+ m_origin(origin),
+ m_compiler_id(compiler_id)
+ {
+ }
+
+ Diagnostic(const Diagnostic &rhs) :
+ m_message(rhs.m_message),
+ m_severity(rhs.m_severity),
+ m_origin(rhs.m_origin),
+ m_compiler_id(rhs.m_compiler_id)
+ {
+ }
+
+ virtual ~Diagnostic() = default;
+
+ virtual bool HasFixIts () const { return false; }
+
+ DiagnosticSeverity
+ GetSeverity() const
+ {
+ return m_severity;
+ }
+
+ uint32_t
+ GetCompilerID() const
+ {
+ return m_compiler_id;
+ }
+
+ const char *
+ GetMessage() const
+ {
+ return m_message.c_str();
+ }
+
+ void AppendMessage(const char *message, bool precede_with_newline = true)
+ {
+ if (precede_with_newline)
+ m_message.push_back('\n');
+ m_message.append(message);
+ }
+
+protected:
+ std::string m_message;
+ DiagnosticSeverity m_severity;
+ DiagnosticOrigin m_origin;
+ uint32_t m_compiler_id; // Compiler-specific diagnostic ID
+};
+
+typedef std::vector<Diagnostic *> DiagnosticList;
+
+class DiagnosticManager
+{
+public:
+ void
+ Clear()
+ {
+ m_diagnostics.clear();
+ m_fixed_expression.clear();
+ }
+
+ // The diagnostic manager holds a list of diagnostics, which are owned by the manager.
+ const DiagnosticList &
+ Diagnostics()
+ {
+ return m_diagnostics;
+ }
+
+ ~DiagnosticManager()
+ {
+ for (Diagnostic *diag : m_diagnostics)
+ {
+ delete diag;
+ }
+ }
+
+ bool
+ HasFixIts()
+ {
+ for (Diagnostic *diag : m_diagnostics)
+ {
+ if (diag->HasFixIts())
+ return true;
+ }
+ return false;
+ }
+
+ void
+ AddDiagnostic(const char *message, DiagnosticSeverity severity, DiagnosticOrigin origin,
+ uint32_t compiler_id = LLDB_INVALID_COMPILER_ID)
+ {
+ m_diagnostics.push_back(new Diagnostic(message, severity, origin, compiler_id));
+ }
+
+ void
+ AddDiagnostic(Diagnostic *diagnostic)
+ {
+ m_diagnostics.push_back(diagnostic);
+ }
+
+ size_t
+ Printf(DiagnosticSeverity severity, const char *format, ...) __attribute__((format(printf, 3, 4)));
+ size_t
+ PutCString(DiagnosticSeverity severity, const char *cstr);
+
+ void
+ AppendMessageToDiagnostic(const char *cstr)
+ {
+ if (m_diagnostics.size())
+ {
+ m_diagnostics.back()->AppendMessage(cstr);
+ }
+ }
+
+ // Returns a string containing errors in this format:
+ //
+ // "error: error text\n
+ // warning: warning text\n
+ // remark text\n"
+ std::string
+ GetString(char separator = '\n');
+
+ void
+ Dump(Log *log);
+
+ const std::string &
+ GetFixedExpression()
+ {
+ return m_fixed_expression;
+ }
+
+ // Moves fixed_expression to the internal storage.
+ void
+ SetFixedExpression(std::string fixed_expression)
+ {
+ m_fixed_expression = std::move(fixed_expression);
+ fixed_expression.clear();
+ }
+
+protected:
+ DiagnosticList m_diagnostics;
+ std::string m_fixed_expression;
+};
+}
+
+#endif /* lldb_DiagnosticManager_h */
diff --git a/include/lldb/Expression/ExpressionParser.h b/include/lldb/Expression/ExpressionParser.h
index 49333e79bf5e..323e515e3bba 100644
--- a/include/lldb/Expression/ExpressionParser.h
+++ b/include/lldb/Expression/ExpressionParser.h
@@ -57,17 +57,34 @@ 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 in which to store the errors and warnings.
///
/// @return
/// The number of errors encountered during parsing. 0 means
/// success.
//------------------------------------------------------------------
virtual unsigned
- Parse (Stream &stream) = 0;
+ Parse(DiagnosticManager &diagnostic_manager) = 0;
//------------------------------------------------------------------
+ /// Try to use the FixIts in the diagnostic_manager to rewrite the
+ /// expression. If successful, the rewritten expression is stored
+ /// in the diagnostic_manager, get it out with GetFixedExpression.
+ ///
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager containing fixit's to apply.
+ ///
+ /// @return
+ /// \b true if the rewrite was successful, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ RewriteExpression(DiagnosticManager &diagnostic_manager)
+ {
+ return false;
+ }
+
+ //------------------------------------------------------------------
/// Ready an already-parsed expression for execution, possibly
/// evaluating it statically.
///
diff --git a/include/lldb/Expression/ExpressionSourceCode.h b/include/lldb/Expression/ExpressionSourceCode.h
index 2dd09378fcd2..33ceade45558 100644
--- a/include/lldb/Expression/ExpressionSourceCode.h
+++ b/include/lldb/Expression/ExpressionSourceCode.h
@@ -54,10 +54,17 @@ public:
bool GetText (std::string &text,
lldb::LanguageType wrapping_language,
- bool const_object,
bool static_method,
ExecutionContext &exe_ctx) const;
+ // Given a string returned by GetText, find the beginning and end of the body passed to CreateWrapped.
+ // Return true if the bounds could be found. This will also work on text with FixItHints applied.
+ static bool
+ GetOriginalBodyBounds(std::string transformed_text,
+ lldb::LanguageType wrapping_language,
+ size_t &start_loc,
+ size_t &end_loc);
+
private:
ExpressionSourceCode (const char *name,
const char *prefix,
diff --git a/include/lldb/Expression/ExpressionVariable.h b/include/lldb/Expression/ExpressionVariable.h
index d8030ba1c257..451acb685bb7 100644
--- a/include/lldb/Expression/ExpressionVariable.h
+++ b/include/lldb/Expression/ExpressionVariable.h
@@ -16,6 +16,8 @@
#include <vector>
// Other libraries and framework includes
+#include "llvm/ADT/DenseMap.h"
+
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/ConstString.h"
@@ -309,10 +311,19 @@ public:
RemovePersistentVariable (lldb::ExpressionVariableSP variable) = 0;
virtual lldb::addr_t
- LookupSymbol (const ConstString &name) = 0;
+ LookupSymbol (const ConstString &name);
+
+ void
+ RegisterExecutionUnit (lldb::IRExecutionUnitSP &execution_unit_sp);
private:
LLVMCastKind m_kind;
+
+ typedef std::set<lldb::IRExecutionUnitSP> ExecutionUnitSet;
+ ExecutionUnitSet m_execution_units; ///< The execution units that contain valuable symbols.
+
+ typedef llvm::DenseMap<const char *, lldb::addr_t> SymbolMap;
+ SymbolMap m_symbol_map; ///< The addresses of the symbols in m_execution_units.
};
} // namespace lldb_private
diff --git a/include/lldb/Expression/FunctionCaller.h b/include/lldb/Expression/FunctionCaller.h
index c9a45811670f..3848073c654f 100644
--- a/include/lldb/Expression/FunctionCaller.h
+++ b/include/lldb/Expression/FunctionCaller.h
@@ -99,17 +99,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.
//------------------------------------------------------------------
virtual unsigned
- CompileFunction (Stream &errors) = 0;
-
+ CompileFunction (lldb::ThreadSP thread_to_use_sp,
+ DiagnosticManager &diagnostic_manager) = 0;
+
//------------------------------------------------------------------
- /// Insert the default function wrapper and its default argument struct
+ /// Insert the default function wrapper and its default argument struct
///
/// @param[in] exe_ctx
/// The execution context to insert the function and its arguments
@@ -120,16 +126,14 @@ public:
/// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
/// and args_addr_ref is pointed to it.
///
- /// @param[in] errors
- /// The stream to write errors to.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
bool
- InsertFunction (ExecutionContext &exe_ctx,
- lldb::addr_t &args_addr_ref,
- Stream &errors);
+ InsertFunction(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, DiagnosticManager &diagnostic_manager);
//------------------------------------------------------------------
/// Insert the default function wrapper (using the JIT)
@@ -138,17 +142,17 @@ public:
/// The execution context to insert the function and its arguments
/// into.
///
- /// @param[in] errors
- /// The stream to write errors to.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
- bool WriteFunctionWrapper (ExecutionContext &exe_ctx,
- Stream &errors);
-
+ bool
+ WriteFunctionWrapper(ExecutionContext &exe_ctx, DiagnosticManager &diagnostic_manager);
+
//------------------------------------------------------------------
- /// Insert the default function argument struct
+ /// Insert the default function argument struct
///
/// @param[in] exe_ctx
/// The execution context to insert the function and its arguments
@@ -159,16 +163,16 @@ public:
/// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
/// and args_addr_ref is pointed to it.
///
- /// @param[in] errors
- /// The stream to write errors to.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
- bool WriteFunctionArguments (ExecutionContext &exe_ctx,
- lldb::addr_t &args_addr_ref,
- Stream &errors);
-
+ bool
+ WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref,
+ DiagnosticManager &diagnostic_manager);
+
//------------------------------------------------------------------
/// Insert an argument struct with a non-default function address and
/// non-default argument values
@@ -185,16 +189,15 @@ public:
/// @param[in] arg_values
/// The values of the function's arguments.
///
- /// @param[in] errors
- /// The stream to write errors to.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
- bool WriteFunctionArguments (ExecutionContext &exe_ctx,
- lldb::addr_t &args_addr_ref,
- ValueList &arg_values,
- Stream &errors);
+ bool
+ WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, ValueList &arg_values,
+ DiagnosticManager &diagnostic_manager);
//------------------------------------------------------------------
/// Run the function this FunctionCaller was created with.
@@ -211,8 +214,8 @@ public:
/// for deallocating it. And if passed in with a value other than LLDB_INVALID_ADDRESS,
/// this should point to an already allocated structure with the values already written.
///
- /// @param[in] errors
- /// Errors will be written here if there are any.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @param[in] options
/// The options for this expression execution.
@@ -224,12 +227,9 @@ public:
/// Returns one of the ExpressionResults enum indicating function call status.
//------------------------------------------------------------------
lldb::ExpressionResults
- ExecuteFunction(ExecutionContext &exe_ctx,
- lldb::addr_t *args_addr_ptr,
- const EvaluateExpressionOptions &options,
- Stream &errors,
- Value &results);
-
+ ExecuteFunction(ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr, const EvaluateExpressionOptions &options,
+ DiagnosticManager &diagnostic_manager, Value &results);
+
//------------------------------------------------------------------
/// Get a thread plan to run the function this FunctionCaller was created with.
///
@@ -243,8 +243,8 @@ public:
/// @param[in] args_addr
/// The address of the argument struct.
///
- /// @param[in] errors
- /// The stream to write errors to.
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
///
/// @param[in] stop_others
/// True if other threads should pause during execution.
@@ -256,11 +256,9 @@ public:
/// A ThreadPlan shared pointer for executing the function.
//------------------------------------------------------------------
lldb::ThreadPlanSP
- GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
- lldb::addr_t args_addr,
- const EvaluateExpressionOptions &options,
- Stream &errors);
-
+ GetThreadPlanToCallFunction(ExecutionContext &exe_ctx, lldb::addr_t args_addr,
+ const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager);
+
//------------------------------------------------------------------
/// Get the result of the function from its struct
///
diff --git a/include/lldb/Expression/IRDynamicChecks.h b/include/lldb/Expression/IRDynamicChecks.h
index ef77d55f4b34..9f31a6eb01d6 100644
--- a/include/lldb/Expression/IRDynamicChecks.h
+++ b/include/lldb/Expression/IRDynamicChecks.h
@@ -61,8 +61,8 @@ public:
/// Install the utility functions into a process. This binds the
/// instance of DynamicCheckerFunctions to that process.
///
- /// @param[in] error_stream
- /// A stream to print errors on.
+ /// @param[in] diagnostic_manager
+ /// A diagnostic manager to report errors to.
///
/// @param[in] exe_ctx
/// The execution context to install the functions into.
@@ -71,11 +71,12 @@ public:
/// True on success; false on failure, or if the functions have
/// already been installed.
//------------------------------------------------------------------
- bool Install (Stream &error_stream,
- ExecutionContext &exe_ctx);
-
- bool DoCheckersExplainStop (lldb::addr_t addr, Stream &message);
-
+ bool
+ Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx);
+
+ bool
+ DoCheckersExplainStop(lldb::addr_t addr, Stream &message);
+
std::unique_ptr<UtilityFunction> m_valid_pointer_check;
std::unique_ptr<UtilityFunction> m_objc_object_check;
};
diff --git a/include/lldb/Expression/IRExecutionUnit.h b/include/lldb/Expression/IRExecutionUnit.h
index 86744b7b9726..d557a35d0b06 100644
--- a/include/lldb/Expression/IRExecutionUnit.h
+++ b/include/lldb/Expression/IRExecutionUnit.h
@@ -26,8 +26,8 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Expression/IRMemoryMap.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
namespace llvm {
@@ -71,13 +71,19 @@ public:
std::unique_ptr<llvm::Module> &module_ap,
ConstString &name,
const lldb::TargetSP &target_sp,
+ const SymbolContext &sym_ctx,
std::vector<std::string> &cpu_features);
//------------------------------------------------------------------
/// Destructor
//------------------------------------------------------------------
~IRExecutionUnit() override;
-
+
+ ConstString GetFunctionName()
+ {
+ return m_name;
+ }
+
llvm::Module *
GetModule()
{
@@ -131,7 +137,83 @@ public:
lldb::ModuleSP
GetJITModule ();
+
+ lldb::addr_t
+ FindSymbol(const ConstString &name);
+ void
+ GetStaticInitializers(std::vector <lldb::addr_t> &static_initializers);
+
+ //----------------------------------------------------------------------
+ /// @class JittedFunction IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h"
+ /// @brief Encapsulates a single function that has been generated by the JIT.
+ ///
+ /// Functions that have been generated by the JIT are first resident in the
+ /// local process, and then placed in the target process. JittedFunction
+ /// represents a function possibly resident in both.
+ //----------------------------------------------------------------------
+ struct JittedEntity {
+ ConstString m_name; ///< The function's name
+ lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory
+ lldb::addr_t m_remote_addr; ///< The address of the function in the target's memory
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variabes.
+ ///
+ /// @param[in] name
+ /// The name of the function.
+ ///
+ /// @param[in] local_addr
+ /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
+ /// it is not present in LLDB's memory.
+ ///
+ /// @param[in] remote_addr
+ /// The address of the function in the target, or LLDB_INVALID_ADDRESS
+ /// if it is not present in the target's memory.
+ //------------------------------------------------------------------
+ JittedEntity (const char *name,
+ lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
+ lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
+ m_name (name),
+ m_local_addr (local_addr),
+ m_remote_addr (remote_addr)
+ {
+ }
+ };
+
+ struct JittedFunction : JittedEntity
+ {
+ bool m_external;
+ JittedFunction (const char *name,
+ bool external,
+ lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
+ lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
+ JittedEntity (name, local_addr, remote_addr),
+ m_external(external)
+ {}
+ };
+
+ struct JittedGlobalVariable : JittedEntity
+ {
+ JittedGlobalVariable (const char *name,
+ lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
+ lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
+ JittedEntity (name, local_addr, remote_addr)
+ {}
+ };
+
+ const std::vector<JittedFunction> &GetJittedFunctions()
+ {
+ return m_jitted_functions;
+ }
+
+ const std::vector<JittedGlobalVariable> &GetJittedGlobalVariables()
+ {
+ return m_jitted_global_variables;
+ }
+
private:
//------------------------------------------------------------------
/// Look up the object in m_address_map that contains a given address,
@@ -201,6 +283,33 @@ private:
DisassembleFunction (Stream &stream,
lldb::ProcessSP &process_sp);
+ struct SearchSpec;
+
+ void
+ CollectCandidateCNames(std::vector<SearchSpec> &C_specs,
+ const ConstString &name);
+
+ void
+ CollectCandidateCPlusPlusNames(std::vector<SearchSpec> &CPP_specs,
+ const std::vector<SearchSpec> &C_specs,
+ const SymbolContext &sc);
+
+ void
+ CollectFallbackNames(std::vector<SearchSpec> &fallback_specs,
+ const std::vector<SearchSpec> &C_specs);
+
+ lldb::addr_t
+ FindInSymbols(const std::vector<SearchSpec> &specs,
+ const lldb_private::SymbolContext &sc);
+
+ lldb::addr_t
+ FindInRuntimes(const std::vector<SearchSpec> &specs,
+ const lldb_private::SymbolContext &sc);
+
+ lldb::addr_t
+ FindInUserDefinedSymbols(const std::vector<SearchSpec> &specs,
+ const lldb_private::SymbolContext &sc);
+
void
ReportSymbolLookupError(const ConstString &name);
@@ -275,9 +384,6 @@ private:
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override {
}
- //------------------------------------------------------------------
- /// Passthrough interface stub
- //------------------------------------------------------------------
uint64_t getSymbolAddress(const std::string &Name) override;
void *getPointerToNamedFunction(const std::string &Name,
@@ -288,45 +394,6 @@ private:
IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for.
};
- //----------------------------------------------------------------------
- /// @class JittedFunction IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h"
- /// @brief Encapsulates a single function that has been generated by the JIT.
- ///
- /// Functions that have been generated by the JIT are first resident in the
- /// local process, and then placed in the target process. JittedFunction
- /// represents a function possibly resident in both.
- //----------------------------------------------------------------------
- struct JittedFunction {
- std::string m_name; ///< The function's name
- lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory
- lldb::addr_t m_remote_addr; ///< The address of the function in the target's memory
-
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] name
- /// The name of the function.
- ///
- /// @param[in] local_addr
- /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
- /// it is not present in LLDB's memory.
- ///
- /// @param[in] remote_addr
- /// The address of the function in the target, or LLDB_INVALID_ADDRESS
- /// if it is not present in the target's memory.
- //------------------------------------------------------------------
- JittedFunction (const char *name,
- lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
- lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
- m_name (name),
- m_local_addr (local_addr),
- m_remote_addr (remote_addr)
- {
- }
- };
-
static const unsigned eSectionIDInvalid = (unsigned)-1;
//----------------------------------------------------------------------
@@ -377,6 +444,9 @@ private:
void dump (Log *log);
};
+ bool
+ CommitOneAllocation (lldb::ProcessSP &process_sp, Error &error, AllocationRecord &record);
+
typedef std::vector<AllocationRecord> RecordVector;
RecordVector m_records;
@@ -385,14 +455,24 @@ private:
std::unique_ptr<llvm::Module> m_module_ap; ///< Holder for the module until it's been handed off
llvm::Module *m_module; ///< Owned by the execution engine
std::vector<std::string> m_cpu_features;
- llvm::SmallVector<JittedFunction, 1> m_jitted_functions; ///< A vector of all functions that have been JITted into machine code
+ std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions that have been JITted into machine code
+ std::vector<JittedGlobalVariable> m_jitted_global_variables; ///< A vector of all functions that have been JITted into machine code
const ConstString m_name;
+ SymbolContext m_sym_ctx; ///< Used for symbol lookups
std::vector<ConstString> m_failed_lookups;
std::atomic<bool> m_did_jit;
lldb::addr_t m_function_load_addr;
lldb::addr_t m_function_end_load_addr;
+
+ bool m_strip_underscore; ///< True for platforms where global symbols have a _ prefix
+ bool m_reported_allocations; ///< True after allocations have been reported. It is possible that
+ ///< sections will be allocated when this is true, in which case they weren't
+ ///< depended on by any function. (Top-level code defining a variable, but
+ ///< defining no functions using that variable, would do this.) If this
+ ///< is true, any allocations need to be committed immediately -- no
+ ///< opportunity for relocation.
};
} // namespace lldb_private
diff --git a/include/lldb/Expression/IRInterpreter.h b/include/lldb/Expression/IRInterpreter.h
index 4eb81bc68d19..14c145b91c26 100644
--- a/include/lldb/Expression/IRInterpreter.h
+++ b/include/lldb/Expression/IRInterpreter.h
@@ -50,7 +50,7 @@ public:
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,
diff --git a/include/lldb/Expression/IRMemoryMap.h b/include/lldb/Expression/IRMemoryMap.h
index 6fb718a341f7..36631d25a742 100644
--- a/include/lldb/Expression/IRMemoryMap.h
+++ b/include/lldb/Expression/IRMemoryMap.h
@@ -129,7 +129,7 @@ private:
typedef std::map<lldb::addr_t, Allocation> AllocationMap;
AllocationMap m_allocations;
- lldb::addr_t FindSpace (size_t size, bool zero_memory = false);
+ lldb::addr_t FindSpace (size_t size);
bool ContainsHostOnlyAllocations ();
AllocationMap::iterator FindAllocation (lldb::addr_t addr, size_t size);
diff --git a/include/lldb/Expression/LLVMUserExpression.h b/include/lldb/Expression/LLVMUserExpression.h
index e3d17986f4b3..3762fa11ddbd 100644
--- a/include/lldb/Expression/LLVMUserExpression.h
+++ b/include/lldb/Expression/LLVMUserExpression.h
@@ -16,6 +16,9 @@
#include <map>
#include <vector>
+// Other libraries and framework includes
+#include "llvm/IR/LegacyPassManager.h"
+
// Project includes
#include "lldb/Expression/UserExpression.h"
@@ -34,26 +37,28 @@ namespace lldb_private
//----------------------------------------------------------------------
class LLVMUserExpression : public UserExpression
{
- public:
- LLVMUserExpression(ExecutionContextScope &exe_scope,
- const char *expr,
- const char *expr_prefix,
- lldb::LanguageType language,
- ResultType desired_type,
+public:
+ // The IRPasses struct is filled in by a runtime after an expression is compiled and can be used to to run
+ // fixups/analysis passes as required. EarlyPasses are run on the generated module before lldb runs its own IR
+ // fixups and inserts instrumentation code/pointer checks. LatePasses are run after the module has been processed by
+ // llvm, before the module is assembled and run in the ThreadPlan.
+ struct IRPasses
+ {
+ IRPasses() : EarlyPasses(nullptr), LatePasses(nullptr){};
+ std::shared_ptr<llvm::legacy::PassManager> EarlyPasses;
+ std::shared_ptr<llvm::legacy::PassManager> LatePasses;
+ };
+
+ LLVMUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
+ lldb::LanguageType language, ResultType desired_type,
const EvaluateExpressionOptions &options);
~LLVMUserExpression() override;
- lldb::ExpressionResults Execute(Stream &error_stream,
- ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions &options,
- lldb::UserExpressionSP &shared_ptr_to_me,
- lldb::ExpressionVariableSP &result) override;
-
- 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;
+ 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;
bool
CanInterpret() override
@@ -73,17 +78,22 @@ class LLVMUserExpression : public UserExpression
lldb::ModuleSP GetJITModule() override;
- protected:
- virtual void ScanContext(ExecutionContext &exe_ctx, lldb_private::Error &err) = 0;
+protected:
+ lldb::ExpressionResults
+ DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me,
+ lldb::ExpressionVariableSP &result) override;
- bool PrepareToExecuteJITExpression(Stream &error_stream, ExecutionContext &exe_ctx, lldb::addr_t &struct_address);
+ virtual void
+ ScanContext(ExecutionContext &exe_ctx, lldb_private::Error &err) = 0;
- virtual bool
- AddArguments (ExecutionContext &exe_ctx,
- std::vector<lldb::addr_t> &args,
- lldb::addr_t struct_address,
- Stream &error_stream) = 0;
+ bool
+ PrepareToExecuteJITExpression(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb::addr_t &struct_address);
+ virtual bool
+ AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args, lldb::addr_t struct_address,
+ DiagnosticManager &diagnostic_manager) = 0;
lldb::addr_t m_stack_frame_bottom; ///< The bottom of the allocated stack frame.
lldb::addr_t m_stack_frame_top; ///< The top of the allocated stack frame.
diff --git a/include/lldb/Expression/UserExpression.h b/include/lldb/Expression/UserExpression.h
index 517dfcd1dc47..2b685dc046c7 100644
--- a/include/lldb/Expression/UserExpression.h
+++ b/include/lldb/Expression/UserExpression.h
@@ -79,8 +79,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
@@ -98,11 +98,8 @@ public:
/// True on success (no errors); false otherwise.
//------------------------------------------------------------------
virtual bool
- Parse (Stream &error_stream,
- ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy,
- bool keep_result_in_memory,
- bool generate_debug_info) = 0;
+ Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory, bool generate_debug_info) = 0;
virtual bool CanInterpret() = 0;
@@ -110,10 +107,11 @@ public:
MatchesContext (ExecutionContext &exe_ctx);
//------------------------------------------------------------------
- /// Execute the parsed expression
+ /// Execute the parsed expression by callinng the derived class's
+ /// DoExecute method.
///
- /// @param[in] error_stream
- /// A stream to print errors to.
+ /// @param[in] diagnostic_manager
+ /// A diagnostic manager to report errors to.
///
/// @param[in] exe_ctx
/// The execution context to use when looking up entities that
@@ -136,16 +134,15 @@ public:
/// @return
/// A Process::Execution results value.
//------------------------------------------------------------------
- virtual lldb::ExpressionResults Execute(Stream &error_stream, ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions &options,
- lldb::UserExpressionSP &shared_ptr_to_me,
- lldb::ExpressionVariableSP &result) = 0;
+ lldb::ExpressionResults
+ Execute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options,
+ lldb::UserExpressionSP &shared_ptr_to_me, lldb::ExpressionVariableSP &result);
//------------------------------------------------------------------
/// Apply the side effects of the function to program state.
///
- /// @param[in] error_stream
- /// A stream to print errors to.
+ /// @param[in] diagnostic_manager
+ /// A diagnostic manager to report errors to.
///
/// @param[in] exe_ctx
/// The execution context to use when looking up entities that
@@ -164,10 +161,10 @@ public:
/// @return
/// A Process::Execution results value.
//------------------------------------------------------------------
- virtual 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) = 0;
+ virtual 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) = 0;
//------------------------------------------------------------------
/// Return the string that the parser should parse.
@@ -285,6 +282,9 @@ public:
/// @param[in] line_offset
/// The offset of the first line of the expression from the "beginning" of a virtual source file used for error reporting and debug info.
///
+ /// @param[out] fixed_expression
+ /// If non-nullptr, the fixed expression is copied into the provided string.
+ ///
/// @param[out] jit_module_sp_ptr
/// If non-nullptr, used to persist the generated IR module.
///
@@ -299,11 +299,24 @@ public:
lldb::ValueObjectSP &result_valobj_sp,
Error &error,
uint32_t line_offset = 0,
+ std::string *fixed_expression = nullptr,
lldb::ModuleSP *jit_module_sp_ptr = nullptr);
static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression.
+
+ const char *
+ GetFixedText()
+ {
+ if (m_fixed_text.empty())
+ return nullptr;
+ return m_fixed_text.c_str();
+ }
protected:
+ virtual lldb::ExpressionResults
+ DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options,
+ lldb::UserExpressionSP &shared_ptr_to_me, lldb::ExpressionVariableSP &result) = 0;
+
static lldb::addr_t
GetObjectPointer (lldb::StackFrameSP frame_sp,
ConstString &object_name,
@@ -325,6 +338,7 @@ protected:
Address m_address; ///< The address the process is stopped in.
std::string m_expr_text; ///< The text of the expression, as typed by the user
std::string m_expr_prefix; ///< The text of the translation-level definitions, as provided by the user
+ std::string m_fixed_text; ///< The text of the expression with fix-its applied - this won't be set if the fixed text doesn't parse.
lldb::LanguageType m_language; ///< The language to use when parsing (eLanguageTypeUnknown means use defaults)
ResultType m_desired_type; ///< The type to coerce the expression's result to. If eResultTypeAny, inferred from the expression.
EvaluateExpressionOptions m_options; ///< Additional options provided by the user.
diff --git a/include/lldb/Expression/UtilityFunction.h b/include/lldb/Expression/UtilityFunction.h
index bee83d8111e4..a78972082c52 100644
--- a/include/lldb/Expression/UtilityFunction.h
+++ b/include/lldb/Expression/UtilityFunction.h
@@ -54,8 +54,8 @@ public:
//------------------------------------------------------------------
/// 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 print parse errors and warnings to.
///
/// @param[in] exe_ctx
/// The execution context to install the utility function to.
@@ -64,8 +64,8 @@ public:
/// True on success (no errors); false otherwise.
//------------------------------------------------------------------
virtual bool
- Install (Stream &error_stream, ExecutionContext &exe_ctx) = 0;
-
+ Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) = 0;
+
//------------------------------------------------------------------
/// Check whether the given PC is inside the function
///
@@ -139,8 +139,10 @@ public:
}
// This makes the function caller function.
+ // Pass in the ThreadSP if you have one available, compilation can end up calling code (e.g. to look up indirect
+ // functions) and we don't want this to wander onto another thread.
FunctionCaller *
- MakeFunctionCaller(const CompilerType &return_type, const ValueList &arg_value_list, Error &error);
+ MakeFunctionCaller(const CompilerType &return_type, const ValueList &arg_value_list, lldb::ThreadSP compilation_thread, Error &error);
// This one retrieves the function caller that is already made. If you haven't made it yet, this returns nullptr
FunctionCaller *
diff --git a/include/lldb/Host/Editline.h b/include/lldb/Host/Editline.h
index 697be4cd8e77..43c0eccf37dd 100644
--- a/include/lldb/Host/Editline.h
+++ b/include/lldb/Host/Editline.h
@@ -27,11 +27,12 @@
#include <sstream>
#include <vector>
+#include <locale>
// components needed to handle wide characters ( <codecvt>, codecvt_utf8, libedit built with '--enable-widec' )
-// are not consistenly available on non-OSX platforms. The wchar_t versions of libedit functions will only be
+// are available on some platforms. The wchar_t versions of libedit functions will only be
// used in cases where this is true. This is a compile time dependecy, for now selected per target Platform
-#if defined (__APPLE__)
+#if defined (__APPLE__) || defined(__NetBSD__)
#define LLDB_EDITLINE_USE_WCHAR 1
#include <codecvt>
#else
@@ -49,13 +50,13 @@
#endif
#endif
+#include <mutex>
#include <string>
#include <vector>
#include "lldb/Host/Condition.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/Predicate.h"
namespace lldb_private {
@@ -278,11 +279,15 @@ namespace lldb_private {
/// Prompt implementation for EditLine.
const char *
Prompt();
-
- /// Line break command used when return is pressed in multi-line mode.
+
+ /// Line break command used when meta+return is pressed in multi-line mode.
unsigned char
BreakLineCommand (int ch);
-
+
+ /// Command used when return is pressed in multi-line mode.
+ unsigned char
+ EndOrAddLineCommand(int ch);
+
/// Delete command used when delete is pressed in multi-line mode.
unsigned char
DeleteNextCharCommand (int ch);
@@ -298,7 +303,15 @@ namespace lldb_private {
/// Line navigation command used when ^N or down arrow are pressed in multi-line mode.
unsigned char
NextLineCommand (int ch);
-
+
+ /// History navigation command used when Alt + up arrow is pressed in multi-line mode.
+ unsigned char
+ PreviousHistoryCommand(int ch);
+
+ /// History navigation command used when Alt + down arrow is pressed in multi-line mode.
+ unsigned char
+ NextHistoryCommand(int ch);
+
/// Buffer start command used when Esc < is typed in multi-line emacs mode.
unsigned char
BufferStartCommand (int ch);
@@ -358,7 +371,7 @@ namespace lldb_private {
CompleteCallbackType m_completion_callback = nullptr;
void * m_completion_callback_baton = nullptr;
- Mutex m_output_mutex;
+ std::mutex m_output_mutex;
};
}
diff --git a/include/lldb/Host/File.h b/include/lldb/Host/File.h
index 27f3f405ffd3..e2c44fa5c0d2 100644
--- a/include/lldb/Host/File.h
+++ b/include/lldb/Host/File.h
@@ -45,7 +45,7 @@ public:
eOpenOptionNonBlocking = (1u << 4), // File reads
eOpenOptionCanCreate = (1u << 5), // Create file if doesn't already exist
eOpenOptionCanCreateNewOnly = (1u << 6), // Can create file only if it doesn't already exist
- eOpenoptionDontFollowSymlinks = (1u << 7),
+ eOpenOptionDontFollowSymlinks = (1u << 7),
eOpenOptionCloseOnExec = (1u << 8) // Close the file when executing a new process
};
@@ -74,8 +74,6 @@ public:
{
}
- File (const File &rhs);
-
//------------------------------------------------------------------
/// Constructor with path.
///
@@ -138,9 +136,6 @@ public:
//------------------------------------------------------------------
~File() override;
- File &
- operator= (const File &rhs);
-
bool
IsValid() const override
{
@@ -223,9 +218,9 @@ public:
Error
Close() override;
- Error
- Duplicate (const File &rhs);
-
+ void
+ Clear ();
+
int
GetDescriptor() const;
@@ -554,6 +549,9 @@ protected:
LazyBool m_is_interactive;
LazyBool m_is_real_terminal;
LazyBool m_supports_colors;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(File);
};
} // namespace lldb_private
diff --git a/include/lldb/Host/FileSpec.h b/include/lldb/Host/FileSpec.h
index 0ff1bc9d2f44..219af662dfcb 100644
--- a/include/lldb/Host/FileSpec.h
+++ b/include/lldb/Host/FileSpec.h
@@ -117,6 +117,12 @@ public:
//------------------------------------------------------------------
~FileSpec ();
+ bool
+ DirectoryEquals(const FileSpec &other) const;
+
+ bool
+ FileEquals(const FileSpec &other) const;
+
//------------------------------------------------------------------
/// Assignment operator.
///
@@ -261,6 +267,19 @@ public:
Equal (const FileSpec& a, const FileSpec& b, bool full, bool remove_backups = false);
//------------------------------------------------------------------
+ /// Case sensitivity of path.
+ ///
+ /// @return
+ /// \b true if the file path is case sensitive (POSIX), false
+ /// if case insensitive (Windows).
+ //------------------------------------------------------------------
+ bool
+ IsCaseSensitive() const
+ {
+ return m_syntax != ePathSyntaxWindows;
+ }
+
+ //------------------------------------------------------------------
/// Dump this object to a Stream.
///
/// Dump the object to the supplied stream \a s. If the object
diff --git a/include/lldb/Host/FileSystem.h b/include/lldb/Host/FileSystem.h
index 465ad451bdd6..d656d2264f66 100644
--- a/include/lldb/Host/FileSystem.h
+++ b/include/lldb/Host/FileSystem.h
@@ -11,6 +11,8 @@
#define liblldb_Host_FileSystem_h
#include <stdint.h>
+#include <stdio.h>
+#include <sys/stat.h>
#include "lldb/lldb-types.h"
@@ -23,6 +25,7 @@ class FileSystem
{
public:
static const char *DEV_NULL;
+ static const char *PATH_CONVERSION_ERROR;
static FileSpec::PathSyntax GetNativePathSyntax();
@@ -59,6 +62,15 @@ class FileSystem
/// Return \b true if \a spec is on a locally mounted file system, \b false otherwise.
static bool IsLocal(const FileSpec &spec);
+
+ /// Wraps ::fopen in a platform-independent way. Once opened, FILEs can be
+ /// manipulated and closed with the normal ::fread, ::fclose, etc. functions.
+ static FILE *
+ Fopen(const char *path, const char *mode);
+
+ /// Wraps ::stat in a platform-independent way.
+ static int
+ Stat(const char *path, struct stat *stats);
};
}
diff --git a/include/lldb/Host/Host.h b/include/lldb/Host/Host.h
index 235367a7cc5c..6a6b2265257a 100644
--- a/include/lldb/Host/Host.h
+++ b/include/lldb/Host/Host.h
@@ -38,12 +38,10 @@ class ProcessLaunchInfo;
class Host
{
public:
-
- typedef bool (*MonitorChildProcessCallback) (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
+ typedef std::function<bool(lldb::pid_t pid, bool exited,
+ int signal, // Zero for no signal
+ int status)> // Exit value of process if signal is zero
+ MonitorChildProcessCallback;
//------------------------------------------------------------------
/// Start monitoring a child process.
@@ -65,10 +63,6 @@ public:
/// A function callback to call when a child receives a signal
/// (if \a monitor_signals is true) or a child exits.
///
- /// @param[in] callback_baton
- /// A void * of user data that will be pass back when
- /// \a callback is called.
- ///
/// @param[in] pid
/// The process ID of a child process to monitor, -1 for all
/// processes.
@@ -84,8 +78,8 @@ public:
///
/// @see static void Host::StopMonitoringChildProcess (uint32_t)
//------------------------------------------------------------------
- static HostThread StartMonitoringChildProcess(MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid,
- bool monitor_signals);
+ static HostThread
+ StartMonitoringChildProcess(const MonitorChildProcessCallback &callback, lldb::pid_t pid, bool monitor_signals);
enum SystemLogType
{
diff --git a/include/lldb/Host/HostInfoBase.h b/include/lldb/Host/HostInfoBase.h
index 6a5f784ebba3..654c9683286b 100644
--- a/include/lldb/Host/HostInfoBase.h
+++ b/include/lldb/Host/HostInfoBase.h
@@ -34,6 +34,8 @@ class HostInfoBase
public:
static void Initialize();
+ static void
+ Terminate();
//------------------------------------------------------------------
/// Returns the number of CPUs on this current host.
diff --git a/include/lldb/Host/HostNativeProcessBase.h b/include/lldb/Host/HostNativeProcessBase.h
index ba16bf2b876f..d51161f1ef1b 100644
--- a/include/lldb/Host/HostNativeProcessBase.h
+++ b/include/lldb/Host/HostNativeProcessBase.h
@@ -46,9 +46,10 @@ class HostNativeProcessBase
return m_process;
}
- virtual HostThread StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals) = 0;
+ virtual HostThread
+ StartMonitoring(const Host::MonitorChildProcessCallback &callback, bool monitor_signals) = 0;
- protected:
+protected:
lldb::process_t m_process;
};
diff --git a/include/lldb/Host/HostProcess.h b/include/lldb/Host/HostProcess.h
index aff779aee219..59585fc31130 100644
--- a/include/lldb/Host/HostProcess.h
+++ b/include/lldb/Host/HostProcess.h
@@ -10,6 +10,7 @@
#ifndef lldb_Host_HostProcess_h_
#define lldb_Host_HostProcess_h_
+#include "lldb/Host/Host.h"
#include "lldb/lldb-types.h"
//----------------------------------------------------------------------
@@ -36,9 +37,7 @@ class HostThread;
class HostProcess
{
- public:
- typedef bool (*MonitorCallback)(void *callback_baton, lldb::pid_t process, bool exited, int signal, int status);
-
+public:
HostProcess();
HostProcess(lldb::process_t process);
~HostProcess();
@@ -49,7 +48,8 @@ class HostProcess
lldb::pid_t GetProcessId() const;
bool IsRunning() const;
- HostThread StartMonitoring(MonitorCallback callback, void *callback_baton, bool monitor_signals);
+ HostThread
+ StartMonitoring(const Host::MonitorChildProcessCallback &callback, bool monitor_signals);
HostNativeProcessBase &GetNativeProcess();
const HostNativeProcessBase &GetNativeProcess() const;
diff --git a/include/lldb/Host/OptionParser.h b/include/lldb/Host/OptionParser.h
index 175a1973c7af..c2aeaf0430ea 100644
--- a/include/lldb/Host/OptionParser.h
+++ b/include/lldb/Host/OptionParser.h
@@ -10,8 +10,8 @@
#ifndef liblldb_OptionParser_h_
#define liblldb_OptionParser_h_
+#include <mutex>
#include <string>
-#include "lldb/Host/Mutex.h"
struct option;
@@ -39,7 +39,8 @@ public:
eOptionalArgument
};
- static void Prepare(Mutex::Locker &locker);
+ static void
+ Prepare(std::unique_lock<std::mutex> &lock);
static void EnableError(bool error);
diff --git a/include/lldb/Host/ProcessRunLock.h b/include/lldb/Host/ProcessRunLock.h
index ceb1e90be757..797939a7edee 100644
--- a/include/lldb/Host/ProcessRunLock.h
+++ b/include/lldb/Host/ProcessRunLock.h
@@ -18,7 +18,6 @@
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-defines.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/Condition.h"
//----------------------------------------------------------------------
diff --git a/include/lldb/Host/common/NativeBreakpointList.h b/include/lldb/Host/common/NativeBreakpointList.h
index aba2f8a74cdc..bd1a9ae09db2 100644
--- a/include/lldb/Host/common/NativeBreakpointList.h
+++ b/include/lldb/Host/common/NativeBreakpointList.h
@@ -12,11 +12,11 @@
#include "lldb/lldb-private-forward.h"
#include "lldb/Core/Error.h"
-#include "lldb/Host/Mutex.h"
// #include "lldb/Host/NativeBreakpoint.h"
#include <functional>
#include <map>
+#include <mutex>
namespace lldb_private
{
@@ -48,7 +48,7 @@ namespace lldb_private
private:
typedef std::map<lldb::addr_t, NativeBreakpointSP> BreakpointMap;
- Mutex m_mutex;
+ std::recursive_mutex m_mutex;
BreakpointMap m_breakpoints;
};
}
diff --git a/include/lldb/Host/common/NativeProcessProtocol.h b/include/lldb/Host/common/NativeProcessProtocol.h
index 7236bf659042..d306a58f3cab 100644
--- a/include/lldb/Host/common/NativeProcessProtocol.h
+++ b/include/lldb/Host/common/NativeProcessProtocol.h
@@ -10,12 +10,12 @@
#ifndef liblldb_NativeProcessProtocol_h_
#define liblldb_NativeProcessProtocol_h_
+#include <mutex>
#include <vector>
#include "lldb/lldb-private-forward.h"
#include "lldb/lldb-types.h"
#include "lldb/Core/Error.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/MainLoop.h"
#include "llvm/ADT/StringRef.h"
@@ -364,15 +364,15 @@ namespace lldb_private
std::vector<NativeThreadProtocolSP> m_threads;
lldb::tid_t m_current_thread_id;
- mutable Mutex m_threads_mutex;
+ mutable std::recursive_mutex m_threads_mutex;
lldb::StateType m_state;
- mutable Mutex m_state_mutex;
+ mutable std::recursive_mutex m_state_mutex;
lldb_private::ExitType m_exit_type;
int m_exit_status;
std::string m_exit_description;
- Mutex m_delegates_mutex;
+ std::recursive_mutex m_delegates_mutex;
std::vector<NativeDelegate*> m_delegates;
NativeBreakpointList m_breakpoint_list;
NativeWatchpointList m_watchpoint_list;
diff --git a/include/lldb/Host/linux/Signalfd.h b/include/lldb/Host/linux/Signalfd.h
deleted file mode 100644
index cf50e87097fb..000000000000
--- a/include/lldb/Host/linux/Signalfd.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//===-- Signalfd.h ----------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This file defines signalfd functions & structures
-
-#ifndef liblldb_Host_linux_Signalfd_h_
-#define liblldb_Host_linux_Signalfd_h_
-
-#ifdef __ANDROID_NDK__
-#include <android/api-level.h>
-#endif
-
-#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
-
-#include <linux/types.h>
-#include <linux/fcntl.h>
-
-#define SFD_CLOEXEC O_CLOEXEC
-#define SFD_NONBLOCK O_NONBLOCK
-
-struct signalfd_siginfo {
- __u32 ssi_signo;
- __s32 ssi_errno;
- __s32 ssi_code;
- __u32 ssi_pid;
- __u32 ssi_uid;
- __s32 ssi_fd;
- __u32 ssi_tid;
- __u32 ssi_band;
- __u32 ssi_overrun;
- __u32 ssi_trapno;
- __s32 ssi_status;
- __s32 ssi_int;
- __u64 ssi_ptr;
- __u64 ssi_utime;
- __u64 ssi_stime;
- __u64 ssi_addr;
- __u16 ssi_addr_lsb;
- __u8 __pad[46];
-};
-
-int signalfd (int fd, const sigset_t *mask, int flags);
-
-#else
-#include <sys/signalfd.h>
-#endif
-
-#endif // liblldb_Host_linux_Signalfd_h_
diff --git a/include/lldb/Host/macosx/HostInfoMacOSX.h b/include/lldb/Host/macosx/HostInfoMacOSX.h
index 3b62c7fb9061..4a8ee4fd850e 100644
--- a/include/lldb/Host/macosx/HostInfoMacOSX.h
+++ b/include/lldb/Host/macosx/HostInfoMacOSX.h
@@ -32,6 +32,7 @@ class HostInfoMacOSX : public HostInfoPosix
static bool GetOSBuildString(std::string &s);
static bool GetOSKernelDescription(std::string &s);
static FileSpec GetProgramFileSpec();
+ static uint32_t GetMaxThreadNameLength();
protected:
static bool ComputeSupportExeDirectory(FileSpec &file_spec);
diff --git a/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h b/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h
index 7e7904cd5fa8..0d3ec35ce467 100644
--- a/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h
+++ b/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h
@@ -13,13 +13,13 @@
// C++ Includes
#include <atomic>
#include <memory>
+#include <mutex>
#include "lldb/lldb-forward.h"
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Connection.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Host/Predicate.h"
#include "lldb/Host/IOObject.h"
@@ -105,7 +105,7 @@ class ConnectionFileDescriptor : public Connection
// the port number.
Pipe m_pipe;
- Mutex m_mutex;
+ std::recursive_mutex m_mutex;
std::atomic<bool> m_shutting_down; // This marks that we are shutting down so if we get woken up from
// BytesAvailable to disconnect, we won't try to read again.
bool m_waiting_for_accept;
diff --git a/include/lldb/Host/posix/HostInfoPosix.h b/include/lldb/Host/posix/HostInfoPosix.h
index 9524a2a2481d..2e6c2a22f99c 100644
--- a/include/lldb/Host/posix/HostInfoPosix.h
+++ b/include/lldb/Host/posix/HostInfoPosix.h
@@ -33,7 +33,10 @@ class HostInfoPosix : public HostInfoBase
static FileSpec GetDefaultShell();
- protected:
+ static bool
+ GetEnvironmentVar(const std::string &var_name, std::string &var);
+
+protected:
static bool ComputeSupportExeDirectory(FileSpec &file_spec);
static bool ComputeHeaderDirectory(FileSpec &file_spec);
static bool ComputePythonDirectory(FileSpec &file_spec);
diff --git a/include/lldb/Host/posix/HostProcessPosix.h b/include/lldb/Host/posix/HostProcessPosix.h
index 5db49d17d757..53700fda1acc 100644
--- a/include/lldb/Host/posix/HostProcessPosix.h
+++ b/include/lldb/Host/posix/HostProcessPosix.h
@@ -39,7 +39,8 @@ class HostProcessPosix : public HostNativeProcessBase
lldb::pid_t GetProcessId() const override;
bool IsRunning() const override;
- HostThread StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals) override;
+ HostThread
+ StartMonitoring(const Host::MonitorChildProcessCallback &callback, bool monitor_signals) override;
};
} // namespace lldb_private
diff --git a/include/lldb/Host/windows/HostInfoWindows.h b/include/lldb/Host/windows/HostInfoWindows.h
index 022e15533d31..23d52e7810e7 100644
--- a/include/lldb/Host/windows/HostInfoWindows.h
+++ b/include/lldb/Host/windows/HostInfoWindows.h
@@ -26,14 +26,29 @@ class HostInfoWindows : public HostInfoBase
~HostInfoWindows();
public:
- static size_t GetPageSize();
-
- static bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update);
- static bool GetOSBuildString(std::string &s);
- static bool GetOSKernelDescription(std::string &s);
- static bool GetHostname(std::string &s);
- static FileSpec GetProgramFileSpec();
- static FileSpec GetDefaultShell();
+ static void
+ Initialize();
+ static void
+ Terminate();
+
+ static size_t
+ GetPageSize();
+
+ static bool
+ GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update);
+ static bool
+ GetOSBuildString(std::string &s);
+ static bool
+ GetOSKernelDescription(std::string &s);
+ static bool
+ GetHostname(std::string &s);
+ static FileSpec
+ GetProgramFileSpec();
+ static FileSpec
+ GetDefaultShell();
+
+ static bool
+ GetEnvironmentVar(const std::string &var_name, std::string &var);
protected:
static bool ComputePythonDirectory(FileSpec &file_spec);
diff --git a/include/lldb/Host/windows/HostProcessWindows.h b/include/lldb/Host/windows/HostProcessWindows.h
index 6f8ad3dc4d40..2d2ad0e70e8d 100644
--- a/include/lldb/Host/windows/HostProcessWindows.h
+++ b/include/lldb/Host/windows/HostProcessWindows.h
@@ -33,9 +33,10 @@ class HostProcessWindows : public HostNativeProcessBase
virtual lldb::pid_t GetProcessId() const;
virtual bool IsRunning() const;
- virtual HostThread StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals);
+ HostThread
+ StartMonitoring(const Host::MonitorChildProcessCallback &callback, bool monitor_signals) override;
- private:
+private:
static lldb::thread_result_t MonitorThread(void *thread_arg);
void Close();
diff --git a/include/lldb/Initialization/SystemLifetimeManager.h b/include/lldb/Initialization/SystemLifetimeManager.h
index 843ec2820677..2dd7b22c240a 100644
--- a/include/lldb/Initialization/SystemLifetimeManager.h
+++ b/include/lldb/Initialization/SystemLifetimeManager.h
@@ -11,9 +11,9 @@
#define LLDB_INITIALIZATION_SYSTEM_LIFETIME_MANAGER_H
#include "lldb/lldb-private-types.h"
-#include "lldb/Host/Mutex.h"
#include <memory>
+#include <mutex>
namespace lldb_private
{
@@ -29,13 +29,14 @@ class SystemLifetimeManager
void Terminate();
private:
- Mutex m_mutex;
- std::unique_ptr<SystemInitializer> m_initializer;
- bool m_initialized;
-
- // Noncopyable.
- SystemLifetimeManager(const SystemLifetimeManager &other) = delete;
- SystemLifetimeManager &operator=(const SystemLifetimeManager &other) = delete;
+ std::recursive_mutex m_mutex;
+ std::unique_ptr<SystemInitializer> m_initializer;
+ bool m_initialized;
+
+ // Noncopyable.
+ SystemLifetimeManager(const SystemLifetimeManager &other) = delete;
+ SystemLifetimeManager &
+ operator=(const SystemLifetimeManager &other) = delete;
};
}
diff --git a/include/lldb/Interpreter/Args.h b/include/lldb/Interpreter/Args.h
index e79318ba5626..bd54d5d3db5d 100644
--- a/include/lldb/Interpreter/Args.h
+++ b/include/lldb/Interpreter/Args.h
@@ -91,14 +91,20 @@ public:
~Args();
//------------------------------------------------------------------
- /// Dump all arguments to the stream \a s.
+ /// Dump all entries to the stream \a s using label \a label_name.
+ ///
+ /// If label_name is nullptr, the dump operation is skipped.
///
/// @param[in] s
/// The stream to which to dump all arguments in the argument
/// vector.
+ /// @param[in] label_name
+ /// The label_name to use as the label printed for each
+ /// entry of the args like so:
+ /// {label_name}[{index}]={value}
//------------------------------------------------------------------
void
- Dump (Stream *s);
+ Dump (Stream &s, const char *label_name = "argv") const;
//------------------------------------------------------------------
/// Sets the command string contained by this object.
@@ -403,7 +409,7 @@ public:
StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update);
static const char *
- GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg);
+ GetShellSafeArgument (const FileSpec& shell, const char *unsafe_arg, std::string &safe_arg);
// EncodeEscapeSequences will change the textual representation of common
// escape sequences like "\n" (two characters) into a single '\n'. It does
@@ -432,6 +438,23 @@ public:
void
LongestCommonPrefix (std::string &common_prefix);
+ //------------------------------------------------------------------
+ /// Return whether a given environment variable exists.
+ ///
+ /// This command treats Args like a list of environment variables,
+ /// as used in ProcessLaunchInfo. It treats each argument as
+ /// an {env_var_name}={value} or an {env_var_name} entry.
+ ///
+ /// @param[in] env_var_name
+ /// Specifies the name of the environment variable to check.
+ ///
+ /// @return
+ /// true if the specified env var name exists in the list in
+ /// either of the above-mentioned formats; otherwise, false.
+ //------------------------------------------------------------------
+ bool
+ ContainsEnvironmentVariable(const char *env_var_name) const;
+
protected:
//------------------------------------------------------------------
// Classes that inherit from Args can see and modify these
diff --git a/include/lldb/Interpreter/CommandAlias.h b/include/lldb/Interpreter/CommandAlias.h
new file mode 100644
index 000000000000..d48719f821ec
--- /dev/null
+++ b/include/lldb/Interpreter/CommandAlias.h
@@ -0,0 +1,123 @@
+//===-- CommandAlias.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_CommandAlias_h_
+#define liblldb_CommandAlias_h_
+
+// C Includes
+// C++ Includes
+#include <memory>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-forward.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandObject.h"
+
+namespace lldb_private {
+class CommandAlias : public CommandObject
+{
+public:
+ typedef std::unique_ptr<CommandAlias> UniquePointer;
+
+ CommandAlias (CommandInterpreter &interpreter,
+ lldb::CommandObjectSP cmd_sp,
+ const char *options_args,
+ const char *name,
+ const char *help = nullptr,
+ const char *syntax = nullptr,
+ uint32_t flags = 0);
+
+ void
+ GetAliasExpansion (StreamString &help_string);
+
+ bool
+ IsValid ()
+ {
+ return m_underlying_command_sp && m_option_args_sp;
+ }
+
+ explicit operator bool ()
+ {
+ return IsValid();
+ }
+
+ bool
+ WantsRawCommandString() override;
+
+ bool
+ WantsCompletion() override;
+
+ int
+ HandleCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override;
+
+ int
+ 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) override;
+
+ Options*
+ GetOptions() override;
+
+ bool
+ IsAlias () override { return true; }
+
+ bool
+ IsDashDashCommand () override;
+
+ const char*
+ GetHelp () override;
+
+ const char*
+ GetHelpLong () override;
+
+ void
+ SetHelp (const char * str) override;
+
+ void
+ SetHelpLong (const char * str) override;
+
+ bool
+ Execute(const char *args_string, CommandReturnObject &result) override;
+
+ lldb::CommandObjectSP GetUnderlyingCommand() { return m_underlying_command_sp; }
+ OptionArgVectorSP GetOptionArguments() { return m_option_args_sp; }
+ const char* GetOptionString() { return m_option_string.c_str(); }
+
+ // this takes an alias - potentially nested (i.e. an alias to an alias)
+ // and expands it all the way to a non-alias command
+ std::pair<lldb::CommandObjectSP, OptionArgVectorSP>
+ Desugar ();
+
+protected:
+ bool
+ IsNestedAlias ();
+
+private:
+ lldb::CommandObjectSP m_underlying_command_sp;
+ std::string m_option_string;
+ OptionArgVectorSP m_option_args_sp ;
+ LazyBool m_is_dashdash_alias;
+ bool m_did_set_help : 1;
+ bool m_did_set_help_long : 1;
+};
+} // namespace lldb_private
+
+#endif // liblldb_CommandAlias_h_
diff --git a/include/lldb/Interpreter/CommandHistory.h b/include/lldb/Interpreter/CommandHistory.h
index db5db15fc1e5..ff05f6da6c32 100644
--- a/include/lldb/Interpreter/CommandHistory.h
+++ b/include/lldb/Interpreter/CommandHistory.h
@@ -12,6 +12,7 @@
// C Includes
// C++ Includes
+#include <mutex>
#include <string>
#include <vector>
@@ -19,7 +20,6 @@
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Core/Stream.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -66,7 +66,7 @@ private:
DISALLOW_COPY_AND_ASSIGN(CommandHistory);
typedef std::vector<std::string> History;
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
History m_history;
};
diff --git a/include/lldb/Interpreter/CommandInterpreter.h b/include/lldb/Interpreter/CommandInterpreter.h
index dd5c189d0ab9..4dc2c5859f45 100644
--- a/include/lldb/Interpreter/CommandInterpreter.h
+++ b/include/lldb/Interpreter/CommandInterpreter.h
@@ -20,6 +20,7 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Core/Log.h"
+#include "lldb/Interpreter/CommandAlias.h"
#include "lldb/Interpreter/CommandHistory.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
@@ -200,8 +201,6 @@ class CommandInterpreter :
public IOHandlerDelegate
{
public:
- typedef std::map<std::string, OptionArgVectorSP> OptionArgMap;
-
enum
{
eBroadcastBitThreadShouldExit = (1 << 0),
@@ -277,10 +276,11 @@ public:
bool
UserCommandExists (const char *cmd);
- void
- AddAlias (const char *alias_name,
- lldb::CommandObjectSP& command_obj_sp);
-
+ CommandAlias*
+ AddAlias (const char *alias_name,
+ lldb::CommandObjectSP& command_obj_sp,
+ const char *args_string = nullptr);
+
// Remove a command if it is removable (python or regex command)
bool
RemoveCommand (const char *cmd);
@@ -300,20 +300,8 @@ public:
m_user_dict.clear();
}
- OptionArgVectorSP
- GetAliasOptions (const char *alias_name);
-
- bool
- ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp,
- const char *options_args,
- OptionArgVectorSP &option_arg_vector_sp);
-
- void
- RemoveAliasOptions (const char *alias_name);
-
- void
- AddOrReplaceAliasOptions (const char *alias_name,
- OptionArgVectorSP &option_arg_vector_sp);
+ CommandAlias*
+ GetAlias (const char *alias_name);
CommandObject *
BuildAliasResult (const char *alias_name,
@@ -422,7 +410,6 @@ public:
void
GetAliasHelp (const char *alias_name,
- const char *command_name,
StreamString &help_string);
void
@@ -533,15 +520,13 @@ public:
bool
GetSynchronous ();
- size_t
- FindLongestCommandWord (CommandObject::CommandMap &dict);
-
void
FindCommandsForApropos (const char *word,
StringList &commands_found,
StringList &commands_help,
bool search_builtin_commands,
- bool search_user_commands);
+ bool search_user_commands,
+ bool search_alias_commands);
bool
GetBatchCommandMode () { return m_batch_command_mode; }
@@ -694,6 +679,12 @@ private:
CommandObject *
ResolveCommandImpl(std::string &command_line, CommandReturnObject &result);
+ void
+ FindCommandsForApropos (const char *word,
+ StringList &commands_found,
+ StringList &commands_help,
+ CommandObject::CommandMap &command_map);
+
Debugger &m_debugger; // The debugger session that this interpreter is associated with
ExecutionContextRef m_exe_ctx_ref; // The current execution context to use when handling commands
bool m_synchronous_execution;
@@ -702,7 +693,6 @@ private:
CommandObject::CommandMap m_command_dict; // Stores basic built-in commands (they cannot be deleted, removed or overwritten).
CommandObject::CommandMap m_alias_dict; // Stores user aliases/abbreviations for commands
CommandObject::CommandMap m_user_dict; // Stores user-defined commands
- OptionArgMap m_alias_options; // Stores any options (with or without arguments) that go with any alias.
CommandHistory m_command_history;
std::string m_repeat_command; // Stores the command that will be executed for an empty command string.
lldb::ScriptInterpreterSP m_script_interpreter_sp;
diff --git a/include/lldb/Interpreter/CommandObject.h b/include/lldb/Interpreter/CommandObject.h
index 8015fec41cd2..b5d39ce83257 100644
--- a/include/lldb/Interpreter/CommandObject.h
+++ b/include/lldb/Interpreter/CommandObject.h
@@ -23,11 +23,54 @@
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Core/StringList.h"
#include "lldb/Core/Flags.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/ExecutionContext.h"
namespace lldb_private {
+// This function really deals with CommandObjectLists, but we didn't make a
+// CommandObjectList class, so I'm sticking it here. But we really should have
+// such a class. Anyway, it looks up the commands in the map that match the partial
+// string cmd_str, inserts the matches into matches, and returns the number added.
+
+template <typename ValueType>
+int
+AddNamesMatchingPartialString (std::map<std::string,ValueType> &in_map, const char *cmd_str, StringList &matches)
+{
+ int number_added = 0;
+
+ const bool add_all = ((cmd_str == nullptr) || (cmd_str[0] == 0));
+
+ for (auto iter = in_map.begin(), end = in_map.end();
+ iter != end;
+ iter++)
+ {
+ if (add_all ||
+ (iter->first.find(cmd_str,0) == 0))
+ {
+ ++number_added;
+ matches.AppendString(iter->first.c_str());
+ }
+ }
+
+ return number_added;
+}
+
+template <typename ValueType>
+size_t
+FindLongestCommandWord (std::map<std::string,ValueType> &dict)
+{
+ auto end = dict.end();
+ size_t max_len = 0;
+
+ for (auto pos = dict.begin(); pos != end; ++pos)
+ {
+ size_t len = pos->first.size();
+ if (max_len < len)
+ max_len = len;
+ }
+ return max_len;
+}
+
class CommandObject
{
public:
@@ -104,25 +147,19 @@ public:
virtual const char *
GetHelpLong ();
- const char *
+ virtual const char *
GetSyntax ();
const char *
GetCommandName ();
- void
+ virtual void
SetHelp (const char * str);
- void
- SetHelp (std::string str);
-
- void
+ virtual void
SetHelpLong (const char * str);
void
- SetHelpLong (std::string str);
-
- void
SetSyntax (const char *str);
// override this to return true if you want to enable the user to delete
@@ -131,14 +168,20 @@ public:
virtual bool
IsRemovable () const { return false; }
- bool
- IsAlias () { return m_is_alias; }
+ virtual bool
+ IsMultiwordObject () { return false; }
- void
- SetIsAlias (bool value) { m_is_alias = value; }
+ virtual CommandObjectMultiword*
+ GetAsMultiwordCommand () { return nullptr; }
virtual bool
- IsMultiwordObject () { return false; }
+ IsAlias () { return false; }
+
+ // override this to return true if your command is somehow a "dash-dash"
+ // form of some other command (e.g. po is expr -O --); this is a powerful
+ // hint to the help system that one cannot pass options to this command
+ virtual bool
+ IsDashDashCommand () { return false; }
virtual lldb::CommandObjectSP
GetSubcommandSP(const char *sub_cmd, StringList *matches = nullptr)
@@ -230,14 +273,6 @@ public:
void
SetCommandName (const char *name);
- // This function really deals with CommandObjectLists, but we didn't make a
- // CommandObjectList class, so I'm sticking it here. But we really should have
- // such a class. Anyway, it looks up the commands in the map that match the partial
- // string cmd_str, inserts the matches into matches, and returns the number added.
-
- static int
- AddNamesMatchingPartialString (CommandMap &in_map, const char *cmd_str, StringList &matches);
-
//------------------------------------------------------------------
/// The input array contains a parsed version of the line. The insertion
/// point is given by cursor_index (the index in input of the word containing
@@ -340,7 +375,11 @@ public:
}
bool
- HelpTextContainsWord (const char *search_word);
+ HelpTextContainsWord (const char *search_word,
+ bool search_short_help = true,
+ bool search_long_help = true,
+ bool search_syntax = true,
+ bool search_options = true);
//------------------------------------------------------------------
/// The flags accessor.
@@ -451,6 +490,12 @@ protected:
// is present you want to prime the dummy target with entities that will be copied over to new targets.
Target *GetSelectedOrDummyTarget(bool prefer_dummy = false);
Target *GetDummyTarget();
+
+ // If a command needs to use the "current" thread, use this call.
+ // Command objects will have an ExecutionContext to use, and that may or may not have a thread in it. If it
+ // does, you should use that by default, if not, then use the ExecutionContext's target's selected thread, etc...
+ // This call insulates you from the details of this calculation.
+ Thread *GetDefaultThread();
//------------------------------------------------------------------
/// Check the command to make sure anything required by this
@@ -471,12 +516,11 @@ protected:
CommandInterpreter &m_interpreter;
ExecutionContext m_exe_ctx;
- Mutex::Locker m_api_locker;
+ std::unique_lock<std::recursive_mutex> m_api_locker;
std::string m_cmd_name;
std::string m_cmd_help_short;
std::string m_cmd_help_long;
std::string m_cmd_syntax;
- bool m_is_alias;
Flags m_flags;
std::vector<CommandArgumentEntry> m_arguments;
lldb::CommandOverrideCallback m_deprecated_command_override_callback;
diff --git a/include/lldb/Interpreter/CommandObjectMultiword.h b/include/lldb/Interpreter/CommandObjectMultiword.h
index e1ad2940c383..3b7d1868a855 100644
--- a/include/lldb/Interpreter/CommandObjectMultiword.h
+++ b/include/lldb/Interpreter/CommandObjectMultiword.h
@@ -41,6 +41,12 @@ public:
{
return true;
}
+
+ CommandObjectMultiword*
+ GetAsMultiwordCommand () override
+ {
+ return this;
+ }
bool
LoadSubCommand(const char *cmd_name,
@@ -96,6 +102,11 @@ public:
}
protected:
+ CommandObject::CommandMap&
+ GetSubcommandDictionary ()
+ {
+ return m_subcommand_dict;
+ }
CommandObject::CommandMap m_subcommand_dict;
bool m_can_be_removed;
@@ -126,6 +137,9 @@ public:
bool
IsMultiwordObject() override;
+ CommandObjectMultiword*
+ GetAsMultiwordCommand () override;
+
void
GenerateHelpText (Stream &result) override;
diff --git a/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h b/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
index 53c8550da81e..86e4c1662e6e 100644
--- a/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
+++ b/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
@@ -77,6 +77,7 @@ public:
uint32_t no_summary_depth;
uint32_t max_depth;
uint32_t ptr_depth;
+ uint32_t elem_count;
lldb::DynamicValueType use_dynamic;
};
diff --git a/include/lldb/Interpreter/ScriptInterpreter.h b/include/lldb/Interpreter/ScriptInterpreter.h
index eafc03a00cca..8cfb3cea44b6 100644
--- a/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/include/lldb/Interpreter/ScriptInterpreter.h
@@ -380,6 +380,12 @@ public:
{
return nullptr;
}
+
+ virtual ConstString
+ GetSyntheticTypeName (const StructuredData::ObjectSP &implementor)
+ {
+ return ConstString();
+ }
virtual bool
RunScriptBasedCommand (const char* impl_function,
diff --git a/include/lldb/Makefile b/include/lldb/Makefile
deleted file mode 100644
index 6066298fce4a..000000000000
--- a/include/lldb/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-LEVEL = ../../../..
-DIRS :=
-
-include $(LEVEL)/Makefile.common
-
-install-local::
- $(Echo) Installing LLDB include files
- $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir)
- $(Verb) if test -d "$(PROJ_SRC_ROOT)/tools/lldb/include/lldb" ; then \
- cd $(PROJ_SRC_ROOT)/tools/lldb/include && \
- for hdr in `find lldb -type f '!' '(' -name '*~' \
- -o -name '.#*' -o -name '*.in' -o -name '*.txt' \
- -o -name 'Makefile' -o -name '*.td' -o -name '*.orig' ')' -print \
- | grep -v CVS | grep -v .svn | grep -v .dir` ; do \
- instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \
- if test \! -d "$$instdir" ; then \
- $(EchoCmd) Making install directory $$instdir ; \
- $(MKDIR) $$instdir ;\
- fi ; \
- $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
- done ; \
- fi
-ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
- $(Verb) if test -d "$(PROJ_OBJ_ROOT)/tools/lldb/include/lldb" ; then \
- cd $(PROJ_OBJ_ROOT)/tools/lldb/include && \
- for hdr in `find lldb -type f '!' '(' -name 'Makefile' ')' -print \
- | grep -v CVS | grep -v .tmp | grep -v .dir` ; do \
- $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
- done ; \
- fi
-endif
diff --git a/include/lldb/Symbol/ArmUnwindInfo.h b/include/lldb/Symbol/ArmUnwindInfo.h
index b19af23744a4..8c40f19d2859 100644
--- a/include/lldb/Symbol/ArmUnwindInfo.h
+++ b/include/lldb/Symbol/ArmUnwindInfo.h
@@ -14,7 +14,6 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RangeMap.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/lldb-private.h"
diff --git a/include/lldb/Symbol/Block.h b/include/lldb/Symbol/Block.h
index 6c0793dda80f..6dbb9c56097b 100644
--- a/include/lldb/Symbol/Block.h
+++ b/include/lldb/Symbol/Block.h
@@ -310,8 +310,9 @@ public:
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);
-
+
//------------------------------------------------------------------
/// Appends the variables from this block, and optionally from all
/// parent blocks, to \a variable_list.
@@ -341,9 +342,10 @@ public:
/// variable_list.
//------------------------------------------------------------------
uint32_t
- AppendVariables (bool can_create,
- bool get_parent_variables,
+ AppendVariables (bool can_create,
+ bool get_parent_variables,
bool stop_if_block_is_inlined_function,
+ const std::function<bool(Variable*)>& filter,
VariableList *variable_list);
//------------------------------------------------------------------
diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h
index bd3a113e6cc5..08f7b6b412dc 100644
--- a/include/lldb/Symbol/ClangASTContext.h
+++ b/include/lldb/Symbol/ClangASTContext.h
@@ -30,11 +30,14 @@
// Project includes
#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
-#include "lldb/lldb-enumerations.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/TypeSystem.h"
+#include "lldb/lldb-enumerations.h"
+
+class DWARFASTParserClang;
+class PDBASTParser;
namespace lldb_private {
@@ -61,6 +64,9 @@ public:
~ClangASTContext() override;
+ void
+ Finalize() override;
+
//------------------------------------------------------------------
// PluginInterface functions
//------------------------------------------------------------------
@@ -127,7 +133,7 @@ public:
void
Clear();
-
+
const char *
GetTargetTriple ();
@@ -297,6 +303,11 @@ public:
}
CompilerType
+ CreateStructForIdentifier (const ConstString &type_name,
+ const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
+ bool packed = false);
+
+ CompilerType
GetOrCreateStructForIdentifier (const ConstString &type_name,
const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
bool packed = false);
@@ -422,6 +433,11 @@ public:
GetUniqueNamespaceDeclaration (const char *name,
clang::DeclContext *decl_ctx);
+ static clang::NamespaceDecl *
+ GetUniqueNamespaceDeclaration (clang::ASTContext *ast,
+ const char *name,
+ clang::DeclContext *decl_ctx);
+
//------------------------------------------------------------------
// Function Types
//------------------------------------------------------------------
@@ -465,6 +481,9 @@ public:
SetFunctionParameters (clang::FunctionDecl *function_decl,
clang::ParmVarDecl **params,
unsigned num_params);
+
+ CompilerType
+ CreateBlockPointerType (const CompilerType &function_type);
//------------------------------------------------------------------
// Array Types
@@ -513,7 +532,9 @@ public:
// TypeSystem methods
//------------------------------------------------------------------
DWARFASTParser *
- GetDWARFParser () override;
+ GetDWARFParser() override;
+ PDBASTParser *
+ GetPDBParser();
//------------------------------------------------------------------
// ClangASTContext callbacks for external source lookups.
@@ -536,12 +557,6 @@ public:
//----------------------------------------------------------------------
// CompilerDecl override functions
//----------------------------------------------------------------------
- lldb::VariableSP
- DeclGetVariable (void *opaque_decl) override;
-
- void
- DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object) override;
-
ConstString
DeclGetName (void *opaque_decl) override;
@@ -565,7 +580,9 @@ public:
//----------------------------------------------------------------------
std::vector<CompilerDecl>
- DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name) override;
+ DeclContextFindDeclByName (void *opaque_decl_ctx,
+ ConstString name,
+ const bool ignore_using_decls) override;
bool
DeclContextIsStructUnionOrClass (void *opaque_decl_ctx) override;
@@ -583,16 +600,6 @@ public:
ConstString *language_object_name_ptr) override;
//----------------------------------------------------------------------
- // Clang specific CompilerType predicates
- //----------------------------------------------------------------------
-
- static bool
- IsClangType (const CompilerType &ct)
- {
- return llvm::dyn_cast_or_null<ClangASTContext>(ct.GetTypeSystem()) != nullptr && ct.GetOpaqueQualType() != nullptr;
- }
-
- //----------------------------------------------------------------------
// Clang specific clang::DeclContext functions
//----------------------------------------------------------------------
@@ -678,8 +685,14 @@ public:
IsFunctionPointerType (lldb::opaque_compiler_type_t type) override;
bool
- IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) override;
+ IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override;
+ bool
+ IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) override;
+
+ bool
+ IsEnumerationType (lldb::opaque_compiler_type_t type, bool &is_signed) override;
+
static bool
IsObjCClassType (const CompilerType& type);
@@ -694,7 +707,13 @@ public:
bool
IsPolymorphicClass (lldb::opaque_compiler_type_t type) override;
-
+
+ static bool
+ IsClassType(lldb::opaque_compiler_type_t type);
+
+ static bool
+ IsEnumType(lldb::opaque_compiler_type_t type);
+
bool
IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
CompilerType *target_type, // Can pass nullptr
@@ -824,9 +843,6 @@ public:
// If the current object represents a typedef type, get the underlying type
CompilerType
GetTypedefedType (lldb::opaque_compiler_type_t type) override;
-
- static CompilerType
- RemoveFastQualifiers (const CompilerType& type);
//----------------------------------------------------------------------
// Create related types using the current type's AST
@@ -1025,18 +1041,12 @@ public:
const char *name, // the full symbol name as seen in the symbol table (lldb::opaque_compiler_type_t type, "-[NString stringWithCString:]")
const CompilerType &method_compiler_type,
lldb::AccessType access,
- bool is_artificial);
+ bool is_artificial,
+ bool is_variadic);
static bool
SetHasExternalStorage (lldb::opaque_compiler_type_t type, bool has_extern);
-
- static bool
- CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer);
-
- static bool
- Import (const CompilerType &type, lldb_private::ClangASTImporter &importer);
-
static bool
GetHasExternalStorage (const CompilerType &type);
//------------------------------------------------------------------
@@ -1139,29 +1149,6 @@ public:
static clang::ObjCInterfaceDecl *
GetAsObjCInterfaceDecl (const CompilerType& type);
-
- static clang::QualType
- GetQualType (const CompilerType& type)
- {
- // Make sure we have a clang type before making a clang::QualType
- if (type.GetOpaqueQualType())
- {
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
- if (ast)
- return clang::QualType::getFromOpaquePtr(type.GetOpaqueQualType());
- }
- return clang::QualType();
- }
-
- static clang::QualType
- GetCanonicalQualType (const CompilerType& type)
- {
- // Make sure we have a clang type before making a clang::QualType
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
- if (ast)
- return clang::QualType::getFromOpaquePtr(type.GetOpaqueQualType()).getCanonicalType();
- return clang::QualType();
- }
clang::ClassTemplateDecl *
ParseClassTemplateDecl (clang::DeclContext *decl_ctx,
@@ -1182,26 +1169,30 @@ public:
clang::VarDecl *
CreateVariableDeclaration (clang::DeclContext *decl_context, const char *name, clang::QualType type);
-protected:
+ static lldb::opaque_compiler_type_t
+ GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type);
+
static clang::QualType
- GetQualType (lldb::opaque_compiler_type_t type)
+ GetQualType(lldb::opaque_compiler_type_t type)
{
if (type)
return clang::QualType::getFromOpaquePtr(type);
return clang::QualType();
}
-
+
static clang::QualType
- GetCanonicalQualType (lldb::opaque_compiler_type_t type)
+ GetCanonicalQualType(lldb::opaque_compiler_type_t type)
{
if (type)
return clang::QualType::getFromOpaquePtr(type).getCanonicalType();
return clang::QualType();
}
+protected:
//------------------------------------------------------------------
// Classes that inherit from ClangASTContext can see and modify these
//------------------------------------------------------------------
+ // clang-format off
std::string m_target_triple;
std::unique_ptr<clang::ASTContext> m_ast_ap;
std::unique_ptr<clang::LangOptions> m_language_options_ap;
@@ -1215,7 +1206,8 @@ protected:
std::unique_ptr<clang::IdentifierTable> m_identifier_table_ap;
std::unique_ptr<clang::SelectorTable> m_selector_table_ap;
std::unique_ptr<clang::Builtin::Context> m_builtins_ap;
- std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap;
+ std::unique_ptr<DWARFASTParserClang> m_dwarf_ast_parser_ap;
+ std::unique_ptr<PDBASTParser> m_pdb_ast_parser_ap;
std::unique_ptr<ClangASTSource> m_scratch_ast_source_ap;
std::unique_ptr<clang::MangleContext> m_mangle_ctx_ap;
CompleteTagDeclCallback m_callback_tag_decl;
@@ -1224,8 +1216,7 @@ protected:
uint32_t m_pointer_byte_size;
bool m_ast_owned;
bool m_can_evaluate_expressions;
- std::map<void *, std::shared_ptr<void>> m_decl_objects;
-
+ // clang-format on
private:
//------------------------------------------------------------------
// For ClangASTContext only
diff --git a/include/lldb/Symbol/ClangASTImporter.h b/include/lldb/Symbol/ClangASTImporter.h
index 8c3f8735c2e1..0ea7308d9541 100644
--- a/include/lldb/Symbol/ClangASTImporter.h
+++ b/include/lldb/Symbol/ClangASTImporter.h
@@ -19,6 +19,9 @@
// Other libraries and framework includes
#include "clang/AST/ASTImporter.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
@@ -26,6 +29,8 @@
#include "lldb/lldb-types.h"
#include "lldb/Symbol/CompilerDeclContext.h"
+#include "llvm/ADT/DenseMap.h"
+
namespace lldb_private {
class ClangASTMetrics
@@ -93,6 +98,16 @@ private:
class ClangASTImporter
{
public:
+ 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;
+ };
+
ClangASTImporter () :
m_file_manager(clang::FileSystemOptions())
{
@@ -126,10 +141,28 @@ public:
DeportDecl (clang::ASTContext *dst_ctx,
clang::ASTContext *src_ctx,
clang::Decl *decl);
-
+
void
- CompleteDecl (clang::Decl *decl);
-
+ InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout);
+
+ 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);
+
+ bool
+ CanImport(const CompilerType &type);
+
+ bool
+ Import(const CompilerType &type);
+
+ bool
+ CompleteType(const CompilerType &compiler_type);
+
+ void
+ CompleteDecl(clang::Decl *decl);
+
bool
CompleteTagDecl (clang::TagDecl *decl);
@@ -381,6 +414,9 @@ private:
GetDeclOrigin (const clang::Decl *decl);
clang::FileManager m_file_manager;
+ typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo> RecordDeclToLayoutMap;
+
+ RecordDeclToLayoutMap m_record_decl_to_layout_map;
};
} // namespace lldb_private
diff --git a/include/lldb/Symbol/ClangUtil.h b/include/lldb/Symbol/ClangUtil.h
new file mode 100644
index 000000000000..ee9ff5678d79
--- /dev/null
+++ b/include/lldb/Symbol/ClangUtil.h
@@ -0,0 +1,37 @@
+//===-- ClangUtil.h ---------------------------------------------*- 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.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SYMBOL_CLANGUTIL_H
+#define LLDB_SYMBOL_CLANGUTIL_H
+
+#include "clang/AST/Type.h"
+
+#include "lldb/Symbol/CompilerType.h"
+
+namespace lldb_private
+{
+struct ClangUtil
+{
+ static bool
+ IsClangType(const CompilerType &ct);
+
+ static clang::QualType
+ GetQualType(const CompilerType &ct);
+
+ static clang::QualType
+ GetCanonicalQualType(const CompilerType &ct);
+
+ static CompilerType
+ RemoveFastQualifiers(const CompilerType &ct);
+};
+}
+
+#endif
diff --git a/include/lldb/Symbol/CompactUnwindInfo.h b/include/lldb/Symbol/CompactUnwindInfo.h
index 239eb3ac77ad..6bf65a223471 100644
--- a/include/lldb/Symbol/CompactUnwindInfo.h
+++ b/include/lldb/Symbol/CompactUnwindInfo.h
@@ -10,11 +10,11 @@
#ifndef liblldb_CompactUnwindInfo_h_
#define liblldb_CompactUnwindInfo_h_
+#include <mutex>
#include <vector>
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RangeMap.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/lldb-private.h"
@@ -133,11 +133,17 @@ private:
bool
CreateUnwindPlan_i386 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start);
+ bool
+ CreateUnwindPlan_arm64 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start);
+
+ bool
+ CreateUnwindPlan_armv7 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start);
+
ObjectFile &m_objfile;
lldb::SectionSP m_section_sp;
lldb::DataBufferSP m_section_contents_if_encrypted; // if the binary is encrypted, read the sect contents
// out of live memory and cache them here
- Mutex m_mutex;
+ std::mutex m_mutex;
std::vector<UnwindIndex> m_indexes;
LazyBool m_indexes_computed; // eLazyBoolYes once we've tried to parse the unwind info
diff --git a/include/lldb/Symbol/CompileUnit.h b/include/lldb/Symbol/CompileUnit.h
index 0c331c38f8c6..2f596f89ec5f 100644
--- a/include/lldb/Symbol/CompileUnit.h
+++ b/include/lldb/Symbol/CompileUnit.h
@@ -68,11 +68,16 @@ public:
/// of this compile unit.
///
/// @param[in] is_optimized
- /// true if this compile unit was compiled with optimization.
+ /// A value that can initialized with eLazyBoolYes, eLazyBoolNo
+ /// or eLazyBoolCalculate. If set to eLazyBoolCalculate, then
+ /// an extra call into SymbolVendor will be made to calculate if
+ /// the compile unit is optimized will be made when
+ /// CompileUnit::GetIsOptimized() is called.
///
/// @see lldb::LanguageType
//------------------------------------------------------------------
- CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, lldb::user_id_t uid, lldb::LanguageType language, bool is_optimized);
+ CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, lldb::user_id_t uid,
+ lldb::LanguageType language, lldb_private::LazyBool is_optimized);
//------------------------------------------------------------------
/// Construct with a module, file spec, UID and language.
@@ -103,11 +108,16 @@ public:
/// of this compile unit.
///
/// @param[in] is_optimized
- /// true if this compile unit was compiled with optimization.
+ /// A value that can initialized with eLazyBoolYes, eLazyBoolNo
+ /// or eLazyBoolCalculate. If set to eLazyBoolCalculate, then
+ /// an extra call into SymbolVendor will be made to calculate if
+ /// the compile unit is optimized will be made when
+ /// CompileUnit::GetIsOptimized() is called.
///
/// @see lldb::LanguageType
//------------------------------------------------------------------
- CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, lldb::LanguageType language, bool is_optimized);
+ CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid,
+ lldb::LanguageType language, lldb_private::LazyBool is_optimized);
//------------------------------------------------------------------
/// Destructor
@@ -446,7 +456,7 @@ protected:
std::unique_ptr<LineTable> m_line_table_ap; ///< Line table that will get parsed on demand.
DebugMacrosSP m_debug_macros_sp; ///< Debug macros that will get parsed on demand.
lldb::VariableListSP m_variables; ///< Global and static variable list that will get parsed on demand.
- bool m_is_optimized; /// eLazyBoolYes if this compile unit was compiled with optimization.
+ lldb_private::LazyBool m_is_optimized; /// eLazyBoolYes if this compile unit was compiled with optimization.
private:
enum
diff --git a/include/lldb/Symbol/CompilerDecl.h b/include/lldb/Symbol/CompilerDecl.h
index b749e79b459a..19654ab165bb 100644
--- a/include/lldb/Symbol/CompilerDecl.h
+++ b/include/lldb/Symbol/CompilerDecl.h
@@ -65,12 +65,6 @@ public:
IsClang () const;
//----------------------------------------------------------------------
- // Object linked to the decl
- //----------------------------------------------------------------------
- lldb::VariableSP
- GetAsVariable ();
-
- //----------------------------------------------------------------------
// Accessors
//----------------------------------------------------------------------
diff --git a/include/lldb/Symbol/CompilerDeclContext.h b/include/lldb/Symbol/CompilerDeclContext.h
index 9135b44323b5..7432adac6133 100644
--- a/include/lldb/Symbol/CompilerDeclContext.h
+++ b/include/lldb/Symbol/CompilerDeclContext.h
@@ -66,7 +66,7 @@ public:
IsClang () const;
std::vector<CompilerDecl>
- FindDeclByName (ConstString name);
+ FindDeclByName (ConstString name, const bool ignore_using_decls);
//----------------------------------------------------------------------
/// Checks if this decl context represents a method of a class.
diff --git a/include/lldb/Symbol/CompilerType.h b/include/lldb/Symbol/CompilerType.h
index 4f3ecc54ba1a..36f6ef3ba6eb 100644
--- a/include/lldb/Symbol/CompilerType.h
+++ b/include/lldb/Symbol/CompilerType.h
@@ -149,9 +149,18 @@ public:
IsFunctionPointerType () const;
bool
- IsIntegerType (bool &is_signed) const;
+ IsBlockPointerType (CompilerType *function_pointer_type_ptr) const;
bool
+ IsIntegerType (bool &is_signed) const;
+
+ bool
+ IsEnumerationType (bool &is_signed) const;
+
+ bool
+ IsIntegerOrEnumerationType (bool &is_signed) const;
+
+ bool
IsPolymorphicClass () const;
bool
diff --git a/include/lldb/Symbol/DWARFCallFrameInfo.h b/include/lldb/Symbol/DWARFCallFrameInfo.h
index cc497c039a4e..da7f87ced0a0 100644
--- a/include/lldb/Symbol/DWARFCallFrameInfo.h
+++ b/include/lldb/Symbol/DWARFCallFrameInfo.h
@@ -11,6 +11,7 @@
#define liblldb_DWARFCallFrameInfo_h_
#include <map>
+#include <mutex>
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/DataExtractor.h"
@@ -18,7 +19,6 @@
#include "lldb/Core/RangeMap.h"
#include "lldb/Core/VMRange.h"
#include "lldb/Core/dwarf.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/lldb-private.h"
@@ -73,6 +73,9 @@ public:
void
GetFunctionAddressAndSizeVector (FunctionAddressAndSizeVector &function_info);
+ void
+ ForEachFDEEntries(const std::function<bool(lldb::addr_t, uint32_t, dw_offset_t)>& callback);
+
private:
enum
{
@@ -152,7 +155,7 @@ private:
FDEEntryMap m_fde_index;
bool m_fde_index_initialized; // only scan the section for FDEs once
- Mutex m_fde_index_mutex; // and isolate the thread that does it
+ std::mutex m_fde_index_mutex; // and isolate the thread that does it
bool m_is_eh_frame;
diff --git a/include/lldb/Symbol/FuncUnwinders.h b/include/lldb/Symbol/FuncUnwinders.h
index 728b4c6fcb32..6d5991cc2b33 100644
--- a/include/lldb/Symbol/FuncUnwinders.h
+++ b/include/lldb/Symbol/FuncUnwinders.h
@@ -1,12 +1,12 @@
#ifndef liblldb_FuncUnwinders_h
#define liblldb_FuncUnwinders_h
+#include <mutex>
#include <vector>
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/AddressRange.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -116,10 +116,18 @@ private:
lldb::UnwindAssemblySP
GetUnwindAssemblyProfiler (Target& target);
+ // Do a simplistic comparison for the register restore rule for getting
+ // the caller's pc value on two UnwindPlans -- returns LazyBoolYes if
+ // they have the same unwind rule for the pc, LazyBoolNo if they do not
+ // have the same unwind rule for the pc, and LazyBoolCalculate if it was
+ // unable to determine this for some reason.
+ lldb_private::LazyBool
+ CompareUnwindPlansForIdenticalInitialPCLocation (Thread& thread, const lldb::UnwindPlanSP &a, const lldb::UnwindPlanSP &b);
+
UnwindTable& m_unwind_table;
AddressRange m_range;
- Mutex m_mutex;
+ std::recursive_mutex m_mutex;
lldb::UnwindPlanSP m_unwind_plan_assembly_sp;
lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp;
diff --git a/include/lldb/Symbol/Function.h b/include/lldb/Symbol/Function.h
index cd2df9b6078f..9892d620ce47 100644
--- a/include/lldb/Symbol/Function.h
+++ b/include/lldb/Symbol/Function.h
@@ -574,6 +574,14 @@ public:
CompilerType
GetCompilerType ();
+ //------------------------------------------------------------------
+ /// Get the size of the prologue instructions for this function. The "prologue"
+ /// instructions include any instructions given line number 0 immediately following
+ /// the prologue end.
+ ///
+ /// @return
+ /// The size of the prologue.
+ //------------------------------------------------------------------
uint32_t
GetPrologueByteSize ();
diff --git a/include/lldb/Symbol/GoASTContext.h b/include/lldb/Symbol/GoASTContext.h
index 09d79bacc585..ec0203bc3221 100644
--- a/include/lldb/Symbol/GoASTContext.h
+++ b/include/lldb/Symbol/GoASTContext.h
@@ -85,17 +85,6 @@ class GoASTContext : public TypeSystem
return ConstString();
}
- lldb::VariableSP
- DeclGetVariable (void *opaque_decl) override
- {
- return lldb::VariableSP();
- }
-
- void
- DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object) override
- {
- }
-
//----------------------------------------------------------------------
// CompilerDeclContext functions
//----------------------------------------------------------------------
@@ -176,6 +165,8 @@ class GoASTContext : public TypeSystem
CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index) override;
bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override;
+
+ bool IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override;
bool IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed) override;
diff --git a/include/lldb/Symbol/JavaASTContext.h b/include/lldb/Symbol/JavaASTContext.h
new file mode 100644
index 000000000000..7d5a37649f6f
--- /dev/null
+++ b/include/lldb/Symbol/JavaASTContext.h
@@ -0,0 +1,385 @@
+//===-- JavaASTContext.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_JavaASTContext_h_
+#define liblldb_JavaASTContext_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <memory>
+#include <set>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/Symbol/TypeSystem.h"
+
+namespace lldb_private
+{
+
+class JavaASTContext : public TypeSystem
+{
+public:
+ class JavaType;
+ typedef std::map<ConstString, std::unique_ptr<JavaType>> JavaTypeMap;
+
+ JavaASTContext(const ArchSpec &arch);
+ ~JavaASTContext() override;
+
+ //------------------------------------------------------------------
+ // PluginInterface functions
+ //------------------------------------------------------------------
+ ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
+
+ static ConstString
+ GetPluginNameStatic();
+
+ static lldb::TypeSystemSP
+ CreateInstance(lldb::LanguageType language, Module *module, Target *target);
+
+ static void
+ EnumerateSupportedLanguages(std::set<lldb::LanguageType> &languages_for_types,
+ std::set<lldb::LanguageType> &languages_for_expressions);
+
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ DWARFASTParser *
+ GetDWARFParser() override;
+
+ uint32_t
+ GetPointerByteSize() override;
+
+ //----------------------------------------------------------------------
+ // CompilerDecl functions
+ //----------------------------------------------------------------------
+ ConstString
+ DeclGetName(void *opaque_decl) override;
+
+ //----------------------------------------------------------------------
+ // CompilerDeclContext functions
+ //----------------------------------------------------------------------
+
+ std::vector<CompilerDecl>
+ DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, const bool ignore_imported_decls) override;
+
+ bool
+ DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override;
+
+ ConstString
+ DeclContextGetName(void *opaque_decl_ctx) override;
+
+ bool
+ DeclContextIsClassMethod(void *opaque_decl_ctx, lldb::LanguageType *language_ptr, bool *is_instance_method_ptr,
+ ConstString *language_object_name_ptr) override;
+
+ //----------------------------------------------------------------------
+ // Tests
+ //----------------------------------------------------------------------
+
+ bool
+ IsArrayType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size,
+ bool *is_incomplete) override;
+
+ bool
+ IsAggregateType(lldb::opaque_compiler_type_t type) override;
+
+ bool
+ IsCharType(lldb::opaque_compiler_type_t type) override;
+
+ bool
+ IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex) override;
+
+ bool
+ IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr = nullptr) override;
+
+ size_t
+ GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index) override;
+
+ bool
+ IsFunctionPointerType(lldb::opaque_compiler_type_t type) override;
+
+ bool
+ IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override;
+
+ bool
+ IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed) override;
+
+ bool
+ IsPossibleDynamicType(lldb::opaque_compiler_type_t type, CompilerType *target_type, bool check_cplusplus,
+ bool check_objc) override;
+
+ bool
+ IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr) override;
+
+ bool
+ IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr,
+ bool *is_rvalue = nullptr) override;
+
+ bool
+ IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr) override;
+
+ bool
+ IsScalarType(lldb::opaque_compiler_type_t type) override;
+
+ bool
+ IsVoidType(lldb::opaque_compiler_type_t type) override;
+
+ bool
+ IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length) override;
+
+ bool
+ IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override;
+
+ bool
+ IsTypedefType(lldb::opaque_compiler_type_t type) override;
+
+ bool
+ IsVectorType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size) override;
+
+ bool
+ IsPolymorphicClass(lldb::opaque_compiler_type_t type) override;
+
+ bool
+ IsCompleteType(lldb::opaque_compiler_type_t type) override;
+
+ bool
+ IsConst(lldb::opaque_compiler_type_t type) override;
+
+ bool
+ IsBeingDefined(lldb::opaque_compiler_type_t type) override;
+
+ bool
+ IsDefined(lldb::opaque_compiler_type_t type) override;
+
+ uint32_t
+ IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, CompilerType *base_type_ptr) override;
+
+ bool
+ SupportsLanguage(lldb::LanguageType language) override;
+
+ bool
+ GetCompleteType(lldb::opaque_compiler_type_t type) override;
+
+ ConstString
+ GetTypeName(lldb::opaque_compiler_type_t type) override;
+
+ uint32_t
+ GetTypeInfo(lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_compiler_type = nullptr) override;
+
+ lldb::TypeClass
+ GetTypeClass(lldb::opaque_compiler_type_t type) override;
+
+ lldb::LanguageType
+ GetMinimumLanguage(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride = nullptr) override;
+
+ CompilerType
+ GetPointeeType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetPointerType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetCanonicalType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetNonReferenceType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetTypedefedType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetBasicTypeFromAST(lldb::BasicType basic_type) override;
+
+ CompilerType
+ GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size) override;
+
+ size_t
+ GetTypeBitAlign(lldb::opaque_compiler_type_t type) override;
+
+ lldb::BasicType
+ GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override;
+
+ uint64_t
+ GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) override;
+
+ lldb::Encoding
+ GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count) override;
+
+ lldb::Format
+ GetFormat(lldb::opaque_compiler_type_t type) override;
+
+ unsigned
+ GetTypeQualifiers(lldb::opaque_compiler_type_t type) override;
+
+ size_t
+ GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, lldb::TemplateArgumentKind &kind) override;
+
+ int
+ GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override;
+
+ CompilerType
+ GetFunctionReturnType(lldb::opaque_compiler_type_t type) override;
+
+ size_t
+ GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override;
+
+ TypeMemberFunctionImpl
+ GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override;
+
+ uint32_t
+ GetNumFields(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ 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) override;
+
+ uint32_t
+ GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes) override;
+
+ uint32_t
+ GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override;
+
+ uint32_t
+ GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override;
+
+ CompilerType
+ GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override;
+
+ size_t
+ ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst, size_t dst_size) override;
+
+ void
+ DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format,
+ const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset, bool show_types, bool show_summary, bool verbose, uint32_t depth) override;
+
+ bool
+ DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, const DataExtractor &data,
+ lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) override;
+
+ void
+ DumpTypeDescription(lldb::opaque_compiler_type_t type) override;
+
+ void
+ DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s) override;
+
+ void
+ DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data,
+ lldb::offset_t data_offset, size_t data_byte_size) override;
+
+ CompilerType
+ 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) override;
+
+ uint32_t
+ GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes) override;
+
+ size_t
+ GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes,
+ std::vector<uint32_t> &child_indexes) override;
+
+ CompilerType
+ GetLValueReferenceType(lldb::opaque_compiler_type_t type) override;
+
+ ConstString
+ DeclContextGetScopeQualifiedName(lldb::opaque_compiler_type_t opaque_decl_ctx) override;
+
+ CompilerType
+ CreateBaseType(const ConstString &name);
+
+ CompilerType
+ CreateObjectType(const ConstString &name, const ConstString &linkage_name, uint32_t byte_size);
+
+ CompilerType
+ CreateArrayType(const ConstString &linkage_name, const CompilerType &element_type,
+ const DWARFExpression &length_expression, const lldb::addr_t data_offset);
+
+ CompilerType
+ CreateReferenceType(const CompilerType &pointee_type);
+
+ void
+ CompleteObjectType(const CompilerType &object_type);
+
+ void
+ AddBaseClassToObject(const CompilerType &object_type, const CompilerType &member_type, uint32_t member_offset);
+
+ void
+ AddMemberToObject(const CompilerType &object_type, const ConstString &name, const CompilerType &member_type,
+ uint32_t member_offset);
+
+ void
+ SetDynamicTypeId(const CompilerType &type, const DWARFExpression &type_id);
+
+ static uint64_t
+ CalculateDynamicTypeId(ExecutionContext *exe_ctx, const CompilerType &type, ValueObject &in_value);
+
+ static ConstString
+ GetLinkageName(const CompilerType &type);
+
+ static uint32_t
+ CalculateArraySize(const CompilerType &type, ValueObject &in_value);
+
+ static uint64_t
+ CalculateArrayElementOffset(const CompilerType &type, size_t index);
+
+ //------------------------------------------------------------------
+ // llvm casting support
+ //------------------------------------------------------------------
+ static bool
+ classof(const TypeSystem *ts)
+ {
+ return ts->getKind() == TypeSystem::eKindJava;
+ }
+
+private:
+ uint32_t m_pointer_byte_size;
+ std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap;
+ JavaTypeMap m_array_type_map;
+ JavaTypeMap m_base_type_map;
+ JavaTypeMap m_reference_type_map;
+ JavaTypeMap m_object_type_map;
+
+ JavaASTContext(const JavaASTContext &) = delete;
+ const JavaASTContext &
+ operator=(const JavaASTContext &) = delete;
+};
+}
+#endif // liblldb_JavaASTContext_h_
diff --git a/include/lldb/Symbol/LineEntry.h b/include/lldb/Symbol/LineEntry.h
index 374c04a7fcec..e6a05c10a764 100644
--- a/include/lldb/Symbol/LineEntry.h
+++ b/include/lldb/Symbol/LineEntry.h
@@ -168,10 +168,21 @@ struct LineEntry
GetSameLineContiguousAddressRange () const;
//------------------------------------------------------------------
+ /// Apply file mappings from target.source-map to the LineEntry's file.
+ ///
+ /// @param[in] target_sp
+ /// Shared pointer to the target this LineEntry belongs to.
+ //------------------------------------------------------------------
+
+ void
+ ApplyFileMappings(lldb::TargetSP target_sp);
+
+ //------------------------------------------------------------------
// Member variables.
//------------------------------------------------------------------
AddressRange range; ///< The section offset address range for this line entry.
- FileSpec file;
+ FileSpec file; ///< The source file, possibly mapped by the target.source-map setting
+ FileSpec original_file; ///< The original source file, from debug info.
uint32_t line; ///< The source line number, or zero if there is no line number information.
uint16_t column; ///< The column number of the source line, or zero if there is no column information.
uint16_t is_start_of_statement:1, ///< Indicates this entry is the beginning of a statement.
diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h
index 4b0a2f9ff936..53f0f3c80517 100644
--- a/include/lldb/Symbol/ObjectFile.h
+++ b/include/lldb/Symbol/ObjectFile.h
@@ -551,6 +551,35 @@ public:
GetUnwindTable () { return m_unwind_table; }
//------------------------------------------------------------------
+ /// Returns if the function bounds for symbols in this symbol file
+ /// are likely accurate.
+ ///
+ /// The unwinder can emulate the instructions of functions to understand
+ /// prologue/epilogue code sequences, where registers are spilled on
+ /// the stack, etc. This feature relies on having the correct start
+ /// addresses of all functions. If the ObjectFile has a way to tell
+ /// that symbols have been stripped and there's no way to reconstruct
+ /// start addresses (e.g. LC_FUNCTION_STARTS on Mach-O, or eh_frame
+ /// unwind info), the ObjectFile should indicate that assembly emulation
+ /// should not be used for this module.
+ ///
+ /// It is uncommon for this to return false. An ObjectFile needs to
+ /// be sure that symbol start addresses are unavailable before false
+ /// is returned. If it is unclear, this should return true.
+ ///
+ /// @return
+ /// Returns true if assembly emulation should be used for this
+ /// module.
+ /// Only returns false if the ObjectFile is sure that symbol
+ /// addresses are insufficient for accurate assembly emulation.
+ //------------------------------------------------------------------
+ virtual bool
+ AllowAssemblyEmulationUnwindPlans ()
+ {
+ return true;
+ }
+
+ //------------------------------------------------------------------
/// Similar to Process::GetImageInfoAddress().
///
/// Some platforms embed auxiliary structures useful to debuggers in the
@@ -860,6 +889,7 @@ protected:
const lldb::addr_t m_memory_addr;
std::unique_ptr<lldb_private::SectionList> m_sections_ap;
std::unique_ptr<lldb_private::Symtab> m_symtab_ap;
+ uint32_t m_synthetic_symbol_idx;
//------------------------------------------------------------------
/// Sets the architecture for a module. At present the architecture
@@ -873,7 +903,11 @@ protected:
/// Returns \b true if the architecture was changed, \b
/// false otherwise.
//------------------------------------------------------------------
- bool SetModulesArchitecture (const ArchSpec &new_arch);
+ bool
+ SetModulesArchitecture (const ArchSpec &new_arch);
+
+ ConstString
+ GetNextSyntheticSymbolName();
private:
DISALLOW_COPY_AND_ASSIGN (ObjectFile);
diff --git a/include/lldb/Symbol/Symbol.h b/include/lldb/Symbol/Symbol.h
index c77d3dea4bd2..43f29f368d92 100644
--- a/include/lldb/Symbol/Symbol.h
+++ b/include/lldb/Symbol/Symbol.h
@@ -383,6 +383,9 @@ public:
bool prefer_file_cache,
Stream &strm);
+ bool
+ ContainsFileAddress (lldb::addr_t file_addr) const;
+
protected:
// This is the internal guts of ResolveReExportedSymbol, it assumes reexport_name is not null, and that module_spec
// is valid. We track the modules we've already seen to make sure we don't get caught in a cycle.
diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h
index 9cb709d24011..f0e8e3590a8a 100644
--- a/include/lldb/Symbol/SymbolContext.h
+++ b/include/lldb/Symbol/SymbolContext.h
@@ -244,6 +244,9 @@ public:
uint32_t range_idx,
bool use_inline_block_range,
AddressRange &range) const;
+
+ bool
+ GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range, Error &error);
void
GetDescription(Stream *s,
diff --git a/include/lldb/Symbol/SymbolFile.h b/include/lldb/Symbol/SymbolFile.h
index fe74ad4f933e..db97ab4f9b65 100644
--- a/include/lldb/Symbol/SymbolFile.h
+++ b/include/lldb/Symbol/SymbolFile.h
@@ -17,6 +17,8 @@
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/Type.h"
+#include "llvm/ADT/DenseSet.h"
+
namespace lldb_private {
class SymbolFile :
@@ -125,6 +127,11 @@ public:
virtual bool ParseCompileUnitLineTable (const SymbolContext& sc) = 0;
virtual bool ParseCompileUnitDebugMacros (const SymbolContext& sc) = 0;
virtual bool ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) = 0;
+ virtual bool
+ ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc)
+ {
+ return false;
+ }
virtual bool ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules) = 0;
virtual size_t ParseFunctionBlocks (const SymbolContext& sc) = 0;
virtual size_t ParseTypes (const SymbolContext& sc) = 0;
@@ -141,7 +148,7 @@ public:
virtual uint32_t FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables);
virtual uint32_t FindFunctions (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list);
virtual uint32_t FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list);
- virtual uint32_t FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, TypeMap& types);
+ virtual uint32_t 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);
virtual size_t FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types);
virtual void GetMangledNamesForFunction(const std::string &scope_qualified_name, std::vector<ConstString> &mangled_names);
diff --git a/include/lldb/Symbol/SymbolVendor.h b/include/lldb/Symbol/SymbolVendor.h
index 19461718ed13..e992c5cde607 100644
--- a/include/lldb/Symbol/SymbolVendor.h
+++ b/include/lldb/Symbol/SymbolVendor.h
@@ -17,6 +17,7 @@
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
+#include "llvm/ADT/DenseSet.h"
namespace lldb_private {
@@ -67,7 +68,10 @@ public:
virtual bool
ParseCompileUnitSupportFiles (const SymbolContext& sc,
FileSpecList& support_files);
-
+
+ virtual bool
+ ParseCompileUnitIsOptimized(const SymbolContext &sc);
+
virtual bool
ParseImportedModules (const SymbolContext &sc,
std::vector<ConstString> &imported_modules);
@@ -129,6 +133,7 @@ public:
const CompilerDeclContext *parent_decl_ctx,
bool append,
size_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap& types);
virtual size_t
diff --git a/include/lldb/Symbol/Symtab.h b/include/lldb/Symbol/Symtab.h
index 130f02c0e68b..4203a3f7599a 100644
--- a/include/lldb/Symbol/Symtab.h
+++ b/include/lldb/Symbol/Symtab.h
@@ -11,12 +11,12 @@
#ifndef liblldb_Symtab_h_
#define liblldb_Symtab_h_
+#include <mutex>
#include <vector>
#include "lldb/lldb-private.h"
#include "lldb/Core/RangeMap.h"
#include "lldb/Core/UniqueCStringMap.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/Symbol.h"
namespace lldb_private {
@@ -50,10 +50,11 @@ public:
void Dump(Stream *s, Target *target, SortOrder sort_type);
void Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const;
uint32_t GetIndexForSymbol (const Symbol *symbol) const;
- Mutex & GetMutex ()
- {
- return m_mutex;
- }
+ std::recursive_mutex &
+ GetMutex()
+ {
+ return m_mutex;
+ }
Symbol * FindSymbolByID (lldb::user_id_t uid) const;
Symbol * SymbolAtIndex (size_t idx);
const Symbol * SymbolAtIndex (size_t idx) const;
@@ -79,7 +80,7 @@ public:
size_t FindAllSymbolsWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes);
size_t FindAllSymbolsMatchingRexExAndType (const RegularExpression &regex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes);
Symbol * FindFirstSymbolWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility);
- Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes);
+ Symbol * FindSymbolAtFileAddress (lldb::addr_t file_addr);
Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr);
void ForEachSymbolContainingFileAddress(lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback);
size_t FindFunctionSymbols (const ConstString &name, uint32_t name_type_mask, SymbolContextList& sc_list);
@@ -124,7 +125,7 @@ protected:
UniqueCStringMap<uint32_t> m_basename_to_index;
UniqueCStringMap<uint32_t> m_method_to_index;
UniqueCStringMap<uint32_t> m_selector_to_index;
- mutable Mutex m_mutex; // Provide thread safety for this symbol table
+ mutable std::recursive_mutex m_mutex; // Provide thread safety for this symbol table
bool m_file_addr_to_index_computed:1,
m_name_indexes_computed:1;
private:
diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h
index 224e0a112df3..9158f28998e3 100644
--- a/include/lldb/Symbol/Type.h
+++ b/include/lldb/Symbol/Type.h
@@ -428,7 +428,10 @@ public:
SetType (lldb::TypeSP type)
{
type_sp = type;
- compiler_type = type_sp->GetForwardCompilerType ();
+ if (type_sp)
+ compiler_type = type_sp->GetForwardCompilerType ();
+ else
+ compiler_type.Clear();
}
lldb::TypeSP
@@ -955,13 +958,13 @@ public:
uint64_t
GetValueAsUnsigned () const
{
- return *m_value.getRawData();
+ return m_value.getZExtValue();
}
int64_t
GetValueAsSigned () const
{
- return (int64_t) *m_value.getRawData();
+ return m_value.getSExtValue();
}
protected:
diff --git a/include/lldb/Symbol/TypeSystem.h b/include/lldb/Symbol/TypeSystem.h
index 9b43b9dec37b..466699366f0a 100644
--- a/include/lldb/Symbol/TypeSystem.h
+++ b/include/lldb/Symbol/TypeSystem.h
@@ -14,6 +14,7 @@
// C++ Includes
#include <functional>
#include <map>
+#include <mutex>
#include <string>
// Other libraries and framework includes
@@ -24,7 +25,6 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Expression/Expression.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
@@ -74,6 +74,7 @@ public:
eKindClang,
eKindSwift,
eKindGo,
+ eKindJava,
kNumKinds
};
@@ -92,8 +93,14 @@ public:
static lldb::TypeSystemSP
CreateInstance (lldb::LanguageType language, Target *target);
+
+ // Free up any resources associated with this TypeSystem. Done before removing
+ // all the TypeSystems from the TypeSystemMap.
+ virtual void
+ Finalize() {}
+
virtual DWARFASTParser *
- GetDWARFParser ()
+ GetDWARFParser()
{
return nullptr;
}
@@ -120,12 +127,6 @@ public:
virtual ConstString
DeclGetMangledName (void *opaque_decl);
- virtual lldb::VariableSP
- DeclGetVariable (void *opaque_decl) = 0;
-
- virtual void
- DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object) = 0;
-
virtual CompilerDeclContext
DeclGetDeclContext (void *opaque_decl);
@@ -143,7 +144,9 @@ public:
//----------------------------------------------------------------------
virtual std::vector<CompilerDecl>
- DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name);
+ DeclContextFindDeclByName (void *opaque_decl_ctx,
+ ConstString name,
+ const bool ignore_imported_decls);
virtual bool
DeclContextIsStructUnionOrClass (void *opaque_decl_ctx) = 0;
@@ -201,9 +204,19 @@ public:
IsFunctionPointerType (lldb::opaque_compiler_type_t type) = 0;
virtual bool
- IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) = 0;
+ IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) = 0;
virtual bool
+ IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) = 0;
+
+ virtual bool
+ IsEnumerationType (lldb::opaque_compiler_type_t type, bool &is_signed)
+ {
+ is_signed = false;
+ return false;
+ }
+
+ virtual bool
IsPossibleDynamicType (lldb::opaque_compiler_type_t type,
CompilerType *target_type, // Can pass NULL
bool check_cplusplus,
@@ -582,6 +595,8 @@ protected:
TypeSystemMap ();
~TypeSystemMap();
+ // Clear calls Finalize on all the TypeSystems managed by this map, and then
+ // empties the map.
void
Clear ();
@@ -597,9 +612,15 @@ protected:
GetTypeSystemForLanguage (lldb::LanguageType language, Target *target, bool can_create);
protected:
+ // This function does not take the map mutex, and should only be called from
+ // functions that do take the mutex.
+ void
+ AddToMap (lldb::LanguageType language, lldb::TypeSystemSP const &type_system_sp);
+
typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> collection;
- mutable Mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments.
+ mutable std::mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments.
collection m_map;
+ bool m_clear_in_progress;
};
} // namespace lldb_private
diff --git a/include/lldb/Symbol/UnwindPlan.h b/include/lldb/Symbol/UnwindPlan.h
index 71100138413d..64c00bf12c27 100644
--- a/include/lldb/Symbol/UnwindPlan.h
+++ b/include/lldb/Symbol/UnwindPlan.h
@@ -116,6 +116,12 @@ public:
return m_type == unspecified;
}
+ bool
+ IsUndefined () const
+ {
+ return m_type == undefined;
+ }
+
bool
IsCFAPlusOffset () const
{
@@ -539,7 +545,7 @@ public:
AppendRow (const RowSP& row_sp);
void
- InsertRow (const RowSP& row_sp);
+ InsertRow (const RowSP& row_sp, bool replace_existing = false);
// Returns a pointer to the best row for the given offset into the function's instructions.
// If offset is -1 it indicates that the function start is unknown - the final row in the UnwindPlan is returned.
diff --git a/include/lldb/Symbol/UnwindTable.h b/include/lldb/Symbol/UnwindTable.h
index f69e4660de24..cb0080aff881 100644
--- a/include/lldb/Symbol/UnwindTable.h
+++ b/include/lldb/Symbol/UnwindTable.h
@@ -12,9 +12,9 @@
#define liblldb_UnwindTable_h
#include <map>
+#include <mutex>
#include "lldb/lldb-private.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -40,6 +40,9 @@ public:
lldb::FuncUnwindersSP
GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc);
+ bool
+ GetAllowAssemblyEmulationUnwindPlans ();
+
// Normally when we create a new FuncUnwinders object we track it in this UnwindTable so it can
// be reused later. But for the target modules show-unwind we want to create brand new
// UnwindPlans for the function of interest - so ignore any existing FuncUnwinders for that
@@ -66,7 +69,7 @@ private:
collection m_unwinds;
bool m_initialized; // delay some initialization until ObjectFile is set up
- Mutex m_mutex;
+ std::mutex m_mutex;
std::unique_ptr<DWARFCallFrameInfo> m_eh_frame_up;
std::unique_ptr<CompactUnwindInfo> m_compact_unwind_up;
diff --git a/include/lldb/Symbol/Variable.h b/include/lldb/Symbol/Variable.h
index 1cac5d0c5649..00761424d107 100644
--- a/include/lldb/Symbol/Variable.h
+++ b/include/lldb/Symbol/Variable.h
@@ -17,6 +17,7 @@
#include "lldb/lldb-private.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/Core/Mangled.h"
+#include "lldb/Core/RangeMap.h"
#include "lldb/Core/UserID.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/Declaration.h"
@@ -27,6 +28,8 @@ class Variable : public UserID,
public std::enable_shared_from_this<Variable>
{
public:
+ typedef RangeVector<lldb::addr_t, lldb::addr_t> RangeList;
+
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
@@ -36,6 +39,7 @@ public:
const lldb::SymbolFileTypeSP &symfile_type_sp,
lldb::ValueType scope,
SymbolContextScope *owner_scope,
+ const RangeList& scope_range,
Declaration* decl,
const DWARFExpression& location,
bool external,
@@ -178,12 +182,14 @@ public:
CompilerDecl
GetDecl ();
+
protected:
ConstString m_name; // The basename of the variable (no namespaces)
Mangled m_mangled; // The mangled name of the variable
lldb::SymbolFileTypeSP m_symfile_type_sp; // The type pointer of the variable (int, struct, class, etc)
lldb::ValueType m_scope; // global, parameter, local
SymbolContextScope *m_owner_scope; // The symbol file scope that this variable was defined in
+ RangeList m_scope_range; // The list of ranges inside the owner's scope where this variable is valid
Declaration m_declaration; // Declaration location for this item.
DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate()
uint8_t m_external:1, // Visible outside the containing compile unit?
diff --git a/include/lldb/Target/ABI.h b/include/lldb/Target/ABI.h
index 94826d173500..cd0b57e61ff8 100644
--- a/include/lldb/Target/ABI.h
+++ b/include/lldb/Target/ABI.h
@@ -16,6 +16,7 @@
// Project includes
#include "lldb/Core/Error.h"
#include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/lldb-private.h"
#include "llvm/ADT/ArrayRef.h"
@@ -110,6 +111,10 @@ public:
virtual bool
RegisterIsVolatile (const RegisterInfo *reg_info) = 0;
+ virtual bool
+ GetFallbackRegisterLocation (const RegisterInfo *reg_info,
+ UnwindPlan::Row::RegisterLocation &unwind_regloc);
+
// Should take a look at a call frame address (CFA) which is just the stack
// pointer value upon entry to a function. ABIs usually impose alignment
// restrictions (4, 8 or 16 byte aligned), and zero is usually not allowed.
diff --git a/include/lldb/Target/DynamicLoader.h b/include/lldb/Target/DynamicLoader.h
index 5eada0342a21..2c4956829b29 100644
--- a/include/lldb/Target/DynamicLoader.h
+++ b/include/lldb/Target/DynamicLoader.h
@@ -71,7 +71,7 @@ public:
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
- ~DynamicLoader() override;
+ virtual ~DynamicLoader() override;
//------------------------------------------------------------------
/// Called after attaching a process.
@@ -238,11 +238,19 @@ public:
/// LLDB_INVALID_ADDRESS is returned.
//------------------------------------------------------------------
virtual lldb::addr_t
- GetThreadLocalData (const lldb::ModuleSP module, const lldb::ThreadSP thread)
+ GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr)
{
return LLDB_INVALID_ADDRESS;
}
+ /// Locates or creates a module given by @p file and updates/loads the
+ /// resulting module at the virtual base address @p base_addr.
+ virtual lldb::ModuleSP
+ LoadModuleAtAddress(const lldb_private::FileSpec &file,
+ lldb::addr_t link_map_addr,
+ lldb::addr_t base_addr,
+ bool base_addr_is_offset);
+
protected:
//------------------------------------------------------------------
// Utility methods for derived classes
@@ -282,14 +290,6 @@ protected:
void
UnloadSectionsCommon(const lldb::ModuleSP module);
- /// Locates or creates a module given by @p file and updates/loads the
- /// resulting module at the virtual base address @p base_addr.
- virtual lldb::ModuleSP
- LoadModuleAtAddress(const lldb_private::FileSpec &file,
- lldb::addr_t link_map_addr,
- lldb::addr_t base_addr,
- bool base_addr_is_offset);
-
const lldb_private::SectionList *
GetSectionListFromModule(const lldb::ModuleSP module) const;
diff --git a/include/lldb/Target/ExecutionContext.h b/include/lldb/Target/ExecutionContext.h
index cdf55e3b744c..da585e4c9dad 100644
--- a/include/lldb/Target/ExecutionContext.h
+++ b/include/lldb/Target/ExecutionContext.h
@@ -12,11 +12,12 @@
// C Includes
// C++ Includes
+#include <mutex>
+
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Target/StackID.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -412,8 +413,8 @@ public:
// These two variants take in a locker, and grab the target, lock the API mutex into locker, then
// fill in the rest of the shared pointers.
- ExecutionContext (const ExecutionContextRef &exe_ctx_ref, Mutex::Locker &locker);
- ExecutionContext (const ExecutionContextRef *exe_ctx_ref, Mutex::Locker &locker);
+ ExecutionContext(const ExecutionContextRef &exe_ctx_ref, std::unique_lock<std::recursive_mutex> &locker);
+ ExecutionContext(const ExecutionContextRef *exe_ctx_ref, std::unique_lock<std::recursive_mutex> &locker);
//------------------------------------------------------------------
// Create execution contexts from execution context scopes
//------------------------------------------------------------------
diff --git a/include/lldb/Target/InstrumentationRuntime.h b/include/lldb/Target/InstrumentationRuntime.h
index 70aa62908406..a5dc853ab55b 100644
--- a/include/lldb/Target/InstrumentationRuntime.h
+++ b/include/lldb/Target/InstrumentationRuntime.h
@@ -20,6 +20,7 @@
#include "lldb/lldb-private.h"
#include "lldb/lldb-types.h"
#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/StructuredData.h"
namespace lldb_private {
@@ -39,6 +40,9 @@ public:
virtual bool
IsActive();
+
+ virtual lldb::ThreadCollectionSP
+ GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info);
};
diff --git a/include/lldb/Target/JITLoaderList.h b/include/lldb/Target/JITLoaderList.h
index f933a61e9952..c86043c5cf1f 100644
--- a/include/lldb/Target/JITLoaderList.h
+++ b/include/lldb/Target/JITLoaderList.h
@@ -10,10 +10,10 @@
#ifndef liblldb_JITLoaderList_h_
#define liblldb_JITLoaderList_h_
+#include <mutex>
#include <vector>
#include "lldb/lldb-forward.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -52,7 +52,7 @@ public:
private:
std::vector<lldb::JITLoaderSP> m_jit_loaders_vec;
- lldb_private::Mutex m_jit_loaders_mutex;
+ std::recursive_mutex m_jit_loaders_mutex;
};
} // namespace lldb_private
diff --git a/include/lldb/Target/Language.h b/include/lldb/Target/Language.h
index 492425ec088b..d1a3ff8e6747 100644
--- a/include/lldb/Target/Language.h
+++ b/include/lldb/Target/Language.h
@@ -113,6 +113,9 @@ public:
virtual std::unique_ptr<TypeScavenger>
GetTypeScavenger ();
+ virtual const char*
+ GetLanguageSpecificTypeLookupHelp ();
+
// if an individual data formatter can apply to several types and cross a language boundary
// it makes sense for individual languages to want to customize the printing of values of that
// type by appending proper prefix/suffix information in language-specific ways
diff --git a/include/lldb/Target/LanguageRuntime.h b/include/lldb/Target/LanguageRuntime.h
index 686ec5ea3479..beb7a9e74876 100644
--- a/include/lldb/Target/LanguageRuntime.h
+++ b/include/lldb/Target/LanguageRuntime.h
@@ -22,6 +22,9 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/Value.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Expression/LLVMUserExpression.h"
+
+#include "clang/Basic/TargetOptions.h"
namespace lldb_private {
@@ -147,6 +150,22 @@ public:
{
}
+ // Called by the Clang expression evaluation engine to allow runtimes to alter the set of target options provided to
+ // the compiler.
+ // If the options prototype is modified, runtimes must return true, false otherwise.
+ virtual bool
+ GetOverrideExprOptions(clang::TargetOptions &prototype)
+ {
+ return false;
+ }
+
+ // Called by ClangExpressionParser::PrepareForExecution to query for any custom LLVM IR passes
+ // that need to be run before an expression is assembled and run.
+ virtual bool
+ GetIRPasses(LLVMUserExpression::IRPasses &custom_passes)
+ {
+ return false;
+ }
protected:
//------------------------------------------------------------------
// Classes that inherit from LanguageRuntime can see and modify these
diff --git a/include/lldb/Target/Memory.h b/include/lldb/Target/Memory.h
index bf1cc1878784..f4d776a43c99 100644
--- a/include/lldb/Target/Memory.h
+++ b/include/lldb/Target/Memory.h
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
#include <vector>
// Other libraries and framework includes
@@ -20,7 +21,6 @@
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Core/RangeMap.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
//----------------------------------------------------------------------
@@ -75,7 +75,7 @@ namespace lldb_private {
//------------------------------------------------------------------
// Classes that inherit from MemoryCache can see and modify these
//------------------------------------------------------------------
- Mutex m_mutex;
+ std::recursive_mutex m_mutex;
BlockMap m_L1_cache; // A first level memory cache whose chunk sizes vary that will be used only if the memory read fits entirely in a chunk
BlockMap m_L2_cache; // A memory cache of fixed size chinks (m_L2_cache_line_byte_size bytes in size each)
InvalidRanges m_invalid_ranges;
@@ -192,7 +192,7 @@ namespace lldb_private {
// Classes that inherit from MemoryCache can see and modify these
//------------------------------------------------------------------
Process &m_process;
- Mutex m_mutex;
+ std::recursive_mutex m_mutex;
typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap;
PermissionsToBlockMap m_memory_map;
diff --git a/include/lldb/Target/MemoryRegionInfo.h b/include/lldb/Target/MemoryRegionInfo.h
index 0726ad15e876..5c82a1f294dd 100644
--- a/include/lldb/Target/MemoryRegionInfo.h
+++ b/include/lldb/Target/MemoryRegionInfo.h
@@ -30,7 +30,8 @@ namespace lldb_private
m_range (),
m_read (eDontKnow),
m_write (eDontKnow),
- m_execute (eDontKnow)
+ m_execute (eDontKnow),
+ m_mapped (eDontKnow)
{
}
@@ -75,6 +76,12 @@ namespace lldb_private
return m_execute;
}
+ OptionalBool
+ GetMapped () const
+ {
+ return m_mapped;
+ }
+
void
SetReadable (OptionalBool val)
{
@@ -93,11 +100,63 @@ namespace lldb_private
m_execute = val;
}
+ void
+ SetMapped (OptionalBool val)
+ {
+ m_mapped = val;
+ }
+
+ //----------------------------------------------------------------------
+ // Get permissions as a uint32_t that is a mask of one or more bits from
+ // the lldb::Permissions
+ //----------------------------------------------------------------------
+ uint32_t
+ GetLLDBPermissions() const
+ {
+ uint32_t permissions = 0;
+ if (m_read)
+ permissions |= lldb::ePermissionsReadable;
+ if (m_write)
+ permissions |= lldb::ePermissionsWritable;
+ if (m_execute)
+ permissions |= lldb::ePermissionsExecutable;
+ return permissions;
+ }
+
+ //----------------------------------------------------------------------
+ // Set permissions from a uint32_t that contains one or more bits from
+ // the lldb::Permissions
+ //----------------------------------------------------------------------
+ void
+ SetLLDBPermissions(uint32_t permissions)
+ {
+ m_read = (permissions & lldb::ePermissionsReadable) ? eYes : eNo;
+ m_write = (permissions & lldb::ePermissionsWritable) ? eYes : eNo;
+ m_execute = (permissions & lldb::ePermissionsExecutable) ? eYes : eNo;
+ }
+
+ bool
+ operator == (const MemoryRegionInfo &rhs) const
+ {
+ return m_range == rhs.m_range &&
+ m_read == rhs.m_read &&
+ m_write == rhs.m_write &&
+ m_execute == rhs.m_execute &&
+ m_mapped == rhs.m_mapped;
+ }
+
+ bool
+ operator != (const MemoryRegionInfo &rhs) const
+ {
+ return !(*this == rhs);
+ }
+
protected:
RangeType m_range;
OptionalBool m_read;
OptionalBool m_write;
OptionalBool m_execute;
+ OptionalBool m_mapped;
};
}
diff --git a/include/lldb/Target/PathMappingList.h b/include/lldb/Target/PathMappingList.h
index 17185cb68495..1a486c4642dc 100644
--- a/include/lldb/Target/PathMappingList.h
+++ b/include/lldb/Target/PathMappingList.h
@@ -116,7 +116,9 @@ public:
bool
RemapPath (const char *path, std::string &new_path) const;
-
+ bool
+ ReverseRemapPath (const ConstString &path, ConstString &new_path) const;
+
//------------------------------------------------------------------
/// Finds a source file given a file spec using the path remappings.
///
diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h
index 53c17a6a66cf..6fdd92db5680 100644
--- a/include/lldb/Target/Platform.h
+++ b/include/lldb/Target/Platform.h
@@ -15,6 +15,7 @@
#include <functional>
#include <map>
#include <memory>
+#include <mutex>
#include <string>
#include <vector>
@@ -28,7 +29,6 @@
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/Mutex.h"
// TODO pull NativeDelegate class out of NativeProcessProtocol so we
// can just forward ref the NativeDelegate rather than include it here.
@@ -427,7 +427,7 @@ class ModuleCache;
virtual size_t
GetSoftwareBreakpointTrapOpcode (Target &target,
- BreakpointSite *bp_site) = 0;
+ BreakpointSite *bp_site);
//------------------------------------------------------------------
/// Launch a new process on a platform, not necessarily for
@@ -1079,7 +1079,8 @@ class ModuleCache;
uint32_t m_update_os_version;
ArchSpec m_system_arch; // The architecture of the kernel or the remote platform
typedef std::map<uint32_t, ConstString> IDToNameMap;
- Mutex m_mutex; // Mutex for modifying Platform data structures that should only be used for non-reentrant code
+ // Mutex for modifying Platform data structures that should only be used for non-reentrant code
+ std::mutex m_mutex;
IDToNameMap m_uid_map;
IDToNameMap m_gid_map;
size_t m_max_uid_name_len;
@@ -1112,9 +1113,9 @@ class ModuleCache;
CalculateTrapHandlerSymbolNames () = 0;
const char *
- GetCachedUserName (uint32_t uid)
+ GetCachedUserName(uint32_t uid)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
// return the empty string if our string is NULL
// so we can tell when things were in the negative
// cached (didn't find a valid user name, don't keep
@@ -1124,35 +1125,35 @@ class ModuleCache;
}
const char *
- SetCachedUserName (uint32_t uid, const char *name, size_t name_len)
+ SetCachedUserName(uint32_t uid, const char *name, size_t name_len)
{
- Mutex::Locker locker (m_mutex);
- ConstString const_name (name);
+ std::lock_guard<std::mutex> guard(m_mutex);
+ ConstString const_name(name);
m_uid_map[uid] = const_name;
if (m_max_uid_name_len < name_len)
m_max_uid_name_len = name_len;
// Const strings lives forever in our const string pool, so we can return the const char *
- return const_name.GetCString();
+ return const_name.GetCString();
}
void
- SetUserNameNotFound (uint32_t uid)
+ SetUserNameNotFound(uint32_t uid)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
m_uid_map[uid] = ConstString();
}
void
- ClearCachedUserNames ()
+ ClearCachedUserNames()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
m_uid_map.clear();
}
-
+
const char *
- GetCachedGroupName (uint32_t gid)
+ GetCachedGroupName(uint32_t gid)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
// return the empty string if our string is NULL
// so we can tell when things were in the negative
// cached (didn't find a valid group name, don't keep
@@ -1162,28 +1163,28 @@ class ModuleCache;
}
const char *
- SetCachedGroupName (uint32_t gid, const char *name, size_t name_len)
+ SetCachedGroupName(uint32_t gid, const char *name, size_t name_len)
{
- Mutex::Locker locker (m_mutex);
- ConstString const_name (name);
+ std::lock_guard<std::mutex> guard(m_mutex);
+ ConstString const_name(name);
m_gid_map[gid] = const_name;
if (m_max_gid_name_len < name_len)
m_max_gid_name_len = name_len;
// Const strings lives forever in our const string pool, so we can return the const char *
- return const_name.GetCString();
+ return const_name.GetCString();
}
void
- SetGroupNameNotFound (uint32_t gid)
+ SetGroupNameNotFound(uint32_t gid)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
m_gid_map[gid] = ConstString();
}
void
- ClearCachedGroupNames ()
+ ClearCachedGroupNames()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
m_gid_map.clear();
}
@@ -1236,20 +1237,15 @@ class ModuleCache;
class PlatformList
{
public:
- PlatformList() :
- m_mutex (Mutex::eMutexTypeRecursive),
- m_platforms (),
- m_selected_platform_sp()
- {
- }
+ PlatformList() : m_mutex(), m_platforms(), m_selected_platform_sp() {}
~PlatformList() = default;
void
- Append (const lldb::PlatformSP &platform_sp, bool set_selected)
+ Append(const lldb::PlatformSP &platform_sp, bool set_selected)
{
- Mutex::Locker locker (m_mutex);
- m_platforms.push_back (platform_sp);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_platforms.push_back(platform_sp);
if (set_selected)
m_selected_platform_sp = m_platforms.back();
}
@@ -1257,16 +1253,16 @@ class ModuleCache;
size_t
GetSize()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_platforms.size();
}
lldb::PlatformSP
- GetAtIndex (uint32_t idx)
+ GetAtIndex(uint32_t idx)
{
lldb::PlatformSP platform_sp;
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (idx < m_platforms.size())
platform_sp = m_platforms[idx];
}
@@ -1283,23 +1279,23 @@ class ModuleCache;
/// processes.
//------------------------------------------------------------------
lldb::PlatformSP
- GetSelectedPlatform ()
+ GetSelectedPlatform()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_selected_platform_sp && !m_platforms.empty())
m_selected_platform_sp = m_platforms.front();
-
+
return m_selected_platform_sp;
}
void
- SetSelectedPlatform (const lldb::PlatformSP &platform_sp)
+ SetSelectedPlatform(const lldb::PlatformSP &platform_sp)
{
if (platform_sp)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const size_t num_platforms = m_platforms.size();
- for (size_t idx=0; idx<num_platforms; ++idx)
+ for (size_t idx = 0; idx < num_platforms; ++idx)
{
if (m_platforms[idx].get() == platform_sp.get())
{
@@ -1307,28 +1303,28 @@ class ModuleCache;
return;
}
}
- m_platforms.push_back (platform_sp);
+ m_platforms.push_back(platform_sp);
m_selected_platform_sp = m_platforms.back();
}
}
protected:
typedef std::vector<lldb::PlatformSP> collection;
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
collection m_platforms;
lldb::PlatformSP m_selected_platform_sp;
private:
DISALLOW_COPY_AND_ASSIGN (PlatformList);
};
-
+
class OptionGroupPlatformRSync : public lldb_private::OptionGroup
{
public:
- OptionGroupPlatformRSync ();
-
- ~OptionGroupPlatformRSync() override;
-
+ OptionGroupPlatformRSync() = default;
+
+ ~OptionGroupPlatformRSync() override = default;
+
lldb_private::Error
SetOptionValue(CommandInterpreter &interpreter,
uint32_t option_idx,
@@ -1353,6 +1349,7 @@ class ModuleCache;
std::string m_rsync_opts;
std::string m_rsync_prefix;
bool m_ignores_remote_hostname;
+
private:
DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformRSync);
};
@@ -1360,10 +1357,10 @@ class ModuleCache;
class OptionGroupPlatformSSH : public lldb_private::OptionGroup
{
public:
- OptionGroupPlatformSSH ();
-
- ~OptionGroupPlatformSSH() override;
-
+ OptionGroupPlatformSSH() = default;
+
+ ~OptionGroupPlatformSSH() override = default;
+
lldb_private::Error
SetOptionValue(CommandInterpreter &interpreter,
uint32_t option_idx,
@@ -1394,10 +1391,10 @@ class ModuleCache;
class OptionGroupPlatformCaching : public lldb_private::OptionGroup
{
public:
- OptionGroupPlatformCaching ();
-
- ~OptionGroupPlatformCaching() override;
-
+ OptionGroupPlatformCaching() = default;
+
+ ~OptionGroupPlatformCaching() override = default;
+
lldb_private::Error
SetOptionValue(CommandInterpreter &interpreter,
uint32_t option_idx,
diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h
index 6bb7a3d783de..57787f2f8f39 100644
--- a/include/lldb/Target/Process.h
+++ b/include/lldb/Target/Process.h
@@ -18,6 +18,7 @@
// C++ Includes
#include <list>
#include <memory>
+#include <mutex>
#include <string>
#include <vector>
#include <unordered_set>
@@ -30,6 +31,7 @@
#include "lldb/Core/Communication.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Event.h"
+#include "lldb/Core/Listener.h"
#include "lldb/Core/LoadedModuleInfoList.h"
#include "lldb/Core/ThreadSafeValue.h"
#include "lldb/Core/PluginInterface.h"
@@ -400,7 +402,7 @@ public:
m_listener_sp = listener_sp;
}
- Listener &
+ lldb::ListenerSP
GetListenerForProcess (Debugger &debugger);
protected:
@@ -939,13 +941,13 @@ public:
/// Construct with a shared pointer to a target, and the Process listener.
/// Uses the Host UnixSignalsSP by default.
//------------------------------------------------------------------
- Process(lldb::TargetSP target_sp, Listener &listener);
+ Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
//------------------------------------------------------------------
/// Construct with a shared pointer to a target, the Process listener,
/// and the appropriate UnixSignalsSP for the process.
//------------------------------------------------------------------
- Process(lldb::TargetSP target_sp, Listener &listener, const lldb::UnixSignalsSP &unix_signals_sp);
+ Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const lldb::UnixSignalsSP &unix_signals_sp);
//------------------------------------------------------------------
/// Destructor.
@@ -985,7 +987,7 @@ public:
static lldb::ProcessSP
FindPlugin (lldb::TargetSP target_sp,
const char *plugin_name,
- Listener &listener,
+ lldb::ListenerSP listener_sp,
const FileSpec *crash_file_path);
//------------------------------------------------------------------
@@ -998,16 +1000,14 @@ public:
/// Subclasses should call Host::StartMonitoringChildProcess ()
/// with:
/// callback = Process::SetHostProcessExitStatus
- /// callback_baton = nullptr
/// pid = Process::GetID()
/// monitor_signals = false
//------------------------------------------------------------------
static bool
- SetProcessExitStatus(void *callback_baton, // The callback baton which should be set to nullptr
- lldb::pid_t pid, // The process ID we want to monitor
+ SetProcessExitStatus(lldb::pid_t pid, // The process ID we want to monitor
bool exited,
- int signo, // Zero for no signal
- int status); // Exit value of process if signal is zero
+ int signo, // Zero for no signal
+ int status); // Exit value of process if signal is zero
lldb::ByteOrder
GetByteOrder () const;
@@ -1886,15 +1886,13 @@ public:
//------------------------------------------------------------------
lldb::StateType
GetState ();
-
+
lldb::ExpressionResults
- RunThreadPlan (ExecutionContext &exe_ctx,
- lldb::ThreadPlanSP &thread_plan_sp,
- const EvaluateExpressionOptions &options,
- Stream &errors);
+ RunThreadPlan(ExecutionContext &exe_ctx, lldb::ThreadPlanSP &thread_plan_sp,
+ const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager);
static const char *
- ExecutionResultAsCString (lldb::ExpressionResults result);
+ ExecutionResultAsCString(lldb::ExpressionResults result);
void
GetStatus (Stream &ostrm);
@@ -1962,6 +1960,9 @@ public:
void
PrintWarningOptimization (const SymbolContext &sc);
+ virtual bool
+ GetProcessInfo(ProcessInstanceInfo &info);
+
public:
//------------------------------------------------------------------
/// Get the exit status for a process.
@@ -2232,11 +2233,11 @@ public:
/// order.
//------------------------------------------------------------------
uint64_t
- ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
- size_t byte_size,
- uint64_t fail_value,
- Error &error);
-
+ ReadUnsignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, uint64_t fail_value, Error &error);
+
+ int64_t
+ ReadSignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, int64_t fail_value, Error &error);
+
lldb::addr_t
ReadPointerFromMemory (lldb::addr_t vm_addr,
Error &error);
@@ -2436,6 +2437,32 @@ public:
virtual lldb::addr_t
ResolveIndirectFunction(const Address *address, Error &error);
+ //------------------------------------------------------------------
+ /// Locate the memory region that contains load_addr.
+ ///
+ /// If load_addr is within the address space the process has mapped
+ /// range_info will be filled in with the start and end of that range
+ /// as well as the permissions for that range and range_info.GetMapped
+ /// will return true.
+ ///
+ /// If load_addr is outside any mapped region then range_info will
+ /// have its start address set to load_addr and the end of the
+ /// range will indicate the start of the next mapped range or be
+ /// set to LLDB_INVALID_ADDRESS if there are no valid mapped ranges
+ /// between load_addr and the end of the process address space.
+ ///
+ /// GetMemoryRegionInfo will only return an error if it is
+ /// unimplemented for the current process.
+ ///
+ /// @param[in] load_addr
+ /// The load address to query the range_info for.
+ ///
+ /// @param[out] range_info
+ /// An range_info value containing the details of the range.
+ ///
+ /// @return
+ /// An error value.
+ //------------------------------------------------------------------
virtual Error
GetMemoryRegionInfo (lldb::addr_t load_addr,
MemoryRegionInfo &range_info)
@@ -2445,6 +2472,19 @@ public:
return error;
}
+ //------------------------------------------------------------------
+ /// Obtain all the mapped memory regions within this process.
+ ///
+ /// @param[out] region_list
+ /// A vector to contain MemoryRegionInfo objects for all mapped
+ /// ranges.
+ ///
+ /// @return
+ /// An error value.
+ //------------------------------------------------------------------
+ virtual Error
+ GetMemoryRegions (std::vector<lldb::MemoryRegionInfoSP>& region_list);
+
virtual Error
GetWatchpointSupportInfo (uint32_t &num)
{
@@ -2851,7 +2891,7 @@ public:
WaitForProcessToStop(const TimeValue *timeout,
lldb::EventSP *event_sp_ptr = nullptr,
bool wait_always = true,
- Listener *hijack_listener = nullptr,
+ lldb::ListenerSP hijack_listener = lldb::ListenerSP(),
Stream *stream = nullptr,
bool use_run_lock = true);
@@ -2877,7 +2917,7 @@ public:
lldb::StateType
WaitForStateChangedEvents(const TimeValue *timeout,
lldb::EventSP &event_sp,
- Listener *hijack_listener); // Pass nullptr to use builtin listener
+ lldb::ListenerSP hijack_listener); // Pass an empty ListenerSP to use builtin listener
//--------------------------------------------------------------------------------------
/// Centralize the code that handles and prints descriptions for process state changes.
@@ -2908,10 +2948,10 @@ public:
ProcessEventHijacker
{
public:
- ProcessEventHijacker (Process &process, Listener *listener) :
+ ProcessEventHijacker (Process &process, lldb::ListenerSP listener_sp) :
m_process (process)
{
- m_process.HijackProcessEvents (listener);
+ m_process.HijackProcessEvents (listener_sp);
}
~ProcessEventHijacker ()
@@ -2940,7 +2980,7 @@ public:
/// \b false otherwise.
//------------------------------------------------------------------
bool
- HijackProcessEvents (Listener *listener);
+ HijackProcessEvents (lldb::ListenerSP listener_sp);
//------------------------------------------------------------------
/// Restores the process event broadcasting to its normal state.
@@ -3308,9 +3348,13 @@ protected:
bool
PrivateStateThreadIsValid () const
{
- return m_private_state_thread.IsJoinable();
+ lldb::StateType state = m_private_state.GetValue();
+ return state != lldb::eStateInvalid &&
+ state != lldb::eStateDetached &&
+ state != lldb::eStateExited &&
+ m_private_state_thread.IsJoinable();
}
-
+
void
ForceNextEventDelivery()
{
@@ -3343,8 +3387,7 @@ protected:
ThreadSafeValue<lldb::StateType> m_private_state; // The actual state of our process
Broadcaster m_private_state_broadcaster; // This broadcaster feeds state changed events into the private state thread's listener.
Broadcaster m_private_state_control_broadcaster; // This is the control broadcaster, used to pause, resume & stop the private state thread.
- Listener m_private_state_listener; // This is the listener for the private state thread.
- Predicate<bool> m_private_state_control_wait; /// This Predicate is used to signal that a control operation is complete.
+ lldb::ListenerSP m_private_state_listener_sp; // This is the listener for the private state thread.
HostThread m_private_state_thread; ///< Thread ID for the thread that watches internal state events
ProcessModID m_mod_id; ///< Tracks the state of the process over stops and other alterations.
uint32_t m_process_unique_id; ///< Each lldb_private::Process class that is created gets a unique integer ID that increments with each new instance
@@ -3352,8 +3395,9 @@ protected:
std::map<uint64_t, uint32_t> m_thread_id_to_index_id_map;
int m_exit_status; ///< The exit status of the process, or -1 if not set.
std::string m_exit_string; ///< A textual description of why a process exited.
- Mutex m_exit_status_mutex; ///< Mutex so m_exit_status m_exit_string can be safely accessed from multiple threads
- Mutex m_thread_mutex;
+ std::mutex
+ m_exit_status_mutex; ///< Mutex so m_exit_status m_exit_string can be safely accessed from multiple threads
+ std::recursive_mutex m_thread_mutex;
ThreadList m_thread_list_real; ///< The threads for this process as are known to the protocol we are debugging with
ThreadList m_thread_list; ///< The threads for this process as the user will see them. This is usually the same as
///< m_thread_list_real, but might be different if there is an OS plug-in creating memory threads
@@ -3363,7 +3407,7 @@ protected:
uint32_t m_queue_list_stop_id; ///< The natural stop id when queue list was last fetched
std::vector<Notifications> m_notifications; ///< The list of notifications that this process can deliver.
std::vector<lldb::addr_t> m_image_tokens;
- Listener &m_listener;
+ lldb::ListenerSP m_listener_sp; ///< Shared pointer to the listener used for public events. Can not be empty.
BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend to insert in the target.
lldb::DynamicLoaderUP m_dyld_ap;
lldb::JITLoaderListUP m_jit_loaders_ap;
@@ -3374,11 +3418,11 @@ protected:
lldb::ABISP m_abi_sp;
lldb::IOHandlerSP m_process_input_reader;
Communication m_stdio_communication;
- Mutex m_stdio_communication_mutex;
+ std::recursive_mutex m_stdio_communication_mutex;
bool m_stdin_forward; /// Remember if stdin must be forwarded to remote debug server
std::string m_stdout_data;
std::string m_stderr_data;
- Mutex m_profile_data_comm_mutex;
+ std::recursive_mutex m_profile_data_comm_mutex;
std::vector<std::string> m_profile_data;
Predicate<uint32_t> m_iohandler_sync;
MemoryCache m_memory_cache;
@@ -3402,6 +3446,7 @@ protected:
bool m_destroy_in_process;
bool m_can_interpret_function_calls; // Some targets, e.g the OSX kernel, don't support the ability to modify the stack.
WarningsCollection m_warnings_issued; // A set of object pointers which have already had warnings printed
+ std::mutex m_run_thread_plan_lock;
enum {
eCanJITDontKnow= 0,
@@ -3433,12 +3478,15 @@ protected:
void
ResumePrivateStateThread ();
+private:
struct PrivateStateThreadArgs
{
+ PrivateStateThreadArgs(Process *p, bool s) : process(p), is_secondary_thread(s) {};
Process *process;
bool is_secondary_thread;
};
-
+
+ // arg is a pointer to a new'ed PrivateStateThreadArgs structure. PrivateStateThread will free it for you.
static lldb::thread_result_t
PrivateStateThread (void *arg);
@@ -3450,6 +3498,7 @@ protected:
lldb::thread_result_t
RunPrivateStateThread (bool is_secondary_thread);
+protected:
void
HandlePrivateEvent (lldb::EventSP &event_sp);
diff --git a/include/lldb/Target/ProcessLaunchInfo.h b/include/lldb/Target/ProcessLaunchInfo.h
index 92a3ed40736d..d1a45794b551 100644
--- a/include/lldb/Target/ProcessLaunchInfo.h
+++ b/include/lldb/Target/ProcessLaunchInfo.h
@@ -148,9 +148,7 @@ namespace lldb_private
int32_t num_resumes);
void
- SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback,
- void *baton,
- bool monitor_signals);
+ SetMonitorProcessCallback(const Host::MonitorChildProcessCallback &callback, bool monitor_signals);
Host::MonitorChildProcessCallback
GetMonitorProcessCallback() const
@@ -158,12 +156,6 @@ namespace lldb_private
return m_monitor_callback;
}
- void *
- GetMonitorProcessBaton() const
- {
- return m_monitor_callback_baton;
- }
-
bool
GetMonitorSignals() const
{
@@ -196,7 +188,7 @@ namespace lldb_private
m_listener_sp = listener_sp;
}
- Listener &
+ lldb::ListenerSP
GetListenerForProcess (Debugger &debugger);
lldb::ListenerSP
diff --git a/include/lldb/Target/QueueList.h b/include/lldb/Target/QueueList.h
index 12a0ea52d7f4..265145db2696 100644
--- a/include/lldb/Target/QueueList.h
+++ b/include/lldb/Target/QueueList.h
@@ -10,6 +10,7 @@
#ifndef liblldb_QueueList_h_
#define liblldb_QueueList_h_
+#include <mutex>
#include <vector>
#include "lldb/lldb-private.h"
@@ -60,7 +61,7 @@ public:
GetQueueAtIndex (uint32_t idx);
typedef std::vector<lldb::QueueSP> collection;
- typedef LockingAdaptedIterable<collection, lldb::QueueSP, vector_adapter> QueueIterable;
+ typedef LockingAdaptedIterable<collection, lldb::QueueSP, vector_adapter, std::mutex> QueueIterable;
//------------------------------------------------------------------
/// Iterate over the list of queues
@@ -119,8 +120,8 @@ public:
lldb::QueueSP
FindQueueByIndexID (uint32_t index_id);
- lldb_private::Mutex &
- GetMutex ();
+ std::mutex &
+ GetMutex();
protected:
@@ -130,7 +131,7 @@ protected:
Process *m_process; ///< The process that manages this queue list.
uint32_t m_stop_id; ///< The process stop ID that this queue list is valid for.
collection m_queues; ///< The queues for this process.
- Mutex m_mutex;
+ std::mutex m_mutex;
private:
QueueList ();
diff --git a/include/lldb/Target/SectionLoadHistory.h b/include/lldb/Target/SectionLoadHistory.h
index ddf46a1861ca..2494b7fd2779 100644
--- a/include/lldb/Target/SectionLoadHistory.h
+++ b/include/lldb/Target/SectionLoadHistory.h
@@ -13,10 +13,10 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
// Project includes
#include "lldb/lldb-public.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -31,11 +31,7 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- SectionLoadHistory () :
- m_stop_id_to_section_load_list(),
- m_mutex (Mutex::eMutexTypeRecursive)
- {
- }
+ SectionLoadHistory() : m_stop_id_to_section_load_list(), m_mutex() {}
~SectionLoadHistory()
{
@@ -98,7 +94,7 @@ protected:
typedef std::map<uint32_t, lldb::SectionLoadListSP> StopIDToSectionLoadList;
StopIDToSectionLoadList m_stop_id_to_section_load_list;
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
private:
DISALLOW_COPY_AND_ASSIGN (SectionLoadHistory);
diff --git a/include/lldb/Target/SectionLoadList.h b/include/lldb/Target/SectionLoadList.h
index 5f5d39e2b24b..1326d6007f2d 100644
--- a/include/lldb/Target/SectionLoadList.h
+++ b/include/lldb/Target/SectionLoadList.h
@@ -13,13 +13,13 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
// Other libraries and framework includes
#include "llvm/ADT/DenseMap.h"
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/Section.h"
-#include "lldb/Host/Mutex.h"
namespace lldb_private {
@@ -29,13 +29,7 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- SectionLoadList () :
- m_addr_to_sect (),
- m_sect_to_addr (),
- m_mutex (Mutex::eMutexTypeRecursive)
-
- {
- }
+ SectionLoadList() : m_addr_to_sect(), m_sect_to_addr(), m_mutex() {}
SectionLoadList (const SectionLoadList& rhs);
@@ -84,7 +78,7 @@ protected:
typedef llvm::DenseMap<const Section *, lldb::addr_t> sect_to_addr_collection;
addr_to_sect_collection m_addr_to_sect;
sect_to_addr_collection m_sect_to_addr;
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
};
} // namespace lldb_private
diff --git a/include/lldb/Target/StackFrame.h b/include/lldb/Target/StackFrame.h
index b65b01810176..b3cc57f176ca 100644
--- a/include/lldb/Target/StackFrame.h
+++ b/include/lldb/Target/StackFrame.h
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <memory>
+#include <mutex>
// Other libraries and framework includes
// Project includes
@@ -289,7 +290,7 @@ public:
/// A pointer to a list of variables.
//------------------------------------------------------------------
lldb::VariableListSP
- GetInScopeVariableList (bool get_file_globals);
+ GetInScopeVariableList (bool get_file_globals, bool must_have_valid_location = false);
//------------------------------------------------------------------
/// Create a ValueObject for a variable name / pathname, possibly
@@ -478,6 +479,11 @@ public:
lldb::LanguageType
GetLanguage ();
+ // similar to GetLanguage(), but is allowed to take a potentially incorrect guess
+ // if exact information is not available
+ lldb::LanguageType
+ GuessLanguage ();
+
//------------------------------------------------------------------
// lldb::ExecutionContextScope pure virtual functions
//------------------------------------------------------------------
@@ -532,7 +538,7 @@ private:
lldb::VariableListSP m_variable_list_sp;
ValueObjectList m_variable_list_value_objects; // Value objects for each variable in m_variable_list_sp
StreamString m_disassembly;
- Mutex m_mutex;
+ std::recursive_mutex m_mutex;
DISALLOW_COPY_AND_ASSIGN (StackFrame);
};
diff --git a/include/lldb/Target/StackFrameList.h b/include/lldb/Target/StackFrameList.h
index 50a656de9e69..8b6bea3193c5 100644
--- a/include/lldb/Target/StackFrameList.h
+++ b/include/lldb/Target/StackFrameList.h
@@ -13,11 +13,11 @@
// C Includes
// C++ Includes
#include <memory>
+#include <mutex>
#include <vector>
// Other libraries and framework includes
// Project includes
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/StackFrame.h"
namespace lldb_private {
@@ -135,7 +135,7 @@ protected:
Thread &m_thread;
lldb::StackFrameListSP m_prev_frames_sp;
- mutable Mutex m_mutex;
+ mutable std::recursive_mutex m_mutex;
collection m_frames;
uint32_t m_selected_frame_idx;
uint32_t m_concrete_frames_fetched;
diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h
index 0cdb248a9b44..7124b2e83467 100644
--- a/include/lldb/Target/Target.h
+++ b/include/lldb/Target/Target.h
@@ -53,9 +53,22 @@ typedef enum LoadScriptFromSymFile
eLoadScriptFromSymFileWarn
} LoadScriptFromSymFile;
+typedef enum LoadCWDlldbinitFile
+{
+ eLoadCWDlldbinitTrue,
+ eLoadCWDlldbinitFalse,
+ eLoadCWDlldbinitWarn
+} LoadCWDlldbinitFile;
+
//----------------------------------------------------------------------
// TargetProperties
//----------------------------------------------------------------------
+class TargetExperimentalProperties : public Properties
+{
+public:
+ TargetExperimentalProperties();
+};
+
class TargetProperties : public Properties
{
public:
@@ -142,6 +155,12 @@ public:
GetEnableAutoImportClangModules () const;
bool
+ GetEnableAutoApplyFixIts () const;
+
+ bool
+ GetEnableNotifyAboutFixIts () const;
+
+ bool
GetEnableSyntheticValue () const;
uint32_t
@@ -192,6 +211,9 @@ public:
LoadScriptFromSymFile
GetLoadScriptFromSymbolFile() const;
+ LoadCWDlldbinitFile
+ GetLoadCWDlldbinitFile () const;
+
Disassembler::HexImmediateStyle
GetHexImmediateStyle() const;
@@ -221,6 +243,12 @@ public:
void
SetProcessLaunchInfo(const ProcessLaunchInfo &launch_info);
+
+ bool
+ GetInjectLocalVariables(ExecutionContext *exe_ctx) const;
+
+ void
+ SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b);
private:
//------------------------------------------------------------------
@@ -241,14 +269,17 @@ private:
// Member variables.
//------------------------------------------------------------------
ProcessLaunchInfo m_launch_info;
+ std::unique_ptr<TargetExperimentalProperties> m_experimental_properties_up;
};
class EvaluateExpressionOptions
{
public:
static const uint32_t default_timeout = 500000;
+ static const ExecutionPolicy default_execution_policy = eExecutionPolicyOnlyWhenNeeded;
+
EvaluateExpressionOptions() :
- m_execution_policy(eExecutionPolicyOnlyWhenNeeded),
+ m_execution_policy(default_execution_policy),
m_language (lldb::eLanguageTypeUnknown),
m_prefix (), // A prefix specific to this expression that is added after the prefix from the settings (if any)
m_coerce_to_id (false),
@@ -261,6 +292,7 @@ public:
m_trap_exceptions (true),
m_generate_debug_info (false),
m_result_is_internal (false),
+ m_auto_apply_fixits (true),
m_use_dynamic (lldb::eNoDynamicValues),
m_timeout_usec (default_timeout),
m_one_thread_timeout_usec (0),
@@ -531,6 +563,18 @@ public:
{
return m_result_is_internal;
}
+
+ void
+ SetAutoApplyFixIts(bool b)
+ {
+ m_auto_apply_fixits = b;
+ }
+
+ bool
+ GetAutoApplyFixIts() const
+ {
+ return m_auto_apply_fixits;
+ }
private:
ExecutionPolicy m_execution_policy;
@@ -548,6 +592,7 @@ private:
bool m_generate_debug_info;
bool m_ansi_color_errors;
bool m_result_is_internal;
+ bool m_auto_apply_fixits;
lldb::DynamicValueType m_use_dynamic;
uint32_t m_timeout_usec;
uint32_t m_one_thread_timeout_usec;
@@ -681,8 +726,8 @@ public:
static const lldb::TargetPropertiesSP &
GetGlobalProperties();
- Mutex &
- GetAPIMutex ()
+ std::recursive_mutex &
+ GetAPIMutex()
{
return m_mutex;
}
@@ -709,7 +754,7 @@ public:
Dump (Stream *s, lldb::DescriptionLevel description_level);
const lldb::ProcessSP &
- CreateProcess (Listener &listener,
+ CreateProcess (lldb::ListenerSP listener,
const char *plugin_name,
const FileSpec *crash_file);
@@ -757,6 +802,7 @@ public:
CreateBreakpoint (const FileSpecList *containingModules,
const FileSpec &file,
uint32_t line_no,
+ lldb::addr_t offset,
LazyBool check_inlines,
LazyBool skip_prologue,
bool internal,
@@ -764,9 +810,11 @@ public:
LazyBool move_to_nearest_code);
// Use this to create breakpoint that matches regex against the source lines in files given in source_file_list:
+ // If function_names is non-empty, also filter by function after the matches are made.
lldb::BreakpointSP
CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
const FileSpecList *source_file_list,
+ const std::unordered_set<std::string> &function_names,
RegularExpression &source_regex,
bool internal,
bool request_hardware,
@@ -813,6 +861,7 @@ public:
const char *func_name,
uint32_t func_name_type_mask,
lldb::LanguageType language,
+ lldb::addr_t offset,
LazyBool skip_prologue,
bool internal,
bool request_hardware);
@@ -834,8 +883,9 @@ public:
const FileSpecList *containingSourceFiles,
const char *func_names[],
size_t num_names,
- uint32_t func_name_type_mask,
+ uint32_t func_name_type_mask,
lldb::LanguageType language,
+ lldb::addr_t offset,
LazyBool skip_prologue,
bool internal,
bool request_hardware);
@@ -846,6 +896,7 @@ public:
const std::vector<std::string> &func_names,
uint32_t func_name_type_mask,
lldb::LanguageType language,
+ lldb::addr_t m_offset,
LazyBool skip_prologue,
bool internal,
bool request_hardware);
@@ -1342,7 +1393,8 @@ public:
EvaluateExpression (const char *expression,
ExecutionContextScope *exe_scope,
lldb::ValueObjectSP &result_valobj_sp,
- const EvaluateExpressionOptions& options = EvaluateExpressionOptions());
+ const EvaluateExpressionOptions& options = EvaluateExpressionOptions(),
+ std::string *fixed_expression = nullptr);
lldb::ExpressionVariableSP
GetPersistentVariable(const ConstString &name);
@@ -1555,7 +1607,8 @@ protected:
//------------------------------------------------------------------
Debugger & m_debugger;
lldb::PlatformSP m_platform_sp; ///< The platform for this target.
- Mutex m_mutex; ///< An API mutex that is used by the lldb::SB* classes make the SB interface thread safe
+ std::recursive_mutex
+ m_mutex; ///< An API mutex that is used by the lldb::SB* classes make the SB interface thread safe
ArchSpec m_arch;
ModuleList m_images; ///< The list of images for this process (shared libraries and anything dynamically loaded).
SectionLoadHistory m_section_load_history;
diff --git a/include/lldb/Target/TargetList.h b/include/lldb/Target/TargetList.h
index fddb715b46f3..d96d2f1b0e7a 100644
--- a/include/lldb/Target/TargetList.h
+++ b/include/lldb/Target/TargetList.h
@@ -12,12 +12,12 @@
// C Includes
// C++ Includes
+#include <mutex>
#include <vector>
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Broadcaster.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/Target.h"
namespace lldb_private {
@@ -229,7 +229,7 @@ protected:
//------------------------------------------------------------------
collection m_target_list;
lldb::TargetSP m_dummy_target_sp;
- mutable Mutex m_target_list_mutex;
+ mutable std::recursive_mutex m_target_list_mutex;
uint32_t m_selected_target_idx;
private:
diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h
index ba73e0b49da8..f3cf97325e16 100644
--- a/include/lldb/Target/Thread.h
+++ b/include/lldb/Target/Thread.h
@@ -13,13 +13,13 @@
// C Includes
// C++ Includes
#include <memory>
+#include <mutex>
#include <string>
#include <vector>
// 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/StructuredData.h"
@@ -708,13 +708,15 @@ public:
/// @param[in] module
/// The module to query TLS data for.
///
+ /// @param[in] tls_file_addr
+ /// The thread local address in module
/// @return
/// If the thread has TLS data allocated for the
/// module, the address of the TLS block. Otherwise
/// LLDB_INVALID_ADDRESS is returned.
//------------------------------------------------------------------
virtual lldb::addr_t
- GetThreadLocalData (const lldb::ModuleSP module);
+ GetThreadLocalData(const lldb::ModuleSP module, lldb::addr_t tls_file_addr);
//------------------------------------------------------------------
/// Check whether this thread is safe to run functions
@@ -1446,11 +1448,11 @@ protected:
const uint32_t m_index_id; ///< A unique 1 based index assigned to each thread for easy UI/command line access.
lldb::RegisterContextSP m_reg_context_sp; ///< The register context for this thread's current register state.
lldb::StateType m_state; ///< The state of our process.
- mutable Mutex m_state_mutex; ///< Multithreaded protection for m_state.
+ mutable std::recursive_mutex m_state_mutex; ///< Multithreaded protection for m_state.
plan_stack m_plan_stack; ///< The stack of plans this thread is executing.
plan_stack m_completed_plan_stack; ///< Plans that have been completed by this stop. They get deleted when the thread resumes.
plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this stop. They get deleted when the thread resumes.
- mutable Mutex m_frame_mutex; ///< Multithreaded protection for m_state.
+ mutable std::recursive_mutex m_frame_mutex; ///< Multithreaded protection for m_state.
lldb::StackFrameListSP m_curr_frames_sp; ///< The stack frames that get lazily populated after a thread stops.
lldb::StackFrameListSP m_prev_frames_sp; ///< The previous stack frames from the last time this thread stopped.
int m_resume_signal; ///< The signal that should be used when continuing this thread.
diff --git a/include/lldb/Target/ThreadCollection.h b/include/lldb/Target/ThreadCollection.h
index 0c2b41cc0ca4..f24167f120a8 100644
--- a/include/lldb/Target/ThreadCollection.h
+++ b/include/lldb/Target/ThreadCollection.h
@@ -10,10 +10,10 @@
#ifndef liblldb_ThreadCollection_h_
#define liblldb_ThreadCollection_h_
+#include <mutex>
#include <vector>
#include "lldb/lldb-private.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Utility/Iterable.h"
namespace lldb_private {
@@ -22,8 +22,8 @@ class ThreadCollection
{
public:
typedef std::vector<lldb::ThreadSP> collection;
- typedef LockingAdaptedIterable<collection, lldb::ThreadSP, vector_adapter> ThreadIterable;
-
+ typedef LockingAdaptedIterable<collection, lldb::ThreadSP, vector_adapter, std::recursive_mutex> ThreadIterable;
+
ThreadCollection();
ThreadCollection(collection threads);
@@ -38,7 +38,10 @@ public:
void
AddThread (const lldb::ThreadSP &thread_sp);
-
+
+ void
+ AddThreadSortedByIndexID (const lldb::ThreadSP &thread_sp);
+
void
InsertThread (const lldb::ThreadSP &thread_sp, uint32_t idx);
@@ -53,16 +56,16 @@ public:
{
return ThreadIterable(m_threads, GetMutex());
}
-
- virtual Mutex &
+
+ virtual std::recursive_mutex &
GetMutex()
{
return m_mutex;
}
-
+
protected:
collection m_threads;
- Mutex m_mutex;
+ std::recursive_mutex m_mutex;
};
} // namespace lldb_private
diff --git a/include/lldb/Target/ThreadList.h b/include/lldb/Target/ThreadList.h
index e6489b25e558..140fdaa444d0 100644
--- a/include/lldb/Target/ThreadList.h
+++ b/include/lldb/Target/ThreadList.h
@@ -10,12 +10,14 @@
#ifndef liblldb_ThreadList_h_
#define liblldb_ThreadList_h_
+#include <mutex>
#include <vector>
#include "lldb/lldb-private.h"
#include "lldb/Core/UserID.h"
#include "lldb/Utility/Iterable.h"
#include "lldb/Target/ThreadCollection.h"
+#include "lldb/Target/Thread.h"
namespace lldb_private {
@@ -44,7 +46,43 @@ public:
// selected at index 0.
lldb::ThreadSP
GetSelectedThread ();
+
+ // Manage the thread to use for running expressions. This is usually the Selected thread,
+ // but sometimes (e.g. when evaluating breakpoint conditions & stop hooks) it isn't.
+ class ExpressionExecutionThreadPusher
+ {
+ public:
+ ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid) :
+ m_thread_list(&thread_list),
+ m_tid(tid)
+ {
+ m_thread_list->PushExpressionExecutionThread(m_tid);
+ }
+
+ ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp);
+
+ ~ExpressionExecutionThreadPusher()
+ {
+ if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID)
+ m_thread_list->PopExpressionExecutionThread(m_tid);
+ }
+
+ private:
+ ThreadList *m_thread_list;
+ lldb::tid_t m_tid;
+ };
+ lldb::ThreadSP
+ GetExpressionExecutionThread();
+
+protected:
+ void
+ PushExpressionExecutionThread(lldb::tid_t tid);
+
+ void
+ PopExpressionExecutionThread(lldb::tid_t tid);
+
+public:
bool
SetSelectedThreadByID (lldb::tid_t tid, bool notify = false);
@@ -127,9 +165,9 @@ public:
void
SetStopID (uint32_t stop_id);
- Mutex &
+ std::recursive_mutex &
GetMutex() override;
-
+
void
Update (ThreadList &rhs);
@@ -147,6 +185,7 @@ protected:
Process *m_process; ///< The process that manages this thread list.
uint32_t m_stop_id; ///< The process stop ID that this thread list is valid for.
lldb::tid_t m_selected_tid; ///< For targets that need the notion of a current thread.
+ std::vector<lldb::tid_t> m_expression_tid_stack;
private:
diff --git a/include/lldb/Target/ThreadPlan.h b/include/lldb/Target/ThreadPlan.h
index e6f9aeb78dd6..6dac4a299e52 100644
--- a/include/lldb/Target/ThreadPlan.h
+++ b/include/lldb/Target/ThreadPlan.h
@@ -12,13 +12,13 @@
// C Includes
// C++ Includes
+#include <mutex>
#include <string>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Core/UserID.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
@@ -632,7 +632,7 @@ private:
ThreadPlanKind m_kind;
std::string m_name;
- Mutex m_plan_complete_mutex;
+ std::recursive_mutex m_plan_complete_mutex;
LazyBool m_cached_plan_explains_stop;
bool m_plan_complete;
bool m_plan_private;
diff --git a/include/lldb/Target/ThreadPlanPython.h b/include/lldb/Target/ThreadPlanPython.h
index ab3fbbdf6fb5..8d5b217226f1 100644
--- a/include/lldb/Target/ThreadPlanPython.h
+++ b/include/lldb/Target/ThreadPlanPython.h
@@ -19,7 +19,6 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/UserID.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
diff --git a/include/lldb/Target/ThreadPlanStepInstruction.h b/include/lldb/Target/ThreadPlanStepInstruction.h
index da83ecadcae6..27b9bf1133fe 100644
--- a/include/lldb/Target/ThreadPlanStepInstruction.h
+++ b/include/lldb/Target/ThreadPlanStepInstruction.h
@@ -23,6 +23,12 @@ namespace lldb_private {
class ThreadPlanStepInstruction : public ThreadPlan
{
public:
+ ThreadPlanStepInstruction (Thread &thread,
+ bool step_over,
+ bool stop_others,
+ Vote stop_vote,
+ Vote run_vote);
+
~ThreadPlanStepInstruction() override;
void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
@@ -37,11 +43,6 @@ public:
protected:
bool DoPlanExplainsStop(Event *event_ptr) override;
- ThreadPlanStepInstruction (Thread &thread,
- bool step_over,
- bool stop_others,
- Vote stop_vote,
- Vote run_vote);
void SetUpState ();
private:
diff --git a/include/lldb/Target/Unwind.h b/include/lldb/Target/Unwind.h
index 17c6c0df8207..09ba87a42bbe 100644
--- a/include/lldb/Target/Unwind.h
+++ b/include/lldb/Target/Unwind.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"
namespace lldb_private {
@@ -25,11 +26,7 @@ protected:
//------------------------------------------------------------------
// Classes that inherit from Unwind can see and modify these
//------------------------------------------------------------------
- Unwind(Thread &thread) :
- m_thread (thread),
- m_unwind_mutex(Mutex::eMutexTypeRecursive)
- {
- }
+ Unwind(Thread &thread) : m_thread(thread), m_unwind_mutex() {}
public:
virtual
@@ -40,18 +37,17 @@ public:
void
Clear()
{
- Mutex::Locker locker(m_unwind_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
DoClear();
-
}
uint32_t
GetFrameCount()
{
- Mutex::Locker locker(m_unwind_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
return DoGetFrameCount();
}
-
+
uint32_t
GetFramesUpTo (uint32_t end_idx)
{
@@ -70,21 +66,19 @@ public:
}
bool
- GetFrameInfoAtIndex (uint32_t frame_idx,
- lldb::addr_t& cfa,
- lldb::addr_t& pc)
+ GetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, lldb::addr_t &pc)
{
- Mutex::Locker locker(m_unwind_mutex);
- return DoGetFrameInfoAtIndex (frame_idx, cfa, pc);
+ std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
+ return DoGetFrameInfoAtIndex(frame_idx, cfa, pc);
}
-
+
lldb::RegisterContextSP
- CreateRegisterContextForFrame (StackFrame *frame)
+ CreateRegisterContextForFrame(StackFrame *frame)
{
- Mutex::Locker locker(m_unwind_mutex);
- return DoCreateRegisterContextForFrame (frame);
+ std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
+ return DoCreateRegisterContextForFrame(frame);
}
-
+
Thread &
GetThread()
{
@@ -110,7 +104,8 @@ protected:
DoCreateRegisterContextForFrame (StackFrame *frame) = 0;
Thread &m_thread;
- Mutex m_unwind_mutex;
+ std::recursive_mutex m_unwind_mutex;
+
private:
DISALLOW_COPY_AND_ASSIGN (Unwind);
};
diff --git a/include/lldb/Utility/Iterable.h b/include/lldb/Utility/Iterable.h
index 2317225d126f..0c16a251b7a7 100644
--- a/include/lldb/Utility/Iterable.h
+++ b/include/lldb/Utility/Iterable.h
@@ -16,7 +16,6 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Host/Mutex.h"
namespace lldb_private
{
@@ -207,36 +206,33 @@ public:
return AdaptedConstIterator<C, E, A>(m_container.end());
}
};
-
-template <typename C, typename E, E (*A)(typename C::const_iterator &)> class LockingAdaptedIterable : public AdaptedIterable<C, E, A>
+
+template <typename C, typename E, E (*A)(typename C::const_iterator &), typename MutexType>
+class LockingAdaptedIterable : public AdaptedIterable<C, E, A>
{
public:
- LockingAdaptedIterable (C &container, Mutex &mutex) :
- AdaptedIterable<C,E,A>(container),
- m_mutex(&mutex)
+ LockingAdaptedIterable(C &container, MutexType &mutex) : AdaptedIterable<C, E, A>(container), m_mutex(&mutex)
{
- m_mutex->Lock();
+ m_mutex->lock();
}
-
- LockingAdaptedIterable (LockingAdaptedIterable &&rhs) :
- AdaptedIterable<C,E,A>(rhs),
- m_mutex(rhs.m_mutex)
+
+ LockingAdaptedIterable(LockingAdaptedIterable &&rhs) : AdaptedIterable<C, E, A>(rhs), m_mutex(rhs.m_mutex)
{
rhs.m_mutex = nullptr;
}
-
- ~LockingAdaptedIterable ()
+
+ ~LockingAdaptedIterable()
{
if (m_mutex)
- m_mutex->Unlock();
+ m_mutex->unlock();
}
-
+
private:
- Mutex *m_mutex = nullptr;
+ MutexType *m_mutex = nullptr;
DISALLOW_COPY_AND_ASSIGN(LockingAdaptedIterable);
};
-
+
} // namespace lldb_private
#endif // liblldb_Iterable_h_
diff --git a/include/lldb/Utility/ProcessStructReader.h b/include/lldb/Utility/ProcessStructReader.h
index 80f90feb87ab..bbb497cd51cb 100644
--- a/include/lldb/Utility/ProcessStructReader.h
+++ b/include/lldb/Utility/ProcessStructReader.h
@@ -94,6 +94,15 @@ namespace lldb_private {
return fail_value;
return (RetType)(m_data.GetMaxU64(&offset, size));
}
+
+ size_t
+ GetOffsetOf(ConstString name, size_t fail_value = SIZE_MAX)
+ {
+ auto iter = m_fields.find(name), end = m_fields.end();
+ if (iter == end)
+ return fail_value;
+ return iter->second.offset;
+ }
};
}
diff --git a/include/lldb/Utility/SharedCluster.h b/include/lldb/Utility/SharedCluster.h
index 2c03c409d97e..dfcc119e14bf 100644
--- a/include/lldb/Utility/SharedCluster.h
+++ b/include/lldb/Utility/SharedCluster.h
@@ -10,8 +10,8 @@
#ifndef utility_SharedCluster_h_
#define utility_SharedCluster_h_
+#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/SharingPtr.h"
-#include "lldb/Host/Mutex.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -46,14 +46,12 @@ template <class T>
class ClusterManager
{
public:
- ClusterManager () :
- m_objects(),
- m_external_ref(0),
- m_mutex(Mutex::eMutexTypeNormal) {}
-
- ~ClusterManager ()
+ ClusterManager() : m_objects(), m_external_ref(0), m_mutex() {}
+
+ ~ClusterManager()
{
- for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(), end = m_objects.end(); pos != end; ++pos)
+ for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(), end = m_objects.end(); pos != end;
+ ++pos)
{
T *object = *pos;
delete object;
@@ -62,42 +60,48 @@ public:
// Decrement refcount should have been called on this ClusterManager,
// and it should have locked the mutex, now we will unlock it before
// we destroy it...
- m_mutex.Unlock();
+ m_mutex.unlock();
}
-
- void ManageObject (T *new_object)
+
+ void
+ ManageObject(T *new_object)
{
- Mutex::Locker locker (m_mutex);
- m_objects.insert (new_object);
+ std::lock_guard<std::mutex> guard(m_mutex);
+ m_objects.insert(new_object);
}
-
- typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object)
+
+ typename lldb_private::SharingPtr<T>
+ GetSharedPointer(T *desired_object)
{
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
m_external_ref++;
- assert (m_objects.count(desired_object));
+ if (0 == m_objects.count(desired_object))
+ {
+ lldbassert(false && "object not found in shared cluster when expected");
+ desired_object = nullptr;
+ }
}
- return typename lldb_private::SharingPtr<T> (desired_object, new imp::shared_ptr_refcount<ClusterManager> (this));
+ return typename lldb_private::SharingPtr<T>(desired_object, new imp::shared_ptr_refcount<ClusterManager>(this));
}
-
+
private:
-
- void DecrementRefCount ()
+ void
+ DecrementRefCount()
{
- m_mutex.Lock();
+ m_mutex.lock();
m_external_ref--;
if (m_external_ref == 0)
delete this;
else
- m_mutex.Unlock();
+ m_mutex.unlock();
}
-
+
friend class imp::shared_ptr_refcount<ClusterManager>;
-
+
llvm::SmallPtrSet<T *, 16> m_objects;
int m_external_ref;
- Mutex m_mutex;
+ std::mutex m_mutex;
};
} // namespace lldb_private
diff --git a/include/lldb/lldb-enumerations.h b/include/lldb/lldb-enumerations.h
index ea31752b09be..d8f076f00b0e 100644
--- a/include/lldb/lldb-enumerations.h
+++ b/include/lldb/lldb-enumerations.h
@@ -271,17 +271,17 @@ namespace lldb {
eErrorTypeWin32 ///< Standard Win32 error codes.
};
-
enum ValueType
{
- eValueTypeInvalid = 0,
- eValueTypeVariableGlobal = 1, // globals variable
- eValueTypeVariableStatic = 2, // static variable
- eValueTypeVariableArgument = 3, // function argument variables
- eValueTypeVariableLocal = 4, // function local variables
- eValueTypeRegister = 5, // stack frame register value
- eValueTypeRegisterSet = 6, // A collection of stack frame register values
- eValueTypeConstResult = 7 // constant result variables
+ eValueTypeInvalid = 0,
+ eValueTypeVariableGlobal = 1, // globals variable
+ eValueTypeVariableStatic = 2, // static variable
+ eValueTypeVariableArgument = 3, // function argument variables
+ eValueTypeVariableLocal = 4, // function local variables
+ eValueTypeRegister = 5, // stack frame register value
+ eValueTypeRegisterSet = 6, // A collection of stack frame register values
+ eValueTypeConstResult = 7, // constant result variables
+ eValueTypeVariableThreadLocal = 8 // thread local storage variable
};
//----------------------------------------------------------------------
@@ -378,7 +378,7 @@ namespace lldb {
///
/// These enumerations use the same language enumerations as the DWARF
/// specification for ease of use and consistency.
- /// The enum -> string code is in LanguageRuntime.cpp, don't change this
+ /// The enum -> string code is in Language.cpp, don't change this
/// table without updating that code as well.
//----------------------------------------------------------------------
enum LanguageType
@@ -434,6 +434,7 @@ namespace lldb {
enum InstrumentationRuntimeType
{
eInstrumentationRuntimeTypeAddressSanitizer = 0x0000,
+ eInstrumentationRuntimeTypeThreadSanitizer = 0x0001,
eNumInstrumentationRuntimeTypes
};
@@ -453,7 +454,7 @@ namespace lldb {
eAccessPackage
};
- enum CommandArgumentType
+ enum CommandArgumentType
{
eArgTypeAddress = 0,
eArgTypeAddressOrExpression,
@@ -538,7 +539,8 @@ namespace lldb {
eArgTypeWatchpointID,
eArgTypeWatchpointIDRange,
eArgTypeWatchType,
- eArgTypeLastArg // Always keep this entry as the last entry in this enumeration!!
+ eArgRawInput,
+ eArgTypeLastArg // Always keep this entry as the last entry in this enumeration!!
};
//----------------------------------------------------------------------
@@ -622,6 +624,7 @@ namespace lldb {
eSectionTypeARMextab,
eSectionTypeCompactUnwind, // compact unwind section in Mach-O, __TEXT,__unwind_info
eSectionTypeGoSymtab,
+ eSectionTypeAbsoluteAddress, // Dummy section for symbols with absolute address
eSectionTypeOther
};
diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h
index 516f31911c2b..cb7979370849 100644
--- a/include/lldb/lldb-forward.h
+++ b/include/lldb/lldb-forward.h
@@ -59,6 +59,7 @@ class ClangPersistentVariables;
class CommandInterpreter;
class CommandInterpreterRunOptions;
class CommandObject;
+class CommandObjectMultiword;
class CommandReturnObject;
class Communication;
class CompactUnwindInfo;
@@ -79,6 +80,7 @@ class DataEncoder;
class DataExtractor;
class Debugger;
class Declaration;
+class DiagnosticManager;
class Disassembler;
class DumpValueObjectOptions;
class DynamicCheckerFunctions;
@@ -310,6 +312,8 @@ namespace lldb {
typedef std::weak_ptr<lldb_private::BreakpointLocation> BreakpointLocationWP;
typedef std::shared_ptr<lldb_private::BreakpointResolver> BreakpointResolverSP;
typedef std::shared_ptr<lldb_private::Broadcaster> BroadcasterSP;
+ typedef std::shared_ptr<lldb_private::BroadcasterManager> BroadcasterManagerSP;
+ typedef std::weak_ptr<lldb_private::BroadcasterManager> BroadcasterManagerWP;
typedef std::unique_ptr<lldb_private::ClangASTContext> ClangASTContextUP;
typedef std::shared_ptr<lldb_private::ClangASTImporter> ClangASTImporterSP;
typedef std::unique_ptr<lldb_private::ClangModulesDeclVendor> ClangModulesDeclVendorUP;
@@ -328,6 +332,7 @@ namespace lldb {
typedef std::shared_ptr<lldb_private::DynamicLoader> DynamicLoaderSP;
typedef std::unique_ptr<lldb_private::DynamicLoader> DynamicLoaderUP;
typedef std::shared_ptr<lldb_private::Event> EventSP;
+ typedef std::shared_ptr<lldb_private::EventData> EventDataSP;
typedef std::shared_ptr<lldb_private::ExecutionContextRef> ExecutionContextRefSP;
typedef std::shared_ptr<lldb_private::ExpressionVariable> ExpressionVariableSP;
typedef std::shared_ptr<lldb_private::File> FileSP;
@@ -348,8 +353,11 @@ namespace lldb {
typedef std::unique_ptr<lldb_private::SystemRuntime> SystemRuntimeUP;
typedef std::shared_ptr<lldb_private::LineTable> LineTableSP;
typedef std::shared_ptr<lldb_private::Listener> ListenerSP;
+ typedef std::weak_ptr<lldb_private::Listener> ListenerWP;
typedef std::shared_ptr<lldb_private::LogChannel> LogChannelSP;
typedef std::shared_ptr<lldb_private::MemoryHistory> MemoryHistorySP;
+ typedef std::shared_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoSP;
+ typedef std::unique_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoUP;
typedef std::shared_ptr<lldb_private::Module> ModuleSP;
typedef std::weak_ptr<lldb_private::Module> ModuleWP;
typedef std::shared_ptr<lldb_private::ObjectFile> ObjectFileSP;
diff --git a/include/lldb/lldb-private-defines.h b/include/lldb/lldb-private-defines.h
new file mode 100644
index 000000000000..4b261ad4712b
--- /dev/null
+++ b/include/lldb/lldb-private-defines.h
@@ -0,0 +1,39 @@
+//===-- lldb-private-defines.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_lldb_private_defines_h_
+#define liblldb_lldb_private_defines_h_
+
+#if defined(__cplusplus)
+
+// Include Compiler.h here so we don't define LLVM_FALLTHROUGH and then Compiler.h
+// later tries to redefine it.
+#include "llvm/Support/Compiler.h"
+
+#ifndef LLVM_FALLTHROUGH
+
+#ifndef __has_cpp_attribute
+# define __has_cpp_attribute(x) 0
+#endif
+
+/// \macro LLVM_FALLTHROUGH
+/// \brief Marks an empty statement preceding a deliberate switch fallthrough.
+#if __has_cpp_attribute(clang::fallthrough)
+#define LLVM_FALLTHROUGH [[clang::fallthrough]]
+#else
+#define LLVM_FALLTHROUGH
+#endif
+
+#endif // ifndef LLVM_FALLTHROUGH
+
+
+
+#endif // #if defined(__cplusplus)
+
+#endif // liblldb_lldb_private_defines_h_
diff --git a/include/lldb/lldb-private-enumerations.h b/include/lldb/lldb-private-enumerations.h
index 5f8f96c6da46..366970a39f2f 100644
--- a/include/lldb/lldb-private-enumerations.h
+++ b/include/lldb/lldb-private-enumerations.h
@@ -164,11 +164,12 @@ typedef enum FormatCategoryItem
//------------------------------------------------------------------
/// Expression execution policies
-//------------------------------------------------------------------
+//------------------------------------------------------------------
typedef enum {
eExecutionPolicyOnlyWhenNeeded,
eExecutionPolicyNever,
- eExecutionPolicyAlways
+ eExecutionPolicyAlways,
+ eExecutionPolicyTopLevel // used for top-level code
} ExecutionPolicy;
//----------------------------------------------------------------------
diff --git a/include/lldb/lldb-private-interfaces.h b/include/lldb/lldb-private-interfaces.h
index 6bc8dadaebff..8775ce6bc565 100644
--- a/include/lldb/lldb-private-interfaces.h
+++ b/include/lldb/lldb-private-interfaces.h
@@ -35,7 +35,7 @@ namespace lldb_private
typedef lldb::CommandObjectSP (*LanguageRuntimeGetCommandObject) (CommandInterpreter& interpreter);
typedef SystemRuntime *(*SystemRuntimeCreateInstance) (Process *process);
typedef lldb::PlatformSP (*PlatformCreateInstance) (bool force, const ArchSpec *arch);
- typedef lldb::ProcessSP (*ProcessCreateInstance) (lldb::TargetSP target_sp, Listener &listener, const FileSpec *crash_file_path);
+ typedef lldb::ProcessSP (*ProcessCreateInstance) (lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path);
typedef lldb::ScriptInterpreterSP (*ScriptInterpreterCreateInstance)(CommandInterpreter &interpreter);
typedef SymbolFile* (*SymbolFileCreateInstance) (ObjectFile* obj_file);
typedef SymbolVendor* (*SymbolVendorCreateInstance) (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm); // Module can be NULL for default system symbol vendor
diff --git a/include/lldb/lldb-private-types.h b/include/lldb/lldb-private-types.h
index 685034a1fee3..bdcf532b4305 100644
--- a/include/lldb/lldb-private-types.h
+++ b/include/lldb/lldb-private-types.h
@@ -103,6 +103,7 @@ namespace lldb_private
};
typedef struct type128 { uint64_t x[2]; } type128;
+ typedef struct type256 { uint64_t x[4]; } type256;
} // namespace lldb_private
diff --git a/include/lldb/lldb-private.h b/include/lldb/lldb-private.h
index 951b22fc94c5..cd6f1470e81d 100644
--- a/include/lldb/lldb-private.h
+++ b/include/lldb/lldb-private.h
@@ -24,6 +24,7 @@
#include "lldb/lldb-private-enumerations.h"
#include "lldb/lldb-private-interfaces.h"
#include "lldb/lldb-private-types.h"
+#include "lldb/lldb-private-defines.h"
namespace lldb_private {
diff --git a/lib/Makefile b/lib/Makefile
deleted file mode 100644
index e2388e05833e..000000000000
--- a/lib/Makefile
+++ /dev/null
@@ -1,217 +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.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL := ../../..
-LLDB_LEVEL := ..
-
-LIBRARYNAME = lldb
-
-#EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/resources/lldb-framework-exports
-NO_BUILD_ARCHIVE = 1
-LINK_LIBS_IN_SHARED = 1
-SHARED_LIBRARY = 1
-
-ifeq (,$(findstring -DLLDB_DISABLE_PYTHON,$(CXXFLAGS)))
-PYTHON_CONFIG?= python-config
-PYTHON_BUILD_FLAGS = $(shell $(PYTHON_CONFIG) --ldflags)
-endif
-
-# Include all archives in liblldb.so file
-USEDLIBS = lldbAPI.a \
- lldbBreakpoint.a \
- lldbCommands.a \
- lldbCore.a \
- lldbDataFormatters.a \
- lldbExpression.a \
- lldbInitialization.a \
- lldbHost.a \
- lldbBase.a \
- lldbInterpreter.a \
- lldbPluginABIMacOSX_arm.a \
- lldbPluginABIMacOSX_arm64.a \
- lldbPluginABIMacOSX_i386.a \
- lldbPluginABISysV_arm.a \
- lldbPluginABISysV_arm64.a \
- lldbPluginABISysV_ppc.a \
- lldbPluginABISysV_ppc64.a \
- lldbPluginABISysV_mips.a \
- lldbPluginABISysV_mips64.a \
- lldbPluginABISysV_i386.a \
- lldbPluginABISysV_x86_64.a \
- lldbPluginABISysV_hexagon.a \
- lldbPluginDisassemblerLLVM.a \
- lldbPluginDynamicLoaderStatic.a \
- lldbPluginDynamicLoaderPosixDYLD.a \
- lldbPluginDynamicLoaderHexagon.a \
- lldbPluginDynamicLoaderMacOSXDYLD.a \
- lldbPluginDynamicLoaderWindowsDYLD.a \
- lldbPluginExpressionParserClang.a \
- lldbPluginExpressionParserGo.a \
- lldbPluginInstructionARM.a \
- lldbPluginInstructionARM64.a \
- lldbPluginInstructionMIPS.a \
- lldbPluginInstructionMIPS64.a \
- lldbPluginInstrumentationRuntimeAddressSanitizer.a \
- lldbPluginCXXItaniumABI.a \
- lldbPluginAppleObjCRuntime.a \
- lldbPluginRenderScriptRuntime.a \
- lldbPluginMemoryHistoryASan.a \
- lldbPluginCPlusPlusLanguage.a \
- lldbPluginLanguageRuntimeGo.a \
- lldbPluginObjCLanguage.a \
- lldbPluginObjCPlusPlusLanguage.a \
- lldbPluginGoLanguage.a \
- lldbPluginObjectContainerBSDArchive.a \
- lldbPluginObjectContainerMachOArchive.a \
- lldbPluginObjectFileELF.a \
- lldbPluginObjectFileJIT.a \
- lldbPluginSymbolVendorELF.a \
- lldbPluginObjectFilePECOFF.a \
- lldbPluginOSGo.a \
- lldbPluginOSPython.a \
- lldbPluginPlatformGDB.a \
- lldbPluginProcessElfCore.a \
- lldbPluginProcessGDBRemote.a \
- lldbPluginSymbolFileDWARF.a \
- lldbPluginSymbolFileSymtab.a \
- lldbPluginSystemRuntimeMacOSX.a \
- lldbPluginUnwindAssemblyInstEmulation.a \
- lldbPluginUnwindAssemblyX86.a \
- lldbPluginProcessUtility.a \
- lldbSymbol.a \
- lldbTarget.a \
- lldbUtility.a \
- clangAnalysis.a \
- clangAST.a \
- clangBasic.a \
- clangCodeGen.a \
- clangFrontend.a \
- clangDriver.a \
- clangEdit.a \
- clangLex.a \
- clangParse.a \
- clangSema.a \
- clangSerialization.a \
- LLVMMCDisassembler.a \
- LLVMProfileData.a \
- LLVMObjCARCOpts.a \
- lldbPluginPlatformMacOSX.a \
- lldbPluginPlatformLinux.a \
- lldbPluginPlatformWindows.a \
- lldbPluginPlatformFreeBSD.a \
- lldbPluginPlatformNetBSD.a \
- lldbPluginPlatformPOSIX.a \
- lldbPluginPlatformKalimba.a \
- lldbPluginPlatformAndroid.a \
- lldbPluginJITLoaderGDB.a \
- lldbPluginScriptInterpreterNone.a \
- lldbPluginScriptInterpreterPython.a
-
-# Because GCC requires RTTI enabled for lldbCore (see source/Core/Makefile) it is
-# necessary to also link the clang rewriter libraries so vtable references can
-# be resolved correctly, if we are building with GCC.
-ifeq (g++,$(shell basename $(CXX) | cut -c 1-4))
- USEDLIBS += clangRewrite.a \
- clangRewriteFrontend.a
-endif
-
-include $(LLDB_LEVEL)/../../Makefile.config
-
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \
- instrumentation ipo irreader selectiondag mc mcjit \
- linker option
-
-ifeq ($(HOST_OS),Darwin)
- USEDLIBS += lldbPluginDynamicLoaderDarwinKernel.a \
- lldbPluginObjectFileMachO.a \
- lldbPluginSymbolVendorMacOSX.a \
- lldbPluginProcessDarwin.a \
- lldbPluginProcessMachCore.a
-endif
-
-ifeq ($(HOST_OS),Linux)
- USEDLIBS += lldbPluginProcessLinux.a \
- lldbPluginProcessPOSIX.a
-endif
-
-ifneq (,$(filter $(HOST_OS), FreeBSD GNU/kFreeBSD))
- USEDLIBS += lldbPluginProcessPOSIX.a \
- lldbPluginProcessFreeBSD.a
-endif
-
-ifeq ($(HOST_OS),NetBSD)
- USEDLIBS += lldbPluginProcessPOSIX.a
-endif
-
-include $(LEVEL)/Makefile.common
-
-ifeq ($(HOST_OS),MingW)
- LLVMLibsOptions += -lws2_32
- # Include everything from the .a's into the shared library.
- ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \
- -Wl,--no-whole-archive
-endif
-
-ifeq ($(HOST_OS),Darwin)
- LLVMLibsOptions += -Wl,-all_load
- # set dylib internal version number to llvmCore submission number
- ifdef LLDB_SUBMIT_VERSION
- LLVMLibsOptions += -Wl,-current_version \
- -Wl,$(LLDB_SUBMIT_VERSION).$(LLDB_SUBMIT_SUBVERSION) \
- -Wl,-compatibility_version -Wl,1
- endif
- # extra options to override libtool defaults
- LLVMLibsOptions += -F/System/Library/Frameworks -F/System/Library/PrivateFrameworks
- LLVMLibsOptions += -framework Foundation -framework CoreFoundation
- LLVMLibsOptions += -framework CoreServices -framework Carbon -framework Security
- LLVMLibsOptions += -framework DebugSymbols $(PYTHON_BUILD_FLAGS) -lobjc
- LLVMLibsOptions += -lxml2 -ledit -lpanel -lcurses
- ifneq ($(EXPORTED_SYMBOL_FILE),)
- LLVMLibsOptions += -Wl,-exported_symbols_list -Wl,"$(EXPORTED_SYMBOL_FILE)"
- endif
- # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line
- DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/')
- ifneq ($(DARWIN_VERS),8)
- LLVMLibsOptions += -Wl,-install_name \
- -Wl,"@executable_path/../lib/lib$(LIBRARYNAME)$(SHLIBEXT)"
- endif
-endif
-
-ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux GNU GNU/kFreeBSD))
- # Include everything from the .a's into the shared library.
- ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \
- -Wl,--no-whole-archive
- # Don't allow unresolved symbols.
- LLVMLibsOptions += -Wl,--no-undefined
- # Link in python
- LLVMLibsOptions += $(PYTHON_BUILD_FLAGS) -lrt -ledit -lncurses -lpanel -lpthread
- LLVMLibsOptions += -Wl,--soname,lib$(LIBRARYNAME)$(SHLIBEXT)
-endif
-
-ifeq ($(HOST_OS),FreeBSD)
- # Include everything from the .a's into the shared library.
- ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \
- -Wl,--no-whole-archive
- # Allow unresolved symbols.
- LLVMLibsOptions += -Wl,--allow-shlib-undefined
- # Link in python
- LLVMLibsOptions += $(PYTHON_BUILD_FLAGS) -lrt -L/usr/local/lib -lexecinfo \
- -ledit -lncurses -lpanel -lpthread
-endif
-
-ifeq ($(HOST_OS),NetBSD)
- # Include everything from the .a's into the shared library.
- ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \
- -Wl,--no-whole-archive
- # Allow unresolved symbols.
- LLVMLibsOptions += -Wl,--allow-shlib-undefined
- # Link in python
- LLVMLibsOptions += $(PYTHON_BUILD_FLAGS) -lrt -L/usr/pkg/lib -lexecinfo \
- -ledit -lcurses -lpthread -lkvm -Wl,-rpath,/usr/pkg/lib
-endif
diff --git a/lit/CMakeLists.txt b/lit/CMakeLists.txt
index 108fc9368732..48f778fbe3d2 100644
--- a/lit/CMakeLists.txt
+++ b/lit/CMakeLists.txt
@@ -33,4 +33,4 @@ add_lit_testsuite(check-lldb-unit "Running lldb unit test suite"
DEPENDS ${LLDB_TEST_DEPS}
)
-set_target_properties(check-lldb-unit PROPERTIES FOLDER "lldb tests")
+set_target_properties(check-lldb-unit PROPERTIES FOLDER "LLDB tests")
diff --git a/lit/Unit/lit.site.cfg.in b/lit/Unit/lit.site.cfg.in
index 61c8179af39e..6d83023c54cb 100644
--- a/lit/Unit/lit.site.cfg.in
+++ b/lit/Unit/lit.site.cfg.in
@@ -1,5 +1,5 @@
-## Autogenerated by LLVM/lld configuration.
-# Do not edit!
+@LIT_SITE_CFG_IN_HEADER@
+
config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
diff --git a/lit/lit.site.cfg.in b/lit/lit.site.cfg.in
index 10f3033da4af..f4105500c9f1 100644
--- a/lit/lit.site.cfg.in
+++ b/lit/lit.site.cfg.in
@@ -1,5 +1,5 @@
-## Autogenerated by LLVM/lldb configuration.
-# Do not edit!
+@LIT_SITE_CFG_IN_HEADER@
+
config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj
index 6c73ccd0801e..c031d9df58aa 100644
--- a/lldb.xcodeproj/project.pbxproj
+++ b/lldb.xcodeproj/project.pbxproj
@@ -43,6 +43,7 @@
AF3059151B4B390800E25622 /* Run Script - remove unneeded Resources and Swift dirs from iOS LLDB.framework bundle */,
);
dependencies = (
+ AFCA21D21D18E556004386B8 /* PBXTargetDependency */,
26CEF3C214FD5973007286B2 /* PBXTargetDependency */,
2687EACF1508116300DD8C2E /* PBXTargetDependency */,
);
@@ -72,6 +73,7 @@
236124A41986B4E2004EFC37 /* IOObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 236124A21986B4E2004EFC37 /* IOObject.cpp */; };
236124A51986B4E2004EFC37 /* Socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 236124A31986B4E2004EFC37 /* Socket.cpp */; };
2377C2F819E613C100737875 /* PipePosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2377C2F719E613C100737875 /* PipePosix.cpp */; };
+ 239481861C59EBDD00DF7168 /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 239481851C59EBDD00DF7168 /* libncurses.dylib */; };
239504DE1BDD453200963CEA /* SocketAddressTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2321F9391BDD332400BA9A93 /* SocketAddressTest.cpp */; };
239504DF1BDD453200963CEA /* SocketTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2321F93A1BDD332400BA9A93 /* SocketTest.cpp */; };
239504E01BDD453200963CEA /* SymbolsTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2321F93B1BDD332400BA9A93 /* SymbolsTest.cpp */; };
@@ -82,6 +84,8 @@
239504E51BDD454B00963CEA /* UriParserTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2321F9461BDD346100BA9A93 /* UriParserTest.cpp */; };
23D4007D1C2101F2000C3885 /* DWARFDebugMacro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23E77CD61C20F29F007192AD /* DWARFDebugMacro.cpp */; };
23D4007E1C210201000C3885 /* DebugMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23E77CDB1C20F2F2007192AD /* DebugMacros.cpp */; };
+ 23DCEA461D1C4D0F00A602B4 /* SBMemoryRegionInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23DCEA421D1C4C6900A602B4 /* SBMemoryRegionInfo.cpp */; };
+ 23DCEA471D1C4D0F00A602B4 /* SBMemoryRegionInfoList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23DCEA431D1C4C6900A602B4 /* SBMemoryRegionInfoList.cpp */; };
23DDF226196C3EE600BB8417 /* CommandOptionValidators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23DDF224196C3EE600BB8417 /* CommandOptionValidators.cpp */; };
23EFE389193D1ABC00E54E54 /* SBTypeEnumMember.h in Headers */ = {isa = PBXBuildFile; fileRef = 23EFE388193D1ABC00E54E54 /* SBTypeEnumMember.h */; settings = {ATTRIBUTES = (Public, ); }; };
23EFE38B193D1AEC00E54E54 /* SBTypeEnumMember.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23EFE38A193D1AEC00E54E54 /* SBTypeEnumMember.cpp */; };
@@ -95,7 +99,6 @@
254FBBA51A91670E00BD6378 /* SBAttachInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 254FBBA41A91670E00BD6378 /* SBAttachInfo.cpp */; };
255EFF741AFABA720069F277 /* LockFileBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 255EFF731AFABA720069F277 /* LockFileBase.cpp */; };
255EFF761AFABA950069F277 /* LockFilePosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 255EFF751AFABA950069F277 /* LockFilePosix.cpp */; };
- 256CBDB11ADD0E1700BC6CDC /* NativeRegisterContextLinux_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 256CBDAB1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm.cpp */; };
256CBDB41ADD0EFD00BC6CDC /* RegisterContextPOSIXCore_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 256CBDB21ADD0EFD00BC6CDC /* RegisterContextPOSIXCore_arm.cpp */; };
256CBDBA1ADD107200BC6CDC /* RegisterContextLinux_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 256CBDB61ADD107200BC6CDC /* RegisterContextLinux_arm.cpp */; };
256CBDBC1ADD107200BC6CDC /* RegisterContextLinux_mips64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 256CBDB81ADD107200BC6CDC /* RegisterContextLinux_mips64.cpp */; };
@@ -147,6 +150,8 @@
263E949F13661AEA00E7D1CE /* UnwindAssembly-x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263E949D13661AE400E7D1CE /* UnwindAssembly-x86.cpp */; };
263FDE601A79A01500E68013 /* FormatEntity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263FDE5F1A79A01500E68013 /* FormatEntity.cpp */; };
2640E19F15DC78FD00F23B50 /* Property.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2640E19E15DC78FD00F23B50 /* Property.cpp */; };
+ 264297571D1DF247003F2BF4 /* SBMemoryRegionInfoList.h in Headers */ = {isa = PBXBuildFile; fileRef = 264297541D1DF209003F2BF4 /* SBMemoryRegionInfoList.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 264297581D1DF250003F2BF4 /* SBMemoryRegionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 264297531D1DF209003F2BF4 /* SBMemoryRegionInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
2642FBAE13D003B400ED6808 /* CommunicationKDP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2642FBA813D003B400ED6808 /* CommunicationKDP.cpp */; };
2642FBB013D003B400ED6808 /* ProcessKDP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2642FBAA13D003B400ED6808 /* ProcessKDP.cpp */; };
2642FBB213D003B400ED6808 /* ProcessKDPLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2642FBAC13D003B400ED6808 /* ProcessKDPLog.cpp */; };
@@ -290,7 +295,6 @@
266942451A6DC2AC0063BE93 /* MIUtilString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266941EE1A6DC2AC0063BE93 /* MIUtilString.cpp */; };
2669424A1A6DC2AC0063BE93 /* MIUtilThreadBaseStd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266941F81A6DC2AC0063BE93 /* MIUtilThreadBaseStd.cpp */; };
2669424B1A6DC2AC0063BE93 /* MIUtilVariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266941FA1A6DC2AC0063BE93 /* MIUtilVariant.cpp */; };
- 2669424C1A6DC2AC0063BE93 /* Platform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266941FC1A6DC2AC0063BE93 /* Platform.cpp */; };
2669424D1A6DC32B0063BE93 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26680207115FD0ED008E1FE4 /* LLDB.framework */; };
266DFE9713FD656E00D0C574 /* OperatingSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266DFE9613FD656E00D0C574 /* OperatingSystem.cpp */; };
266E82971B8CE3AC008FCA06 /* DWARFDIE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266E82961B8CE3AC008FCA06 /* DWARFDIE.cpp */; };
@@ -306,6 +310,15 @@
267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */; };
267C01371368C49C006E963E /* OptionGroupOutputFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BCFC531368B3E4006DC050 /* OptionGroupOutputFile.cpp */; };
267DFB461B06752A00000FB7 /* MICmdArgValPrintValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267DFB441B06752A00000FB7 /* MICmdArgValPrintValues.cpp */; };
+ 267F684A1CC02DED0086832B /* ABISysV_s390x.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267F68471CC02DED0086832B /* ABISysV_s390x.cpp */; };
+ 267F684B1CC02DED0086832B /* ABISysV_s390x.h in Headers */ = {isa = PBXBuildFile; fileRef = 267F68481CC02DED0086832B /* ABISysV_s390x.h */; };
+ 267F684F1CC02E270086832B /* RegisterContextPOSIXCore_s390x.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267F684D1CC02E270086832B /* RegisterContextPOSIXCore_s390x.cpp */; };
+ 267F68501CC02E270086832B /* RegisterContextPOSIXCore_s390x.h in Headers */ = {isa = PBXBuildFile; fileRef = 267F684E1CC02E270086832B /* RegisterContextPOSIXCore_s390x.h */; };
+ 267F68531CC02E920086832B /* RegisterContextLinux_s390x.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267F68511CC02E920086832B /* RegisterContextLinux_s390x.cpp */; };
+ 267F68541CC02E920086832B /* RegisterContextLinux_s390x.h in Headers */ = {isa = PBXBuildFile; fileRef = 267F68521CC02E920086832B /* RegisterContextLinux_s390x.h */; };
+ 267F68571CC02EAE0086832B /* RegisterContextPOSIX_s390x.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267F68551CC02EAE0086832B /* RegisterContextPOSIX_s390x.cpp */; };
+ 267F68581CC02EAE0086832B /* RegisterContextPOSIX_s390x.h in Headers */ = {isa = PBXBuildFile; fileRef = 267F68561CC02EAE0086832B /* RegisterContextPOSIX_s390x.h */; };
+ 267F685A1CC02EBE0086832B /* RegisterInfos_s390x.h in Headers */ = {isa = PBXBuildFile; fileRef = 267F68591CC02EBE0086832B /* RegisterInfos_s390x.h */; };
268648C416531BF800F04704 /* com.apple.debugserver.posix.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 268648C116531BF800F04704 /* com.apple.debugserver.posix.plist */; };
268648C516531BF800F04704 /* com.apple.debugserver.applist.internal.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 268648C216531BF800F04704 /* com.apple.debugserver.applist.internal.plist */; };
268648C616531BF800F04704 /* com.apple.debugserver.internal.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 268648C316531BF800F04704 /* com.apple.debugserver.internal.plist */; };
@@ -635,10 +648,10 @@
26FFC19914FC072100087D58 /* AuxVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26FFC19314FC072100087D58 /* AuxVector.cpp */; };
26FFC19B14FC072100087D58 /* DYLDRendezvous.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26FFC19514FC072100087D58 /* DYLDRendezvous.cpp */; };
26FFC19D14FC072100087D58 /* DynamicLoaderPOSIXDYLD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26FFC19714FC072100087D58 /* DynamicLoaderPOSIXDYLD.cpp */; };
+ 304B2E461CAAA57B007829FE /* ClangUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3032B1B61CAAA3D1004BE1AB /* ClangUtil.cpp */; };
+ 30B38A001CAAA6D7009524E3 /* ClangUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 3032B1B91CAAA400004BE1AB /* ClangUtil.h */; };
30DED5DE1B4ECB49004CC508 /* MainLoopPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 30DED5DC1B4ECB17004CC508 /* MainLoopPosix.cpp */; };
332CCB181AFF41620034D4C4 /* SBLanguageRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 3392EBB71AFF402200858B9F /* SBLanguageRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 33E5E8421A672A240024ED68 /* StringConvert.cpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 33E5E8411A672A240024ED68 /* StringConvert.cpp */; };
- 33E5E8461A6736D30024ED68 /* StringConvert.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 33E5E8451A6736D30024ED68 /* StringConvert.h */; };
33E5E8471A674FB60024ED68 /* StringConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33E5E8411A672A240024ED68 /* StringConvert.cpp */; };
3F8160A61AB9F7DD001DA9DF /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F8160A51AB9F7DD001DA9DF /* Logging.cpp */; };
3F8169191ABA2419001DA9DF /* ConvertEnum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F8169171ABA2419001DA9DF /* ConvertEnum.cpp */; };
@@ -648,12 +661,7 @@
3F8169321ABB7A6D001DA9DF /* SystemInitializerCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F81692F1ABB7A6D001DA9DF /* SystemInitializerCommon.cpp */; };
3F8169331ABB7A6D001DA9DF /* SystemLifetimeManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F8169301ABB7A6D001DA9DF /* SystemLifetimeManager.cpp */; };
3FA093151BF65D3A0037DD08 /* PythonExceptionStateTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FA093141BF65D3A0037DD08 /* PythonExceptionStateTests.cpp */; };
- 3FBA69DF1B6067020008F44A /* ScriptInterpreterNone.cpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3FBA69DD1B6067020008F44A /* ScriptInterpreterNone.cpp */; };
- 3FBA69E01B6067020008F44A /* ScriptInterpreterNone.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3FBA69DE1B6067020008F44A /* ScriptInterpreterNone.h */; };
3FBA69E11B6067120008F44A /* ScriptInterpreterNone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FBA69DD1B6067020008F44A /* ScriptInterpreterNone.cpp */; };
- 3FBA69E71B60672A0008F44A /* lldb-python.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3FBA69E21B60672A0008F44A /* lldb-python.h */; };
- 3FBA69E91B60672A0008F44A /* PythonDataObjects.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3FBA69E41B60672A0008F44A /* PythonDataObjects.h */; };
- 3FBA69EB1B60672A0008F44A /* ScriptInterpreterPython.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3FBA69E61B60672A0008F44A /* ScriptInterpreterPython.h */; };
3FBA69EC1B6067430008F44A /* PythonDataObjects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FBA69E31B60672A0008F44A /* PythonDataObjects.cpp */; };
3FBA69ED1B60674B0008F44A /* ScriptInterpreterPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FBA69E51B60672A0008F44A /* ScriptInterpreterPython.cpp */; };
3FDFDDBD199C3A06009756A7 /* FileAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FDFDDBC199C3A06009756A7 /* FileAction.cpp */; };
@@ -678,7 +686,6 @@
494260DA14579144003C1C78 /* VerifyDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 494260D914579144003C1C78 /* VerifyDecl.cpp */; };
4959511F1A1BC4BC00F6F8FC /* ClangModulesDeclVendor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4959511E1A1BC4BC00F6F8FC /* ClangModulesDeclVendor.cpp */; };
4966DCC4148978A10028481B /* ClangExternalASTSourceCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4966DCC3148978A10028481B /* ClangExternalASTSourceCommon.cpp */; };
- 49684D7B1BAB37E400E6D5D5 /* MIUtilParse.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 49684D791BAB37E400E6D5D5 /* MIUtilParse.h */; };
49684D7C1BAB37F200E6D5D5 /* MIUtilParse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49684D781BAB37E400E6D5D5 /* MIUtilParse.cpp */; };
49724D991AD6ED390033C538 /* RenderScriptRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49724D971AD6ED390033C538 /* RenderScriptRuntime.cpp */; };
4984BA131B978C55008658D4 /* ClangExpressionVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4984BA0E1B978C3E008658D4 /* ClangExpressionVariable.cpp */; };
@@ -691,9 +698,13 @@
49DA65031485C92A005FF180 /* AppleObjCDeclVendor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DA65021485C92A005FF180 /* AppleObjCDeclVendor.cpp */; };
49DCF6FE170E6B4A0092F75E /* IRMemoryMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DCF6FD170E6B4A0092F75E /* IRMemoryMap.cpp */; };
49DCF702170E70120092F75E /* Materializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DCF700170E70120092F75E /* Materializer.cpp */; };
+ 49DEF1221CD7BD90006A7C7D /* BlockPointer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 49DEF1201CD7BD90006A7C7D /* BlockPointer.h */; };
+ 49DEF1251CD7C6DF006A7C7D /* BlockPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DEF11F1CD7BD90006A7C7D /* BlockPointer.cpp */; };
+ 49E4F66B1C9CAD16008487EA /* DiagnosticManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49E4F6681C9CAD12008487EA /* DiagnosticManager.cpp */; };
4C0083401B9F9BA900D5CF24 /* UtilityFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00833F1B9F9BA900D5CF24 /* UtilityFunction.cpp */; };
4C2479BD1BA39295009C9A7B /* FunctionCaller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0083321B9A5DE200D5CF24 /* FunctionCaller.cpp */; };
4C3ADCD61810D88B00357218 /* BreakpointResolverFileRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CAA56141422D986001FFA01 /* BreakpointResolverFileRegex.cpp */; };
+ 4C562CC71CC07DF700C52EAC /* PDBASTParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C562CC21CC07DDD00C52EAC /* PDBASTParser.cpp */; };
4C56543119D1EFAA002E9C44 /* ThreadPlanPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C56543019D1EFAA002E9C44 /* ThreadPlanPython.cpp */; };
4C56543519D2297A002E9C44 /* SBThreadPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C56543419D2297A002E9C44 /* SBThreadPlan.h */; settings = {ATTRIBUTES = (Public, ); }; };
4C56543719D22B32002E9C44 /* SBThreadPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C56543619D22B32002E9C44 /* SBThreadPlan.cpp */; };
@@ -713,6 +724,12 @@
4CF3D80C15AF4DC800845BF3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDB919B414F6F10D008FF64B /* Security.framework */; };
4CF52AF51428291E0051E832 /* SBFileSpecList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CF52AF41428291E0051E832 /* SBFileSpecList.h */; settings = {ATTRIBUTES = (Public, ); }; };
4CF52AF8142829390051E832 /* SBFileSpecList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CF52AF7142829390051E832 /* SBFileSpecList.cpp */; };
+ 6D0F61431C80AAAE00A4ECEE /* JavaASTContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D0F61411C80AAAA00A4ECEE /* JavaASTContext.cpp */; };
+ 6D0F61481C80AAD600A4ECEE /* DWARFASTParserJava.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D0F61441C80AACF00A4ECEE /* DWARFASTParserJava.cpp */; };
+ 6D0F614E1C80AB0700A4ECEE /* JavaLanguageRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D0F614A1C80AB0400A4ECEE /* JavaLanguageRuntime.cpp */; };
+ 6D0F614F1C80AB0C00A4ECEE /* JavaLanguageRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D0F614B1C80AB0400A4ECEE /* JavaLanguageRuntime.h */; };
+ 6D0F61591C80AB3500A4ECEE /* JavaFormatterFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D0F61511C80AB3000A4ECEE /* JavaFormatterFunctions.cpp */; };
+ 6D0F615A1C80AB3900A4ECEE /* JavaLanguage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D0F61531C80AB3000A4ECEE /* JavaLanguage.cpp */; };
6D55B2901A8A806200A70529 /* GDBRemoteCommunicationServerCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D55B28D1A8A806200A70529 /* GDBRemoteCommunicationServerCommon.cpp */; };
6D55B2911A8A806200A70529 /* GDBRemoteCommunicationServerLLGS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D55B28E1A8A806200A70529 /* GDBRemoteCommunicationServerLLGS.cpp */; };
6D55B2921A8A806200A70529 /* GDBRemoteCommunicationServerPlatform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D55B28F1A8A806200A70529 /* GDBRemoteCommunicationServerPlatform.cpp */; };
@@ -726,6 +743,7 @@
6D99A3631BBC2F3200979793 /* ArmUnwindInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D99A3621BBC2F3200979793 /* ArmUnwindInfo.cpp */; };
6D9AB3DD1BB2B74E003F2289 /* TypeMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D9AB3DC1BB2B74E003F2289 /* TypeMap.cpp */; };
6DEC6F391BD66D750091ABA6 /* TaskPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6DEC6F381BD66D750091ABA6 /* TaskPool.cpp */; };
+ 8C26C4261C3EA5F90031DF7C /* ThreadSanitizerRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C26C4241C3EA4340031DF7C /* ThreadSanitizerRuntime.cpp */; };
8C2D6A53197A1EAF006989C9 /* MemoryHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */; };
8C2D6A5E197A250F006989C9 /* MemoryHistoryASan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */; };
8CCB017E19BA28A80009FD44 /* ThreadCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CCB017A19BA283D0009FD44 /* ThreadCollection.cpp */; };
@@ -752,8 +770,10 @@
942612F81B952C9B00EF842E /* ObjCLanguage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B6385E1B8FB7A2004FE1E4 /* ObjCLanguage.cpp */; };
942829561A89614C00521B30 /* JSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 942829551A89614C00521B30 /* JSON.cpp */; };
942829CC1A89839300521B30 /* liblldb-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2689FFCA13353D7A00698AC0 /* liblldb-core.a */; };
+ 9428BC2C1C6E64E4002A24D7 /* LibCxxAtomic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9428BC291C6E64DC002A24D7 /* LibCxxAtomic.cpp */; };
94380B8219940B0A00BFE4A8 /* StringLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94380B8119940B0A00BFE4A8 /* StringLexer.cpp */; };
943BDEFE1AA7B2F800789CE8 /* LLDBAssert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 943BDEFD1AA7B2F800789CE8 /* LLDBAssert.cpp */; };
+ 9441816E1C8F5EC900E5A8D9 /* CommandAlias.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9441816D1C8F5EC900E5A8D9 /* CommandAlias.cpp */; };
944372DC171F6B4300E57C32 /* RegisterContextDummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 944372DA171F6B4300E57C32 /* RegisterContextDummy.cpp */; };
9443B122140C18C40013457C /* SBData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9443B121140C18C10013457C /* SBData.cpp */; };
9443B123140C26AB0013457C /* SBData.h in Headers */ = {isa = PBXBuildFile; fileRef = 9443B120140C18A90013457C /* SBData.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -816,6 +836,7 @@
94E829CA152D33C1006F96A3 /* lldb-server in Resources */ = {isa = PBXBuildFile; fileRef = 26DC6A101337FE6900FF7998 /* lldb-server */; };
94F48F251A01C687005C0EC6 /* StringPrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94F48F241A01C687005C0EC6 /* StringPrinter.cpp */; };
94FA3DE01405D50400833217 /* ValueObjectConstResultChild.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */; };
+ 964381701C8D6B8200023D59 /* SBLanguageRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF20F76C1AF18FC700751A6E /* SBLanguageRuntime.cpp */; };
964463EC1A330C0500154ED8 /* CompactUnwindInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 964463EB1A330C0500154ED8 /* CompactUnwindInfo.cpp */; };
966C6B7918E6A56A0093F5EC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 966C6B7818E6A56A0093F5EC /* libz.dylib */; };
966C6B7A18E6A56A0093F5EC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 966C6B7818E6A56A0093F5EC /* libz.dylib */; };
@@ -865,13 +886,14 @@
AF1FA88A1A60A69500272AFC /* RegisterNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF1FA8891A60A69500272AFC /* RegisterNumber.cpp */; };
AF20F7661AF18F8500751A6E /* ABISysV_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF20F7641AF18F8500751A6E /* ABISysV_arm.cpp */; };
AF20F76A1AF18F9000751A6E /* ABISysV_arm64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF20F7681AF18F9000751A6E /* ABISysV_arm64.cpp */; };
- AF20F76D1AF18FC700751A6E /* SBLanguageRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF20F76C1AF18FC700751A6E /* SBLanguageRuntime.cpp */; };
AF20F7701AF1902900751A6E /* RegisterContextLinux_arm64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF20F76E1AF1902900751A6E /* RegisterContextLinux_arm64.cpp */; };
AF23B4DB19009C66003E2A58 /* FreeBSDSignals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF23B4D919009C66003E2A58 /* FreeBSDSignals.cpp */; };
AF254E31170CCC33007AE5C9 /* PlatformDarwinKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF254E2F170CCC33007AE5C9 /* PlatformDarwinKernel.cpp */; };
AF25AB26188F685C0030DEC3 /* AppleGetQueuesHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF25AB24188F685C0030DEC3 /* AppleGetQueuesHandler.cpp */; };
AF26703A1852D01E00B6CC36 /* Queue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF2670381852D01E00B6CC36 /* Queue.cpp */; };
AF26703B1852D01E00B6CC36 /* QueueList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF2670391852D01E00B6CC36 /* QueueList.cpp */; };
+ AF27AD551D3603EA00CF2833 /* DynamicLoaderDarwin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF27AD531D3603EA00CF2833 /* DynamicLoaderDarwin.cpp */; };
+ AF27AD561D3603EA00CF2833 /* DynamicLoaderDarwin.h in Headers */ = {isa = PBXBuildFile; fileRef = AF27AD541D3603EA00CF2833 /* DynamicLoaderDarwin.h */; };
AF2BA6EC1A707E3400C5248A /* UriParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33064C991A5C7A330033D415 /* UriParser.cpp */; };
AF2BCA6C18C7EFDE005B4526 /* JITLoaderGDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF2BCA6918C7EFDE005B4526 /* JITLoaderGDB.cpp */; };
AF33B4BE1C1FA441001B28D9 /* NetBSDSignals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF33B4BC1C1FA441001B28D9 /* NetBSDSignals.cpp */; };
@@ -879,6 +901,8 @@
AF37E10A17C861F20061E18E /* ProcessRunLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF37E10917C861F20061E18E /* ProcessRunLock.cpp */; };
AF45E1FE1BF57C8D000563EB /* PythonTestSuite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF45E1FC1BF57C8D000563EB /* PythonTestSuite.cpp */; };
AF45FDE518A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF45FDE318A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp */; };
+ AF6335E21C87B21E00F7D554 /* SymbolFilePDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF6335E01C87B21E00F7D554 /* SymbolFilePDB.cpp */; };
+ AF6335E31C87B21E00F7D554 /* SymbolFilePDB.h in Headers */ = {isa = PBXBuildFile; fileRef = AF6335E11C87B21E00F7D554 /* SymbolFilePDB.h */; };
AF77E08F1A033C700096C0EA /* ABISysV_ppc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF77E08D1A033C700096C0EA /* ABISysV_ppc.cpp */; };
AF77E0931A033C7F0096C0EA /* ABISysV_ppc64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF77E0911A033C7F0096C0EA /* ABISysV_ppc64.cpp */; };
AF77E0A11A033D360096C0EA /* RegisterContextFreeBSD_powerpc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF77E09A1A033D360096C0EA /* RegisterContextFreeBSD_powerpc.cpp */; };
@@ -898,7 +922,6 @@
AF9107EF168570D200DBCD3C /* RegisterContextDarwin_arm64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF9107EC168570D200DBCD3C /* RegisterContextDarwin_arm64.cpp */; };
AF9B8F33182DB52900DA866F /* SystemRuntimeMacOSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF9B8F31182DB52900DA866F /* SystemRuntimeMacOSX.cpp */; };
AFB3D2801AC262AB003B4B30 /* MICmdCmdGdbShow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFB3D27E1AC262AB003B4B30 /* MICmdCmdGdbShow.cpp */; };
- AFC234081AF85CE000CDE8B6 /* CommandObjectLanguage.cpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = AFC234061AF85CE000CDE8B6 /* CommandObjectLanguage.cpp */; };
AFC234091AF85CE100CDE8B6 /* CommandObjectLanguage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFC234061AF85CE000CDE8B6 /* CommandObjectLanguage.cpp */; };
AFCB2BBD1BF577F40018B553 /* PythonExceptionState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFCB2BBB1BF577F40018B553 /* PythonExceptionState.cpp */; };
AFCB2BBE1BF577F40018B553 /* PythonExceptionState.h in Headers */ = {isa = PBXBuildFile; fileRef = AFCB2BBC1BF577F40018B553 /* PythonExceptionState.h */; };
@@ -1068,6 +1091,13 @@
remoteGlobalIDString = 26DC6A0F1337FE6900FF7998;
remoteInfo = "lldb-server";
};
+ AFCA21D11D18E556004386B8 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 265E9BE1115C2BAA00D0DCCB /* debugserver.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = 456F67431AD46CE9002850C2;
+ remoteInfo = "debugserver-mini";
+ };
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -1105,16 +1135,8 @@
dstPath = "$(DEVELOPER_DIR)/usr/share/man/man1/";
dstSubfolderSpec = 0;
files = (
- 3FBA69E91B60672A0008F44A /* PythonDataObjects.h in CopyFiles */,
+ 49DEF1221CD7BD90006A7C7D /* BlockPointer.h in CopyFiles */,
AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */,
- 3FBA69E71B60672A0008F44A /* lldb-python.h in CopyFiles */,
- 3FBA69DF1B6067020008F44A /* ScriptInterpreterNone.cpp in CopyFiles */,
- 3FBA69E01B6067020008F44A /* ScriptInterpreterNone.h in CopyFiles */,
- 33E5E8461A6736D30024ED68 /* StringConvert.h in CopyFiles */,
- 3FBA69EB1B60672A0008F44A /* ScriptInterpreterPython.h in CopyFiles */,
- AFC234081AF85CE000CDE8B6 /* CommandObjectLanguage.cpp in CopyFiles */,
- 33E5E8421A672A240024ED68 /* StringConvert.cpp in CopyFiles */,
- 49684D7B1BAB37E400E6D5D5 /* MIUtilParse.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
@@ -1167,26 +1189,23 @@
232CB60F191E00CC00EF39FC /* NativeProcessProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = NativeProcessProtocol.cpp; path = source/Host/common/NativeProcessProtocol.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
232CB611191E00CC00EF39FC /* NativeThreadProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NativeThreadProtocol.cpp; path = source/Host/common/NativeThreadProtocol.cpp; sourceTree = "<group>"; };
232CB613191E00CC00EF39FC /* SoftwareBreakpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SoftwareBreakpoint.cpp; path = source/Host/common/SoftwareBreakpoint.cpp; sourceTree = "<group>"; };
- 232CB62B19213AC200EF39FC /* NativeProcessLinux.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NativeProcessLinux.cpp; sourceTree = "<group>"; };
- 232CB62C19213AC200EF39FC /* NativeProcessLinux.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; path = NativeProcessLinux.h; sourceTree = "<group>"; };
- 232CB62D19213AC200EF39FC /* NativeThreadLinux.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NativeThreadLinux.cpp; sourceTree = "<group>"; };
- 232CB62E19213AC200EF39FC /* NativeThreadLinux.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeThreadLinux.h; sourceTree = "<group>"; };
233B007919609DB40090E598 /* ProcessLaunchInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProcessLaunchInfo.h; path = include/lldb/Target/ProcessLaunchInfo.h; sourceTree = "<group>"; };
233B007A1960A0440090E598 /* ProcessInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProcessInfo.h; path = include/lldb/Target/ProcessInfo.h; sourceTree = "<group>"; };
233B007B1960C9E60090E598 /* ProcessInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProcessInfo.cpp; path = source/Target/ProcessInfo.cpp; sourceTree = "<group>"; };
233B007E1960CB280090E598 /* ProcessLaunchInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProcessLaunchInfo.cpp; path = source/Target/ProcessLaunchInfo.cpp; sourceTree = "<group>"; };
233B009D19610D6B0090E598 /* Host.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Host.cpp; sourceTree = "<group>"; };
- 233B00A1196113730090E598 /* ProcFileReader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ProcFileReader.cpp; sourceTree = "<group>"; };
- 233B00A2196113730090E598 /* ProcFileReader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProcFileReader.h; sourceTree = "<group>"; };
- 233B00A919622F3F0090E598 /* NativeRegisterContextLinux_x86_64.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NativeRegisterContextLinux_x86_64.cpp; sourceTree = "<group>"; };
- 233B00AA19622F3F0090E598 /* NativeRegisterContextLinux_x86_64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeRegisterContextLinux_x86_64.h; sourceTree = "<group>"; };
2360092C193FB21500189DB1 /* MemoryRegionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MemoryRegionInfo.h; path = include/lldb/Target/MemoryRegionInfo.h; sourceTree = "<group>"; };
+ 236102981CF38A2B00B8E0B9 /* AddLLDB.cmake */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AddLLDB.cmake; sourceTree = "<group>"; };
+ 236102991CF38A2B00B8E0B9 /* LLDBConfig.cmake */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LLDBConfig.cmake; sourceTree = "<group>"; };
+ 2361029A1CF38A2B00B8E0B9 /* LLDBStandalone.cmake */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LLDBStandalone.cmake; sourceTree = "<group>"; };
+ 2361029E1CF38A3500B8E0B9 /* Android.cmake */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Android.cmake; sourceTree = "<group>"; };
236124A21986B4E2004EFC37 /* IOObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IOObject.cpp; sourceTree = "<group>"; };
236124A31986B4E2004EFC37 /* Socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Socket.cpp; sourceTree = "<group>"; };
236124A61986B50E004EFC37 /* IOObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IOObject.h; path = include/lldb/Host/IOObject.h; sourceTree = "<group>"; };
236124A71986B50E004EFC37 /* Socket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Socket.h; path = include/lldb/Host/Socket.h; sourceTree = "<group>"; };
2377C2F719E613C100737875 /* PipePosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipePosix.cpp; sourceTree = "<group>"; };
237C577A19AF9D9F00213D59 /* HostInfoLinux.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = HostInfoLinux.h; path = include/lldb/Host/linux/HostInfoLinux.h; sourceTree = SOURCE_ROOT; };
+ 239481851C59EBDD00DF7168 /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = ../../../../../usr/lib/libncurses.dylib; sourceTree = "<group>"; };
239504C21BDD3FD600963CEA /* gtest_common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = gtest_common.h; sourceTree = "<group>"; };
239504C61BDD3FF300963CEA /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
239504D41BDD451400963CEA /* lldb-gtest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "lldb-gtest"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -1196,6 +1215,8 @@
23AB0530199FF639003B8084 /* ProcessFreeBSD.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProcessFreeBSD.h; sourceTree = "<group>"; };
23AB0531199FF639003B8084 /* ProcessMonitor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessMonitor.cpp; sourceTree = "<group>"; };
23AB0532199FF639003B8084 /* ProcessMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProcessMonitor.h; sourceTree = "<group>"; };
+ 23DCEA421D1C4C6900A602B4 /* SBMemoryRegionInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBMemoryRegionInfo.cpp; path = source/API/SBMemoryRegionInfo.cpp; sourceTree = "<group>"; };
+ 23DCEA431D1C4C6900A602B4 /* SBMemoryRegionInfoList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBMemoryRegionInfoList.cpp; path = source/API/SBMemoryRegionInfoList.cpp; sourceTree = "<group>"; };
23DDF224196C3EE600BB8417 /* CommandOptionValidators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandOptionValidators.cpp; path = source/Interpreter/CommandOptionValidators.cpp; sourceTree = "<group>"; };
23E77CD61C20F29F007192AD /* DWARFDebugMacro.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DWARFDebugMacro.cpp; sourceTree = "<group>"; };
23E77CD71C20F29F007192AD /* DWARFDebugMacro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWARFDebugMacro.h; sourceTree = "<group>"; };
@@ -1222,12 +1243,6 @@
255EFF711AFABA4D0069F277 /* LockFileWindows.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LockFileWindows.cpp; path = source/Host/windows/LockFileWindows.cpp; sourceTree = "<group>"; };
255EFF731AFABA720069F277 /* LockFileBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LockFileBase.cpp; sourceTree = "<group>"; };
255EFF751AFABA950069F277 /* LockFilePosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LockFilePosix.cpp; sourceTree = "<group>"; };
- 256CBDAB1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NativeRegisterContextLinux_arm.cpp; sourceTree = "<group>"; };
- 256CBDAC1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeRegisterContextLinux_arm.h; sourceTree = "<group>"; };
- 256CBDAD1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm64.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NativeRegisterContextLinux_arm64.cpp; sourceTree = "<group>"; };
- 256CBDAE1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeRegisterContextLinux_arm64.h; sourceTree = "<group>"; };
- 256CBDAF1ADD0DB600BC6CDC /* NativeRegisterContextLinux_mips64.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NativeRegisterContextLinux_mips64.cpp; sourceTree = "<group>"; };
- 256CBDB01ADD0DB600BC6CDC /* NativeRegisterContextLinux_mips64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeRegisterContextLinux_mips64.h; sourceTree = "<group>"; };
256CBDB21ADD0EFD00BC6CDC /* RegisterContextPOSIXCore_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextPOSIXCore_arm.cpp; sourceTree = "<group>"; };
256CBDB31ADD0EFD00BC6CDC /* RegisterContextPOSIXCore_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextPOSIXCore_arm.h; sourceTree = "<group>"; };
256CBDB61ADD107200BC6CDC /* RegisterContextLinux_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextLinux_arm.cpp; path = Utility/RegisterContextLinux_arm.cpp; sourceTree = "<group>"; };
@@ -1450,6 +1465,10 @@
2640E19E15DC78FD00F23B50 /* Property.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Property.cpp; path = source/Interpreter/Property.cpp; sourceTree = "<group>"; };
26424E3C125986CB0016D82C /* ValueObjectConstResult.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectConstResult.cpp; path = source/Core/ValueObjectConstResult.cpp; sourceTree = "<group>"; };
26424E3E125986D30016D82C /* ValueObjectConstResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResult.h; path = include/lldb/Core/ValueObjectConstResult.h; sourceTree = "<group>"; };
+ 264297531D1DF209003F2BF4 /* SBMemoryRegionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBMemoryRegionInfo.h; path = include/lldb/API/SBMemoryRegionInfo.h; sourceTree = "<group>"; };
+ 264297541D1DF209003F2BF4 /* SBMemoryRegionInfoList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBMemoryRegionInfoList.h; path = include/lldb/API/SBMemoryRegionInfoList.h; sourceTree = "<group>"; };
+ 264297591D1DF2AA003F2BF4 /* SBMemoryRegionInfo.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBMemoryRegionInfo.i; sourceTree = "<group>"; };
+ 2642975A1D1DF2AA003F2BF4 /* SBMemoryRegionInfoList.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBMemoryRegionInfoList.i; sourceTree = "<group>"; };
2642FBA813D003B400ED6808 /* CommunicationKDP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommunicationKDP.cpp; sourceTree = "<group>"; };
2642FBA913D003B400ED6808 /* CommunicationKDP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommunicationKDP.h; sourceTree = "<group>"; };
2642FBAA13D003B400ED6808 /* ProcessKDP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessKDP.cpp; sourceTree = "<group>"; };
@@ -1677,7 +1696,6 @@
266941F91A6DC2AC0063BE93 /* MIUtilThreadBaseStd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MIUtilThreadBaseStd.h; path = "tools/lldb-mi/MIUtilThreadBaseStd.h"; sourceTree = SOURCE_ROOT; };
266941FA1A6DC2AC0063BE93 /* MIUtilVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MIUtilVariant.cpp; path = "tools/lldb-mi/MIUtilVariant.cpp"; sourceTree = SOURCE_ROOT; };
266941FB1A6DC2AC0063BE93 /* MIUtilVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MIUtilVariant.h; path = "tools/lldb-mi/MIUtilVariant.h"; sourceTree = SOURCE_ROOT; };
- 266941FC1A6DC2AC0063BE93 /* Platform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Platform.cpp; path = "tools/lldb-mi/Platform.cpp"; sourceTree = SOURCE_ROOT; };
266941FD1A6DC2AC0063BE93 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Platform.h; path = "tools/lldb-mi/Platform.h"; sourceTree = SOURCE_ROOT; };
266960591199F4230075C61A /* build-llvm.pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = "build-llvm.pl"; sourceTree = "<group>"; };
2669605A1199F4230075C61A /* build-swig-wrapper-classes.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "build-swig-wrapper-classes.sh"; sourceTree = "<group>"; };
@@ -1725,6 +1743,15 @@
267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupValueObjectDisplay.cpp; path = source/Interpreter/OptionGroupValueObjectDisplay.cpp; sourceTree = "<group>"; };
267DFB441B06752A00000FB7 /* MICmdArgValPrintValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MICmdArgValPrintValues.cpp; path = "tools/lldb-mi/MICmdArgValPrintValues.cpp"; sourceTree = SOURCE_ROOT; };
267DFB451B06752A00000FB7 /* MICmdArgValPrintValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MICmdArgValPrintValues.h; path = "tools/lldb-mi/MICmdArgValPrintValues.h"; sourceTree = SOURCE_ROOT; };
+ 267F68471CC02DED0086832B /* ABISysV_s390x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ABISysV_s390x.cpp; sourceTree = "<group>"; };
+ 267F68481CC02DED0086832B /* ABISysV_s390x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABISysV_s390x.h; sourceTree = "<group>"; };
+ 267F684D1CC02E270086832B /* RegisterContextPOSIXCore_s390x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextPOSIXCore_s390x.cpp; sourceTree = "<group>"; };
+ 267F684E1CC02E270086832B /* RegisterContextPOSIXCore_s390x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextPOSIXCore_s390x.h; sourceTree = "<group>"; };
+ 267F68511CC02E920086832B /* RegisterContextLinux_s390x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextLinux_s390x.cpp; path = Utility/RegisterContextLinux_s390x.cpp; sourceTree = "<group>"; };
+ 267F68521CC02E920086832B /* RegisterContextLinux_s390x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextLinux_s390x.h; path = Utility/RegisterContextLinux_s390x.h; sourceTree = "<group>"; };
+ 267F68551CC02EAE0086832B /* RegisterContextPOSIX_s390x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextPOSIX_s390x.cpp; path = Utility/RegisterContextPOSIX_s390x.cpp; sourceTree = "<group>"; };
+ 267F68561CC02EAE0086832B /* RegisterContextPOSIX_s390x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextPOSIX_s390x.h; path = Utility/RegisterContextPOSIX_s390x.h; sourceTree = "<group>"; };
+ 267F68591CC02EBE0086832B /* RegisterInfos_s390x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterInfos_s390x.h; path = Utility/RegisterInfos_s390x.h; sourceTree = "<group>"; };
2682100C143A59AE004BCF2D /* MappedHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MappedHash.h; path = include/lldb/Core/MappedHash.h; sourceTree = "<group>"; };
2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PseudoTerminal.cpp; path = source/Utility/PseudoTerminal.cpp; sourceTree = "<group>"; };
2682F16B115EDA0D00CCFF99 /* PseudoTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PseudoTerminal.h; path = include/lldb/Utility/PseudoTerminal.h; sourceTree = "<group>"; };
@@ -2194,6 +2221,8 @@
26FFC19614FC072100087D58 /* DYLDRendezvous.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DYLDRendezvous.h; sourceTree = "<group>"; };
26FFC19714FC072100087D58 /* DynamicLoaderPOSIXDYLD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicLoaderPOSIXDYLD.cpp; sourceTree = "<group>"; };
26FFC19814FC072100087D58 /* DynamicLoaderPOSIXDYLD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicLoaderPOSIXDYLD.h; sourceTree = "<group>"; };
+ 3032B1B61CAAA3D1004BE1AB /* ClangUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangUtil.cpp; path = source/Symbol/ClangUtil.cpp; sourceTree = "<group>"; };
+ 3032B1B91CAAA400004BE1AB /* ClangUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangUtil.h; path = include/lldb/Symbol/ClangUtil.h; sourceTree = "<group>"; };
30DED5DC1B4ECB17004CC508 /* MainLoopPosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MainLoopPosix.cpp; sourceTree = "<group>"; };
33064C991A5C7A330033D415 /* UriParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UriParser.cpp; path = source/Utility/UriParser.cpp; sourceTree = "<group>"; };
33064C9B1A5C7A490033D415 /* UriParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UriParser.h; path = source/Utility/UriParser.h; sourceTree = "<group>"; };
@@ -2344,8 +2373,12 @@
49DCF6FD170E6B4A0092F75E /* IRMemoryMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRMemoryMap.cpp; path = source/Expression/IRMemoryMap.cpp; sourceTree = "<group>"; };
49DCF6FF170E6FD90092F75E /* Materializer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Materializer.h; path = include/lldb/Expression/Materializer.h; sourceTree = "<group>"; };
49DCF700170E70120092F75E /* Materializer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Materializer.cpp; path = source/Expression/Materializer.cpp; sourceTree = "<group>"; };
+ 49DEF11F1CD7BD90006A7C7D /* BlockPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BlockPointer.cpp; path = Language/CPlusPlus/BlockPointer.cpp; sourceTree = "<group>"; };
+ 49DEF1201CD7BD90006A7C7D /* BlockPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlockPointer.h; path = Language/CPlusPlus/BlockPointer.h; sourceTree = "<group>"; };
49E45FA911F660DC008F7B28 /* CompilerType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompilerType.h; path = include/lldb/Symbol/CompilerType.h; sourceTree = "<group>"; };
49E45FAD11F660FE008F7B28 /* CompilerType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompilerType.cpp; path = source/Symbol/CompilerType.cpp; sourceTree = "<group>"; };
+ 49E4F6681C9CAD12008487EA /* DiagnosticManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DiagnosticManager.cpp; path = source/Expression/DiagnosticManager.cpp; sourceTree = "<group>"; };
+ 49E4F66C1C9CAD2D008487EA /* DiagnosticManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DiagnosticManager.h; path = include/lldb/Expression/DiagnosticManager.h; sourceTree = "<group>"; };
49EC3E98118F90AC00B1265E /* ThreadPlanCallFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanCallFunction.cpp; path = source/Target/ThreadPlanCallFunction.cpp; sourceTree = "<group>"; };
49EC3E9C118F90D400B1265E /* ThreadPlanCallFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanCallFunction.h; path = include/lldb/Target/ThreadPlanCallFunction.h; sourceTree = "<group>"; };
49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangExpressionDeclMap.cpp; path = ExpressionParser/Clang/ClangExpressionDeclMap.cpp; sourceTree = "<group>"; };
@@ -2366,12 +2399,15 @@
4C2479BE1BA39843009C9A7B /* ExpressionParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ExpressionParser.h; path = include/lldb/Expression/ExpressionParser.h; sourceTree = "<group>"; };
4C29E77D1BA2403F00DFF855 /* ExpressionTypeSystemHelper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = ExpressionTypeSystemHelper.h; path = include/lldb/Expression/ExpressionTypeSystemHelper.h; sourceTree = "<group>"; };
4C2FAE2E135E3A70001EDE44 /* SharedCluster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharedCluster.h; path = include/lldb/Utility/SharedCluster.h; sourceTree = "<group>"; };
+ 4C3DA2301CA0BFB800CEB1D4 /* ClangDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangDiagnostic.h; path = ExpressionParser/Clang/ClangDiagnostic.h; sourceTree = "<group>"; };
4C43DEF9110641F300E55CBF /* ThreadPlanShouldStopHere.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanShouldStopHere.h; path = include/lldb/Target/ThreadPlanShouldStopHere.h; sourceTree = "<group>"; };
4C43DEFA110641F300E55CBF /* ThreadPlanShouldStopHere.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanShouldStopHere.cpp; path = source/Target/ThreadPlanShouldStopHere.cpp; sourceTree = "<group>"; };
4C43DF8511069BFD00E55CBF /* ThreadPlanStepInRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanStepInRange.h; path = include/lldb/Target/ThreadPlanStepInRange.h; sourceTree = "<group>"; };
4C43DF8611069BFD00E55CBF /* ThreadPlanStepOverRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanStepOverRange.h; path = include/lldb/Target/ThreadPlanStepOverRange.h; sourceTree = "<group>"; };
4C43DF8911069C3200E55CBF /* ThreadPlanStepInRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanStepInRange.cpp; path = source/Target/ThreadPlanStepInRange.cpp; sourceTree = "<group>"; };
4C43DF8A11069C3200E55CBF /* ThreadPlanStepOverRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanStepOverRange.cpp; path = source/Target/ThreadPlanStepOverRange.cpp; sourceTree = "<group>"; };
+ 4C562CC21CC07DDD00C52EAC /* PDBASTParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PDBASTParser.cpp; path = PDB/PDBASTParser.cpp; sourceTree = "<group>"; };
+ 4C562CC31CC07DDD00C52EAC /* PDBASTParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PDBASTParser.h; path = PDB/PDBASTParser.h; sourceTree = "<group>"; };
4C56543019D1EFAA002E9C44 /* ThreadPlanPython.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanPython.cpp; path = source/Target/ThreadPlanPython.cpp; sourceTree = "<group>"; };
4C56543219D1EFB5002E9C44 /* ThreadPlanPython.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanPython.h; path = include/lldb/Target/ThreadPlanPython.h; sourceTree = "<group>"; };
4C56543419D2297A002E9C44 /* SBThreadPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBThreadPlan.h; path = include/lldb/API/SBThreadPlan.h; sourceTree = "<group>"; };
@@ -2432,6 +2468,17 @@
69A01E1E1236C5D400C660B5 /* Mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mutex.cpp; sourceTree = "<group>"; };
69A01E1F1236C5D400C660B5 /* Symbols.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Symbols.cpp; sourceTree = "<group>"; };
69A01E201236C5D400C660B5 /* TimeValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeValue.cpp; sourceTree = "<group>"; };
+ 6D0F613C1C80AA8900A4ECEE /* DebugMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DebugMacros.h; path = include/lldb/Symbol/DebugMacros.h; sourceTree = "<group>"; };
+ 6D0F613D1C80AA8900A4ECEE /* JavaASTContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JavaASTContext.h; path = include/lldb/Symbol/JavaASTContext.h; sourceTree = "<group>"; };
+ 6D0F61411C80AAAA00A4ECEE /* JavaASTContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JavaASTContext.cpp; path = source/Symbol/JavaASTContext.cpp; sourceTree = "<group>"; };
+ 6D0F61441C80AACF00A4ECEE /* DWARFASTParserJava.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DWARFASTParserJava.cpp; sourceTree = "<group>"; };
+ 6D0F61451C80AACF00A4ECEE /* DWARFASTParserJava.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWARFASTParserJava.h; sourceTree = "<group>"; };
+ 6D0F614A1C80AB0400A4ECEE /* JavaLanguageRuntime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JavaLanguageRuntime.cpp; path = Java/JavaLanguageRuntime.cpp; sourceTree = "<group>"; };
+ 6D0F614B1C80AB0400A4ECEE /* JavaLanguageRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JavaLanguageRuntime.h; path = Java/JavaLanguageRuntime.h; sourceTree = "<group>"; };
+ 6D0F61511C80AB3000A4ECEE /* JavaFormatterFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JavaFormatterFunctions.cpp; path = Language/Java/JavaFormatterFunctions.cpp; sourceTree = "<group>"; };
+ 6D0F61521C80AB3000A4ECEE /* JavaFormatterFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JavaFormatterFunctions.h; path = Language/Java/JavaFormatterFunctions.h; sourceTree = "<group>"; };
+ 6D0F61531C80AB3000A4ECEE /* JavaLanguage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JavaLanguage.cpp; path = Language/Java/JavaLanguage.cpp; sourceTree = "<group>"; };
+ 6D0F61541C80AB3000A4ECEE /* JavaLanguage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JavaLanguage.h; path = Language/Java/JavaLanguage.h; sourceTree = "<group>"; };
6D55B28D1A8A806200A70529 /* GDBRemoteCommunicationServerCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunicationServerCommon.cpp; sourceTree = "<group>"; };
6D55B28E1A8A806200A70529 /* GDBRemoteCommunicationServerLLGS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunicationServerLLGS.cpp; sourceTree = "<group>"; };
6D55B28F1A8A806200A70529 /* GDBRemoteCommunicationServerPlatform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunicationServerPlatform.cpp; sourceTree = "<group>"; };
@@ -2463,6 +2510,8 @@
6D9AB3DE1BB2B76B003F2289 /* TypeMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeMap.h; path = include/lldb/Symbol/TypeMap.h; sourceTree = "<group>"; };
6DEC6F381BD66D750091ABA6 /* TaskPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TaskPool.cpp; path = source/Utility/TaskPool.cpp; sourceTree = "<group>"; };
6DEC6F3A1BD66D950091ABA6 /* TaskPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaskPool.h; path = include/lldb/Utility/TaskPool.h; sourceTree = "<group>"; };
+ 8C26C4241C3EA4340031DF7C /* ThreadSanitizerRuntime.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadSanitizerRuntime.cpp; path = ThreadSanitizer/ThreadSanitizerRuntime.cpp; sourceTree = "<group>"; };
+ 8C26C4251C3EA4340031DF7C /* ThreadSanitizerRuntime.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ThreadSanitizerRuntime.h; path = ThreadSanitizer/ThreadSanitizerRuntime.h; sourceTree = "<group>"; };
8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MemoryHistory.cpp; path = source/Target/MemoryHistory.cpp; sourceTree = "<group>"; };
8C2D6A54197A1EBE006989C9 /* MemoryHistory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MemoryHistory.h; path = include/lldb/Target/MemoryHistory.h; sourceTree = "<group>"; };
8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryHistoryASan.cpp; sourceTree = "<group>"; };
@@ -2485,6 +2534,7 @@
940495791BEC497E00926025 /* NSException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NSException.cpp; path = Language/ObjC/NSException.cpp; sourceTree = "<group>"; };
94094C68163B6CCC0083A547 /* ValueObjectCast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectCast.h; path = include/lldb/Core/ValueObjectCast.h; sourceTree = "<group>"; };
94094C69163B6CD90083A547 /* ValueObjectCast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectCast.cpp; path = source/Core/ValueObjectCast.cpp; sourceTree = "<group>"; };
+ 940B01FE1D2D82220058795E /* ThreadSafeSTLVector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ThreadSafeSTLVector.h; path = include/lldb/Core/ThreadSafeSTLVector.h; sourceTree = "<group>"; };
940B02F419DC96CB00AD0F52 /* SBExecutionContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBExecutionContext.h; path = include/lldb/API/SBExecutionContext.h; sourceTree = "<group>"; };
940B02F519DC96E700AD0F52 /* SBExecutionContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBExecutionContext.cpp; path = source/API/SBExecutionContext.cpp; sourceTree = "<group>"; };
940B02F719DC970900AD0F52 /* SBExecutionContext.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBExecutionContext.i; sourceTree = "<group>"; };
@@ -2500,11 +2550,15 @@
942829541A89614000521B30 /* JSON.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JSON.h; path = include/lldb/Utility/JSON.h; sourceTree = "<group>"; };
942829551A89614C00521B30 /* JSON.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSON.cpp; path = source/Utility/JSON.cpp; sourceTree = "<group>"; };
942829C01A89835300521B30 /* lldb-argdumper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "lldb-argdumper"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 9428BC291C6E64DC002A24D7 /* LibCxxAtomic.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxAtomic.cpp; path = Language/CPlusPlus/LibCxxAtomic.cpp; sourceTree = "<group>"; };
+ 9428BC2A1C6E64DC002A24D7 /* LibCxxAtomic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LibCxxAtomic.h; path = Language/CPlusPlus/LibCxxAtomic.h; sourceTree = "<group>"; };
94380B8019940B0300BFE4A8 /* StringLexer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = StringLexer.h; path = include/lldb/Utility/StringLexer.h; sourceTree = "<group>"; };
94380B8119940B0A00BFE4A8 /* StringLexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringLexer.cpp; path = source/Utility/StringLexer.cpp; sourceTree = "<group>"; };
943B90FC1B991586007BA499 /* VectorIterator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VectorIterator.h; path = include/lldb/DataFormatters/VectorIterator.h; sourceTree = "<group>"; };
943BDEFC1AA7B2DE00789CE8 /* LLDBAssert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LLDBAssert.h; path = include/lldb/Utility/LLDBAssert.h; sourceTree = "<group>"; };
943BDEFD1AA7B2F800789CE8 /* LLDBAssert.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLDBAssert.cpp; path = source/Utility/LLDBAssert.cpp; sourceTree = "<group>"; };
+ 9441816B1C8F5EB000E5A8D9 /* CommandAlias.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CommandAlias.h; path = include/lldb/Interpreter/CommandAlias.h; sourceTree = "<group>"; };
+ 9441816D1C8F5EC900E5A8D9 /* CommandAlias.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandAlias.cpp; path = source/Interpreter/CommandAlias.cpp; sourceTree = "<group>"; };
944372DA171F6B4300E57C32 /* RegisterContextDummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextDummy.cpp; path = Utility/RegisterContextDummy.cpp; sourceTree = "<group>"; };
944372DB171F6B4300E57C32 /* RegisterContextDummy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextDummy.h; path = Utility/RegisterContextDummy.h; sourceTree = "<group>"; };
9443B120140C18A90013457C /* SBData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBData.h; path = include/lldb/API/SBData.h; sourceTree = "<group>"; };
@@ -2761,6 +2815,8 @@
AF25AB25188F685C0030DEC3 /* AppleGetQueuesHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleGetQueuesHandler.h; sourceTree = "<group>"; };
AF2670381852D01E00B6CC36 /* Queue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Queue.cpp; path = source/Target/Queue.cpp; sourceTree = "<group>"; };
AF2670391852D01E00B6CC36 /* QueueList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = QueueList.cpp; path = source/Target/QueueList.cpp; sourceTree = "<group>"; };
+ AF27AD531D3603EA00CF2833 /* DynamicLoaderDarwin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicLoaderDarwin.cpp; sourceTree = "<group>"; };
+ AF27AD541D3603EA00CF2833 /* DynamicLoaderDarwin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicLoaderDarwin.h; sourceTree = "<group>"; };
AF2BCA6918C7EFDE005B4526 /* JITLoaderGDB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITLoaderGDB.cpp; sourceTree = "<group>"; };
AF2BCA6A18C7EFDE005B4526 /* JITLoaderGDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITLoaderGDB.h; sourceTree = "<group>"; };
AF33B4BC1C1FA441001B28D9 /* NetBSDSignals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetBSDSignals.cpp; path = Utility/NetBSDSignals.cpp; sourceTree = "<group>"; };
@@ -2784,6 +2840,8 @@
AF45E1FD1BF57C8D000563EB /* PythonTestSuite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PythonTestSuite.h; sourceTree = "<group>"; };
AF45FDE318A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppleGetThreadItemInfoHandler.cpp; sourceTree = "<group>"; };
AF45FDE418A1F3AC0007051C /* AppleGetThreadItemInfoHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleGetThreadItemInfoHandler.h; sourceTree = "<group>"; };
+ AF6335E01C87B21E00F7D554 /* SymbolFilePDB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SymbolFilePDB.cpp; path = PDB/SymbolFilePDB.cpp; sourceTree = "<group>"; };
+ AF6335E11C87B21E00F7D554 /* SymbolFilePDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SymbolFilePDB.h; path = PDB/SymbolFilePDB.h; sourceTree = "<group>"; };
AF68D2541255416E002FF25B /* RegisterContextLLDB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextLLDB.cpp; path = Utility/RegisterContextLLDB.cpp; sourceTree = "<group>"; };
AF68D2551255416E002FF25B /* RegisterContextLLDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextLLDB.h; path = Utility/RegisterContextLLDB.h; sourceTree = "<group>"; };
AF68D32F1255A110002FF25B /* UnwindLLDB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnwindLLDB.cpp; path = Utility/UnwindLLDB.cpp; sourceTree = "<group>"; };
@@ -2919,6 +2977,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 239481861C59EBDD00DF7168 /* libncurses.dylib in Frameworks */,
2669424D1A6DC32B0063BE93 /* LLDB.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -2963,6 +3022,7 @@
08FB7794FE84155DC02AAC07 /* lldb */ = {
isa = PBXGroup;
children = (
+ 239481851C59EBDD00DF7168 /* libncurses.dylib */,
2326CF4E1BDD687800A5CEAC /* libpanel.dylib */,
2326CF4C1BDD684B00A5CEAC /* libedit.dylib */,
2326CF4A1BDD681800A5CEAC /* libz.dylib */,
@@ -2976,6 +3036,7 @@
2690CD181A6DC0D000E717C8 /* lldb-mi */,
1AB674ADFE9D54B511CA2CBB /* Products */,
2321F9331BDD326500BA9A93 /* unittests */,
+ 236102941CF389BE00B8E0B9 /* cmake */,
);
name = lldb;
sourceTree = "<group>";
@@ -3106,27 +3167,6 @@
path = Editline;
sourceTree = "<group>";
};
- 233B008B196106E90090E598 /* Linux */ = {
- isa = PBXGroup;
- children = (
- 256CBDAB1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm.cpp */,
- 256CBDAC1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm.h */,
- 256CBDAD1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm64.cpp */,
- 256CBDAE1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm64.h */,
- 256CBDAF1ADD0DB600BC6CDC /* NativeRegisterContextLinux_mips64.cpp */,
- 256CBDB01ADD0DB600BC6CDC /* NativeRegisterContextLinux_mips64.h */,
- 232CB62B19213AC200EF39FC /* NativeProcessLinux.cpp */,
- 232CB62C19213AC200EF39FC /* NativeProcessLinux.h */,
- 233B00AA19622F3F0090E598 /* NativeRegisterContextLinux_x86_64.h */,
- 233B00A919622F3F0090E598 /* NativeRegisterContextLinux_x86_64.cpp */,
- 232CB62D19213AC200EF39FC /* NativeThreadLinux.cpp */,
- 232CB62E19213AC200EF39FC /* NativeThreadLinux.h */,
- 233B00A2196113730090E598 /* ProcFileReader.h */,
- 233B00A1196113730090E598 /* ProcFileReader.cpp */,
- );
- path = Linux;
- sourceTree = "<group>";
- };
233B009C19610D130090E598 /* linux */ = {
isa = PBXGroup;
children = (
@@ -3142,6 +3182,33 @@
path = source/Host/linux;
sourceTree = "<group>";
};
+ 236102941CF389BE00B8E0B9 /* cmake */ = {
+ isa = PBXGroup;
+ children = (
+ 236102961CF389F800B8E0B9 /* modules */,
+ 236102971CF38A0900B8E0B9 /* platforms */,
+ );
+ path = cmake;
+ sourceTree = "<group>";
+ };
+ 236102961CF389F800B8E0B9 /* modules */ = {
+ isa = PBXGroup;
+ children = (
+ 236102981CF38A2B00B8E0B9 /* AddLLDB.cmake */,
+ 236102991CF38A2B00B8E0B9 /* LLDBConfig.cmake */,
+ 2361029A1CF38A2B00B8E0B9 /* LLDBStandalone.cmake */,
+ );
+ path = modules;
+ sourceTree = "<group>";
+ };
+ 236102971CF38A0900B8E0B9 /* platforms */ = {
+ isa = PBXGroup;
+ children = (
+ 2361029E1CF38A3500B8E0B9 /* Android.cmake */,
+ );
+ path = platforms;
+ sourceTree = "<group>";
+ };
23AB0526199FF5D3003B8084 /* FreeBSD */ = {
isa = PBXGroup;
children = (
@@ -3228,6 +3295,8 @@
260C897910F57C5600BB2B04 /* MacOSX-DYLD */ = {
isa = PBXGroup;
children = (
+ AF27AD531D3603EA00CF2833 /* DynamicLoaderDarwin.cpp */,
+ AF27AD541D3603EA00CF2833 /* DynamicLoaderDarwin.h */,
260C897A10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLD.cpp */,
260C897B10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLD.h */,
);
@@ -3289,7 +3358,6 @@
26BC179F18C7F4CB00D2196D /* elf-core */,
23AB0526199FF5D3003B8084 /* FreeBSD */,
4CEE62F71145F1C70064CF93 /* GDB Remote */,
- 233B008B196106E90090E598 /* Linux */,
2642FBA713D003B400ED6808 /* MacOSX-Kernel */,
26A527BC14E24F5F00F3A14A /* mach-core */,
26BC17B318C7F4FA00D2196D /* POSIX */,
@@ -3301,6 +3369,7 @@
260C89B110F57C5600BB2B04 /* SymbolFile */ = {
isa = PBXGroup;
children = (
+ AF6335DF1C87B20A00F7D554 /* PDB */,
260C89B210F57C5600BB2B04 /* DWARF */,
260C89DD10F57C5600BB2B04 /* Symtab */,
);
@@ -3310,6 +3379,8 @@
260C89B210F57C5600BB2B04 /* DWARF */ = {
isa = PBXGroup;
children = (
+ 6D0F61441C80AACF00A4ECEE /* DWARFASTParserJava.cpp */,
+ 6D0F61451C80AACF00A4ECEE /* DWARFASTParserJava.h */,
6D95DC031B9DC06F000E318A /* DIERef.h */,
6D95DC041B9DC06F000E318A /* SymbolFileDWARFDwo.h */,
6D95DBFD1B9DC057000E318A /* DIERef.cpp */,
@@ -3434,6 +3505,8 @@
2611FF03142D83060017FEA3 /* SBInstructionList.i */,
2611FF04142D83060017FEA3 /* SBLineEntry.i */,
2611FF05142D83060017FEA3 /* SBListener.i */,
+ 264297591D1DF2AA003F2BF4 /* SBMemoryRegionInfo.i */,
+ 2642975A1D1DF2AA003F2BF4 /* SBMemoryRegionInfoList.i */,
2611FF06142D83060017FEA3 /* SBModule.i */,
263C493B178B61CC0070F12D /* SBModuleSpec.i */,
262F12B8183546C900AEB384 /* SBPlatform.i */,
@@ -3544,6 +3617,10 @@
26DE20621161904200A093E2 /* SBLineEntry.cpp */,
9A9831021125FC5800A56CB0 /* SBListener.h */,
9A9831011125FC5800A56CB0 /* SBListener.cpp */,
+ 264297531D1DF209003F2BF4 /* SBMemoryRegionInfo.h */,
+ 23DCEA421D1C4C6900A602B4 /* SBMemoryRegionInfo.cpp */,
+ 264297541D1DF209003F2BF4 /* SBMemoryRegionInfoList.h */,
+ 23DCEA431D1C4C6900A602B4 /* SBMemoryRegionInfoList.cpp */,
26DE204E11618E9800A093E2 /* SBModule.h */,
26DE204C11618E7A00A093E2 /* SBModule.cpp */,
263C4939178B50CF0070F12D /* SBModuleSpec.h */,
@@ -3705,7 +3782,7 @@
isa = PBXGroup;
children = (
26CE05A0115C31E50022F371 /* debugserver */,
- 239504C51BDD3FD700963CEA /* debugserver */,
+ 239504C51BDD3FD700963CEA /* debugserver-nonui */,
);
name = Products;
sourceTree = "<group>";
@@ -3770,6 +3847,15 @@
path = OperatingSystem;
sourceTree = "<group>";
};
+ 267F68461CC02DED0086832B /* SysV-s390x */ = {
+ isa = PBXGroup;
+ children = (
+ 267F68471CC02DED0086832B /* ABISysV_s390x.cpp */,
+ 267F68481CC02DED0086832B /* ABISysV_s390x.h */,
+ );
+ path = "SysV-s390x";
+ sourceTree = "<group>";
+ };
2682F168115ED9C800CCFF99 /* Utility */ = {
isa = PBXGroup;
children = (
@@ -3991,7 +4077,6 @@
266941F91A6DC2AC0063BE93 /* MIUtilThreadBaseStd.h */,
266941FA1A6DC2AC0063BE93 /* MIUtilVariant.cpp */,
266941FB1A6DC2AC0063BE93 /* MIUtilVariant.h */,
- 266941FC1A6DC2AC0063BE93 /* Platform.cpp */,
266941FD1A6DC2AC0063BE93 /* Platform.h */,
);
path = "lldb-mi";
@@ -4135,6 +4220,8 @@
AF061F86182C97ED00B6A19C /* RegisterContextHistory.h */,
26474CAE18D0CB180073DEBA /* RegisterContextLinux_i386.cpp */,
26474CAF18D0CB180073DEBA /* RegisterContextLinux_i386.h */,
+ 267F68511CC02E920086832B /* RegisterContextLinux_s390x.cpp */,
+ 267F68521CC02E920086832B /* RegisterContextLinux_s390x.h */,
26474CB018D0CB180073DEBA /* RegisterContextLinux_x86_64.cpp */,
26474CB118D0CB180073DEBA /* RegisterContextLinux_x86_64.h */,
AF68D2541255416E002FF25B /* RegisterContextLLDB.cpp */,
@@ -4153,6 +4240,8 @@
26474CC518D0CB5B0073DEBA /* RegisterContextPOSIX_mips64.h */,
AF77E09D1A033D360096C0EA /* RegisterContextPOSIX_powerpc.cpp */,
AF77E09E1A033D360096C0EA /* RegisterContextPOSIX_powerpc.h */,
+ 267F68551CC02EAE0086832B /* RegisterContextPOSIX_s390x.cpp */,
+ 267F68561CC02EAE0086832B /* RegisterContextPOSIX_s390x.h */,
26474CC618D0CB5B0073DEBA /* RegisterContextPOSIX_x86.cpp */,
26474CC718D0CB5B0073DEBA /* RegisterContextPOSIX_x86.h */,
26474CC818D0CB5B0073DEBA /* RegisterContextPOSIX.h */,
@@ -4162,6 +4251,7 @@
26474CD018D0CB700073DEBA /* RegisterInfos_i386.h */,
26474CD118D0CB710073DEBA /* RegisterInfos_mips64.h */,
AF77E09F1A033D360096C0EA /* RegisterInfos_powerpc.h */,
+ 267F68591CC02EBE0086832B /* RegisterInfos_s390x.h */,
26474CD218D0CB710073DEBA /* RegisterInfos_x86_64.h */,
2615DBC81208B5FC0021781D /* StopInfoMachException.cpp */,
2615DBC91208B5FC0021781D /* StopInfoMachException.h */,
@@ -4191,6 +4281,8 @@
26BC17A518C7F4CB00D2196D /* RegisterContextPOSIXCore_mips64.h */,
AF77E0A71A033D740096C0EA /* RegisterContextPOSIXCore_powerpc.cpp */,
AF77E0A81A033D740096C0EA /* RegisterContextPOSIXCore_powerpc.h */,
+ 267F684D1CC02E270086832B /* RegisterContextPOSIXCore_s390x.cpp */,
+ 267F684E1CC02E270086832B /* RegisterContextPOSIXCore_s390x.h */,
26BC17A618C7F4CB00D2196D /* RegisterContextPOSIXCore_x86_64.cpp */,
26BC17A718C7F4CB00D2196D /* RegisterContextPOSIXCore_x86_64.h */,
26BC17A818C7F4CB00D2196D /* ThreadElfCore.cpp */,
@@ -4337,6 +4429,7 @@
AFEC3361194A8ABA00FF05C6 /* StructuredData.cpp */,
26B167A41123BF5500DC7B4F /* ThreadSafeValue.h */,
263FEDA5112CC1DA00E4C208 /* ThreadSafeSTLMap.h */,
+ 940B01FE1D2D82220058795E /* ThreadSafeSTLVector.h */,
26BC7D7E10F1B77400F91463 /* Timer.h */,
26BC7E9610F1B85900F91463 /* Timer.cpp */,
94ED54A119C8A822007BE2EA /* ThreadSafeDenseMap.h */,
@@ -4385,6 +4478,11 @@
26BC7C4B10F1B6C100F91463 /* Symbol */ = {
isa = PBXGroup;
children = (
+ 3032B1B91CAAA400004BE1AB /* ClangUtil.h */,
+ 3032B1B61CAAA3D1004BE1AB /* ClangUtil.cpp */,
+ 6D0F61411C80AAAA00A4ECEE /* JavaASTContext.cpp */,
+ 6D0F613C1C80AA8900A4ECEE /* DebugMacros.h */,
+ 6D0F613D1C80AA8900A4ECEE /* JavaASTContext.h */,
6D9AB3DE1BB2B76B003F2289 /* TypeMap.h */,
6D9AB3DC1BB2B74E003F2289 /* TypeMap.cpp */,
6D99A3621BBC2F3200979793 /* ArmUnwindInfo.cpp */,
@@ -4577,6 +4675,8 @@
26BC7DBE10F1B78200F91463 /* Expression */ = {
isa = PBXGroup;
children = (
+ 49E4F66C1C9CAD2D008487EA /* DiagnosticManager.h */,
+ 49E4F6681C9CAD12008487EA /* DiagnosticManager.cpp */,
4C00832C1B9A58A700D5CF24 /* Expression.h */,
4C88BC291BA3722B00AA0964 /* Expression.cpp */,
4C29E77D1BA2403F00DFF855 /* ExpressionTypeSystemHelper.h */,
@@ -4686,6 +4786,8 @@
26BC7D5310F1B77400F91463 /* Args.h */,
26BC7E6C10F1B85900F91463 /* Args.cpp */,
26A4EEB511682AAC007A372A /* LLDBWrapPython.cpp */,
+ 9441816B1C8F5EB000E5A8D9 /* CommandAlias.h */,
+ 9441816D1C8F5EC900E5A8D9 /* CommandAlias.cpp */,
4C09CB73116BD98B00C7A725 /* CommandCompletions.h */,
4C09CB74116BD98B00C7A725 /* CommandCompletions.cpp */,
94BA8B71176F97D4005A91B5 /* CommandHistory.h */,
@@ -5026,6 +5128,7 @@
263641141B34AEE200145B2F /* SysV-mips64 */,
AF77E08B1A033C3E0096C0EA /* SysV-ppc */,
AF77E08C1A033C4B0096C0EA /* SysV-ppc64 */,
+ 267F68461CC02DED0086832B /* SysV-s390x */,
26DB3E121379E7AD0080DC73 /* SysV-x86_64 */,
);
path = ABI;
@@ -5299,6 +5402,7 @@
4984BA0C1B97620B008658D4 /* Clang */ = {
isa = PBXGroup;
children = (
+ 4C3DA2301CA0BFB800CEB1D4 /* ClangDiagnostic.h */,
4C98D3E0118FB98F00E575D0 /* ClangFunctionCaller.h */,
4C98D3DA118FB96F00E575D0 /* ClangFunctionCaller.cpp */,
26BC7DC010F1B79500F91463 /* ClangExpressionHelper.h */,
@@ -5333,6 +5437,7 @@
4CCA643A13B40B82003BDF98 /* LanguageRuntime */ = {
isa = PBXGroup;
children = (
+ 6D0F61491C80AAF200A4ECEE /* Java */,
AE44FB3B1BB485730033EB62 /* Go */,
49724D961AD6ECFA0033C538 /* RenderScript */,
4CCA643B13B40B82003BDF98 /* CPlusPlus */,
@@ -5449,6 +5554,26 @@
path = source/Host/common;
sourceTree = "<group>";
};
+ 6D0F61491C80AAF200A4ECEE /* Java */ = {
+ isa = PBXGroup;
+ children = (
+ 6D0F614A1C80AB0400A4ECEE /* JavaLanguageRuntime.cpp */,
+ 6D0F614B1C80AB0400A4ECEE /* JavaLanguageRuntime.h */,
+ );
+ name = Java;
+ sourceTree = "<group>";
+ };
+ 6D0F61501C80AB1400A4ECEE /* Java */ = {
+ isa = PBXGroup;
+ children = (
+ 6D0F61511C80AB3000A4ECEE /* JavaFormatterFunctions.cpp */,
+ 6D0F61521C80AB3000A4ECEE /* JavaFormatterFunctions.h */,
+ 6D0F61531C80AB3000A4ECEE /* JavaLanguage.cpp */,
+ 6D0F61541C80AB3000A4ECEE /* JavaLanguage.h */,
+ );
+ name = Java;
+ sourceTree = "<group>";
+ };
6D55B29B1A8CCFF000A70529 /* android */ = {
isa = PBXGroup;
children = (
@@ -5475,6 +5600,15 @@
path = Android;
sourceTree = "<group>";
};
+ 8C26C4221C3EA4050031DF7C /* ThreadSanitizer */ = {
+ isa = PBXGroup;
+ children = (
+ 8C26C4241C3EA4340031DF7C /* ThreadSanitizerRuntime.cpp */,
+ 8C26C4251C3EA4340031DF7C /* ThreadSanitizerRuntime.h */,
+ );
+ name = ThreadSanitizer;
+ sourceTree = "<group>";
+ };
8C2D6A58197A1FB9006989C9 /* MemoryHistory */ = {
isa = PBXGroup;
children = (
@@ -5495,6 +5629,7 @@
8CF02ADD19DCBEC200B14BE0 /* InstrumentationRuntime */ = {
isa = PBXGroup;
children = (
+ 8C26C4221C3EA4050031DF7C /* ThreadSanitizer */,
8CF02ADE19DCBEE600B14BE0 /* AddressSanitizer */,
);
path = InstrumentationRuntime;
@@ -5520,10 +5655,14 @@
945261B01B9A11BE00BF138D /* Formatters */ = {
isa = PBXGroup;
children = (
+ 49DEF1201CD7BD90006A7C7D /* BlockPointer.h */,
+ 49DEF11F1CD7BD90006A7C7D /* BlockPointer.cpp */,
945261B41B9A11E800BF138D /* CxxStringTypes.h */,
945261B31B9A11E800BF138D /* CxxStringTypes.cpp */,
945261B61B9A11E800BF138D /* LibCxx.h */,
945261B51B9A11E800BF138D /* LibCxx.cpp */,
+ 9428BC2A1C6E64DC002A24D7 /* LibCxxAtomic.h */,
+ 9428BC291C6E64DC002A24D7 /* LibCxxAtomic.cpp */,
945261B71B9A11E800BF138D /* LibCxxInitializerList.cpp */,
945261B81B9A11E800BF138D /* LibCxxList.cpp */,
945261B91B9A11E800BF138D /* LibCxxMap.cpp */,
@@ -5579,6 +5718,7 @@
94B638541B8FABEA004FE1E4 /* Language */ = {
isa = PBXGroup;
children = (
+ 6D0F61501C80AB1400A4ECEE /* Java */,
94B6385A1B8FB109004FE1E4 /* CPlusPlus */,
AE44FB431BB4BAC20033EB62 /* Go */,
94B638551B8FAC87004FE1E4 /* ObjC */,
@@ -5787,6 +5927,17 @@
path = GDB;
sourceTree = "<group>";
};
+ AF6335DF1C87B20A00F7D554 /* PDB */ = {
+ isa = PBXGroup;
+ children = (
+ 4C562CC21CC07DDD00C52EAC /* PDBASTParser.cpp */,
+ 4C562CC31CC07DDD00C52EAC /* PDBASTParser.h */,
+ AF6335E01C87B21E00F7D554 /* SymbolFilePDB.cpp */,
+ AF6335E11C87B21E00F7D554 /* SymbolFilePDB.h */,
+ );
+ name = PDB;
+ sourceTree = "<group>";
+ };
AF77E08B1A033C3E0096C0EA /* SysV-ppc */ = {
isa = PBXGroup;
children = (
@@ -5867,8 +6018,10 @@
26680225115FD13D008E1FE4 /* SBFrame.h in Headers */,
26DE205311618FAC00A093E2 /* SBFunction.h in Headers */,
9A3576A8116E9AB700E8ED2F /* SBHostOS.h in Headers */,
+ 264297571D1DF247003F2BF4 /* SBMemoryRegionInfoList.h in Headers */,
9AC7038E117674FB0086C050 /* SBInstruction.h in Headers */,
9AC70390117675270086C050 /* SBInstructionList.h in Headers */,
+ 264297581D1DF250003F2BF4 /* SBMemoryRegionInfo.h in Headers */,
26DE205911618FE700A093E2 /* SBLineEntry.h in Headers */,
254FBB971A81B03100BD6378 /* SBLaunchInfo.h in Headers */,
AF0EBBED185941360059E52F /* SBQueueItem.h in Headers */,
@@ -5912,13 +6065,22 @@
AF8AD6381BEC28C400150209 /* PlatformRemoteAppleTV.h in Headers */,
26EFB61C1BFE8D3E00544801 /* PlatformNetBSD.h in Headers */,
AF33B4BF1C1FA441001B28D9 /* NetBSDSignals.h in Headers */,
+ AF6335E31C87B21E00F7D554 /* SymbolFilePDB.h in Headers */,
+ 267F685A1CC02EBE0086832B /* RegisterInfos_s390x.h in Headers */,
+ 267F68541CC02E920086832B /* RegisterContextLinux_s390x.h in Headers */,
+ 267F68501CC02E270086832B /* RegisterContextPOSIXCore_s390x.h in Headers */,
4984BA181B979C08008658D4 /* ExpressionVariable.h in Headers */,
26C7C4841BFFEA7E009BD01F /* WindowsMiniDump.h in Headers */,
+ 30B38A001CAAA6D7009524E3 /* ClangUtil.h in Headers */,
AF8AD62F1BEC28A400150209 /* PlatformAppleTVSimulator.h in Headers */,
AF8AD63A1BEC28C400150209 /* PlatformRemoteAppleWatch.h in Headers */,
257906651BD5AFD000178368 /* Acceptor.h in Headers */,
260A63171861008E00FECF8E /* IOHandler.h in Headers */,
+ 267F68581CC02EAE0086832B /* RegisterContextPOSIX_s390x.h in Headers */,
+ 6D0F614F1C80AB0C00A4ECEE /* JavaLanguageRuntime.h in Headers */,
+ AF27AD561D3603EA00CF2833 /* DynamicLoaderDarwin.h in Headers */,
AFCB2BBE1BF577F40018B553 /* PythonExceptionState.h in Headers */,
+ 267F684B1CC02DED0086832B /* ABISysV_s390x.h in Headers */,
AF8AD6311BEC28A400150209 /* PlatformAppleWatchSimulator.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -5928,7 +6090,7 @@
/* Begin PBXLegacyTarget section */
2387551E1C24974600CCE8C3 /* lldb-python-test-suite */ = {
isa = PBXLegacyTarget;
- buildArgumentsString = "-u $(SRCROOT)/test/dotest.py --apple-sdk $(PLATFORM_NAME) --executable=$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/lldb --results-formatter lldbsuite.test.xunit_formatter.XunitFormatter --results-file $(BUILD_DIR)/test-results.xml --rerun-all-issues --env TERM=vt100";
+ buildArgumentsString = "-u $(SRCROOT)/test/dotest.py --apple-sdk $(PLATFORM_NAME) --executable=$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/lldb -C $(LLDB_PYTHON_TESTSUITE_CC) --results-formatter lldbsuite.test_event.formatter.xunit.XunitFormatter --results-file $(BUILD_DIR)/test-results.xml --rerun-all-issues --env TERM=vt100 -O--xpass=ignore";
buildConfigurationList = 238755241C24974600CCE8C3 /* Build configuration list for PBXLegacyTarget "lldb-python-test-suite" */;
buildPhases = (
);
@@ -5964,6 +6126,7 @@
239504D01BDD451400963CEA /* Sources */,
239504D11BDD451400963CEA /* Frameworks */,
239504D21BDD451400963CEA /* CopyFiles */,
+ 23B9815E1CB2E2F90059938A /* Run gtests */,
);
buildRules = (
);
@@ -6166,10 +6329,10 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
- 239504C51BDD3FD700963CEA /* debugserver */ = {
+ 239504C51BDD3FD700963CEA /* debugserver-nonui */ = {
isa = PBXReferenceProxy;
fileType = "compiled.mach-o.executable";
- path = debugserver;
+ path = "debugserver-nonui";
remoteRef = 239504C41BDD3FD700963CEA /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
@@ -6196,6 +6359,20 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
+ 23B9815E1CB2E2F90059938A /* Run gtests */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run gtests";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Run the just-built gtest executable\n\n# Uncomment this to see the steps in action\n# set -x\n\n# We need to hide the lldb.py that goes into BUILT_PRODUCTS\n# because it will conflict with finding the lldb module later,\n# which causes the python exception tests to fail.\nif [ -f \"${BUILT_PRODUCTS_DIR}/lldb.py\" ]; then\n mv -f \"${BUILT_PRODUCTS_DIR}/lldb.py\" \"${BUILT_PRODUCTS_DIR}/park.lldb.py\"\nfi\n\n# Tell lldb-gtest where to find the lldb package\nexport PYTHONPATH=${BUILT_PRODUCTS_DIR}/LLDB.framework/Resources/Python\n\n# Set the terminal to VT100 so that the editline internals don't\n# fail.\nexport TERM=vt100\n\n# We must redirect stdin to /dev/null: without this, xcodebuild\n# will wait forever for input when we run the TestExceptionStateChecking\n# test.\n${BUILT_PRODUCTS_DIR}/lldb-gtest --gtest_output=xml:${BUILD_DIR}/gtest-results.xml < /dev/null\nRETCODE=$?\n\nif [ -f \"${BUILT_PRODUCTS_DIR}/park.lldb.py\" ]; then\nmv -f \"${BUILT_PRODUCTS_DIR}/park.lldb.py\" \"${BUILT_PRODUCTS_DIR}/lldb.py\"\nfi\n\nexit ${RETCODE}";
+ };
261B5A7511C3FA6F00AABD0A /* Fixup Framework Headers */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -6225,7 +6402,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "perl $SRCROOT/scripts/build-llvm.pl";
+ shellScript = "/usr/bin/env python -u $SRCROOT/scripts/Xcode/build-llvm.py\n";
};
26DC6A5813380D4300FF7998 /* Prepare Swig Bindings */ = {
isa = PBXShellScriptBuildPhase;
@@ -6239,7 +6416,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "/usr/bin/python $SRCROOT/scripts/prepare_bindings.py --find-swig --framework --src-root $SRCROOT --target-dir $TARGET_BUILD_DIR --config-build-dir $CONFIGURATION_BUILD_DIR";
+ shellScript = "/usr/bin/python $SRCROOT/scripts/prepare_bindings.py --find-swig --framework --src-root $SRCROOT --target-dir $TARGET_BUILD_DIR --config-build-dir $BUILT_PRODUCTS_DIR --target-platform Darwin";
};
4959511A1A1ACE9500F6F8FC /* Install Clang compiler headers */ = {
isa = PBXShellScriptBuildPhase;
@@ -6254,7 +6431,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "/usr/bin/python $SRCROOT/scripts/package-clang-headers.py $TARGET_BUILD_DIR $LLVM_BUILD_DIR/$CURRENT_ARCH/$LLVM_CONFIGURATION";
+ shellScript = "/usr/bin/python $SRCROOT/scripts/Xcode/package-clang-headers.py $TARGET_BUILD_DIR $LLVM_BUILD_DIR/$CURRENT_ARCH";
};
4C3326CA18B2A2B800EB5DD7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
@@ -6300,7 +6477,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "sh $SRCROOT/scripts/finish-swig-wrapper-classes.sh $SRCROOT $TARGET_BUILD_DIR $CONFIGURATION_BUILD_DIR \"\"";
+ shellScript = "sh $SRCROOT/scripts/finish-swig-wrapper-classes.sh $SRCROOT $TARGET_BUILD_DIR $BUILT_PRODUCTS_DIR \"\"";
};
AF3059151B4B390800E25622 /* Run Script - remove unneeded Resources and Swift dirs from iOS LLDB.framework bundle */ = {
isa = PBXShellScriptBuildPhase;
@@ -6368,6 +6545,7 @@
2668032D116005E3008E1FE4 /* SBFileSpec.cpp in Sources */,
2668032E116005E5008E1FE4 /* SBEvent.cpp in Sources */,
2668032F116005E6008E1FE4 /* SBError.cpp in Sources */,
+ 23DCEA461D1C4D0F00A602B4 /* SBMemoryRegionInfo.cpp in Sources */,
26680330116005E7008E1FE4 /* SBDebugger.cpp in Sources */,
26680331116005E9008E1FE4 /* SBCommunication.cpp in Sources */,
26680332116005EA008E1FE4 /* SBCommandReturnObject.cpp in Sources */,
@@ -6382,6 +6560,7 @@
26DE205F1161901B00A093E2 /* SBCompileUnit.cpp in Sources */,
AF0EBBE9185940FB0059E52F /* SBQueueItem.cpp in Sources */,
AF0EBBE8185940FB0059E52F /* SBQueue.cpp in Sources */,
+ 964381701C8D6B8200023D59 /* SBLanguageRuntime.cpp in Sources */,
26DE20611161902700A093E2 /* SBBlock.cpp in Sources */,
26DE20631161904200A093E2 /* SBLineEntry.cpp in Sources */,
26DE20651161904E00A093E2 /* SBSymbol.cpp in Sources */,
@@ -6403,6 +6582,7 @@
8CCB018319BA51BF0009FD44 /* SBThreadCollection.cpp in Sources */,
26B82840142D020F002DBC64 /* SBSection.cpp in Sources */,
B2A58724143119D50092BFBA /* SBWatchpoint.cpp in Sources */,
+ 23DCEA471D1C4D0F00A602B4 /* SBMemoryRegionInfoList.cpp in Sources */,
263C4938178B50C40070F12D /* SBModuleSpec.cpp in Sources */,
2660AAB914622483003A9694 /* LLDBWrapPython.cpp in Sources */,
9475C18814E5E9FA001BFC6D /* SBTypeCategory.cpp in Sources */,
@@ -6435,14 +6615,12 @@
2689FFF913353DB600698AC0 /* BreakpointLocationCollection.cpp in Sources */,
2689FFFB13353DB600698AC0 /* BreakpointLocationList.cpp in Sources */,
2689FFFD13353DB600698AC0 /* BreakpointOptions.cpp in Sources */,
- 256CBDB11ADD0E1700BC6CDC /* NativeRegisterContextLinux_arm.cpp in Sources */,
2689FFFF13353DB600698AC0 /* BreakpointResolver.cpp in Sources */,
25420ECD1A6490B8009ADBCB /* OptionValueChar.cpp in Sources */,
2689000113353DB600698AC0 /* BreakpointResolverAddress.cpp in Sources */,
255EFF741AFABA720069F277 /* LockFileBase.cpp in Sources */,
945261C21B9A11FC00BF138D /* LibCxxList.cpp in Sources */,
2689000313353DB600698AC0 /* BreakpointResolverFileLine.cpp in Sources */,
- AF20F76D1AF18FC700751A6E /* SBLanguageRuntime.cpp in Sources */,
26474CA818D0CB070073DEBA /* RegisterContextFreeBSD_i386.cpp in Sources */,
449ACC98197DEA0B008D175E /* FastDemangle.cpp in Sources */,
2689000513353DB600698AC0 /* BreakpointResolverName.cpp in Sources */,
@@ -6468,6 +6646,7 @@
AFEC3362194A8ABA00FF05C6 /* StructuredData.cpp in Sources */,
6D55B2901A8A806200A70529 /* GDBRemoteCommunicationServerCommon.cpp in Sources */,
26474CAC18D0CB070073DEBA /* RegisterContextFreeBSD_x86_64.cpp in Sources */,
+ 9441816E1C8F5EC900E5A8D9 /* CommandAlias.cpp in Sources */,
2689001713353DDE00698AC0 /* CommandObjectDisassemble.cpp in Sources */,
2689001813353DDE00698AC0 /* CommandObjectExpression.cpp in Sources */,
9404957B1BEC497E00926025 /* NSException.cpp in Sources */,
@@ -6491,6 +6670,7 @@
2689002613353DDE00698AC0 /* CommandObjectSyntax.cpp in Sources */,
267A48011B1411E40021A5BC /* XML.cpp in Sources */,
AF8AD6371BEC28C400150209 /* PlatformRemoteAppleTV.cpp in Sources */,
+ 6D0F614E1C80AB0700A4ECEE /* JavaLanguageRuntime.cpp in Sources */,
2666ADC61B3CB675001FAFD3 /* DynamicLoaderHexagonDYLD.cpp in Sources */,
3F8169331ABB7A6D001DA9DF /* SystemLifetimeManager.cpp in Sources */,
4959511F1A1BC4BC00F6F8FC /* ClangModulesDeclVendor.cpp in Sources */,
@@ -6577,6 +6757,7 @@
2689005813353E0400698AC0 /* ValueObjectChild.cpp in Sources */,
E7723D441AC4A7FB002BA082 /* RegisterContextPOSIXCore_arm64.cpp in Sources */,
233B007F1960CB280090E598 /* ProcessLaunchInfo.cpp in Sources */,
+ 6D0F61591C80AB3500A4ECEE /* JavaFormatterFunctions.cpp in Sources */,
2689005913353E0400698AC0 /* ValueObjectConstResult.cpp in Sources */,
2689005A13353E0400698AC0 /* ValueObjectList.cpp in Sources */,
2689005B13353E0400698AC0 /* ValueObjectRegister.cpp in Sources */,
@@ -6608,6 +6789,7 @@
2689006B13353E0E00698AC0 /* IRForTarget.cpp in Sources */,
AF2BA6EC1A707E3400C5248A /* UriParser.cpp in Sources */,
2689006D13353E0E00698AC0 /* IRExecutionUnit.cpp in Sources */,
+ 304B2E461CAAA57B007829FE /* ClangUtil.cpp in Sources */,
2689006E13353E1A00698AC0 /* File.cpp in Sources */,
49724D991AD6ED390033C538 /* RenderScriptRuntime.cpp in Sources */,
2689006F13353E1A00698AC0 /* FileSpec.cpp in Sources */,
@@ -6624,6 +6806,7 @@
257E47171AA56C2000A62F81 /* ModuleCache.cpp in Sources */,
2689007413353E1A00698AC0 /* Terminal.cpp in Sources */,
2689007513353E1A00698AC0 /* TimeValue.cpp in Sources */,
+ 6D0F61431C80AAAE00A4ECEE /* JavaASTContext.cpp in Sources */,
2689007613353E1A00698AC0 /* CFCBundle.cpp in Sources */,
94BA8B70176F97CE005A91B5 /* CommandHistory.cpp in Sources */,
2689007713353E1A00698AC0 /* CFCData.cpp in Sources */,
@@ -6649,9 +6832,11 @@
2689008413353E2200698AC0 /* CommandObjectRegexCommand.cpp in Sources */,
2689008513353E2200698AC0 /* CommandReturnObject.cpp in Sources */,
6D95DC001B9DC057000E318A /* DIERef.cpp in Sources */,
+ AF27AD551D3603EA00CF2833 /* DynamicLoaderDarwin.cpp in Sources */,
3FDFE53519A29327009756A7 /* HostInfoBase.cpp in Sources */,
26474CBE18D0CB2D0073DEBA /* RegisterContextMach_i386.cpp in Sources */,
2689008613353E2200698AC0 /* Options.cpp in Sources */,
+ 9428BC2C1C6E64E4002A24D7 /* LibCxxAtomic.cpp in Sources */,
2689008713353E2200698AC0 /* ScriptInterpreter.cpp in Sources */,
260A63191861009E00FECF8E /* IOHandler.cpp in Sources */,
2689008D13353E4200698AC0 /* DynamicLoaderMacOSXDYLD.cpp in Sources */,
@@ -6717,6 +6902,7 @@
268900CD13353E5F00698AC0 /* UniqueDWARFASTType.cpp in Sources */,
944372DC171F6B4300E57C32 /* RegisterContextDummy.cpp in Sources */,
4C88BC2D1BA391B000AA0964 /* UserExpression.cpp in Sources */,
+ 49E4F66B1C9CAD16008487EA /* DiagnosticManager.cpp in Sources */,
268900CE13353E5F00698AC0 /* SymbolFileSymtab.cpp in Sources */,
266E82971B8CE3AC008FCA06 /* DWARFDIE.cpp in Sources */,
268900CF13353E5F00698AC0 /* SymbolVendorMacOSX.cpp in Sources */,
@@ -6776,6 +6962,7 @@
268900F513353E6F00698AC0 /* StackID.cpp in Sources */,
268900F613353E6F00698AC0 /* StopInfo.cpp in Sources */,
256CBDB41ADD0EFD00BC6CDC /* RegisterContextPOSIXCore_arm.cpp in Sources */,
+ 267F684F1CC02E270086832B /* RegisterContextPOSIXCore_s390x.cpp in Sources */,
268900F713353E6F00698AC0 /* Target.cpp in Sources */,
268900F813353E6F00698AC0 /* TargetList.cpp in Sources */,
268900F913353E6F00698AC0 /* Thread.cpp in Sources */,
@@ -6799,6 +6986,7 @@
3FDFED2919BA6D96009756A7 /* ThreadLauncher.cpp in Sources */,
232CB617191E00CD00EF39FC /* NativeBreakpointList.cpp in Sources */,
942829561A89614C00521B30 /* JSON.cpp in Sources */,
+ 267F68531CC02E920086832B /* RegisterContextLinux_s390x.cpp in Sources */,
232CB615191E00CD00EF39FC /* NativeBreakpoint.cpp in Sources */,
2689010313353E6F00698AC0 /* ThreadPlanStepRange.cpp in Sources */,
2689010413353E6F00698AC0 /* ThreadPlanStepInRange.cpp in Sources */,
@@ -6817,6 +7005,7 @@
2689010C13353E6F00698AC0 /* UnixSignals.cpp in Sources */,
2689011013353E8200698AC0 /* SharingPtr.cpp in Sources */,
2689011113353E8200698AC0 /* StringExtractor.cpp in Sources */,
+ 6D0F615A1C80AB3900A4ECEE /* JavaLanguage.cpp in Sources */,
2689011213353E8200698AC0 /* StringExtractorGDBRemote.cpp in Sources */,
2689011313353E8200698AC0 /* PseudoTerminal.cpp in Sources */,
E7723D4C1AC4A944002BA082 /* RegisterContextPOSIX_arm64.cpp in Sources */,
@@ -6842,6 +7031,7 @@
2377C2F819E613C100737875 /* PipePosix.cpp in Sources */,
AF77E0931A033C7F0096C0EA /* ABISysV_ppc64.cpp in Sources */,
26D5E15F135BAEA2006EA0A7 /* OptionGroupArchitecture.cpp in Sources */,
+ 6D0F61481C80AAD600A4ECEE /* DWARFASTParserJava.cpp in Sources */,
26D5E163135BB054006EA0A7 /* OptionGroupPlatform.cpp in Sources */,
94CD131A19BA33B400DB7BED /* TypeValidator.cpp in Sources */,
26BD407F135D2AE000237D80 /* FileLineResolver.cpp in Sources */,
@@ -6883,6 +7073,7 @@
26D1803E16CEBFD300EDFB5B /* KQueue.cpp in Sources */,
26A69C5F137A17A500262477 /* RegisterValue.cpp in Sources */,
2690B3711381D5C300ECFBAE /* Memory.cpp in Sources */,
+ 4C562CC71CC07DF700C52EAC /* PDBASTParser.cpp in Sources */,
B28058A1139988B0002D96D0 /* InferiorCallPOSIX.cpp in Sources */,
AF20F76A1AF18F9000751A6E /* ABISysV_arm64.cpp in Sources */,
26F73062139D8FDB00FD51C7 /* History.cpp in Sources */,
@@ -6898,6 +7089,7 @@
2642FBAE13D003B400ED6808 /* CommunicationKDP.cpp in Sources */,
2642FBB013D003B400ED6808 /* ProcessKDP.cpp in Sources */,
23D4007E1C210201000C3885 /* DebugMacros.cpp in Sources */,
+ 8C26C4261C3EA5F90031DF7C /* ThreadSanitizerRuntime.cpp in Sources */,
2642FBB213D003B400ED6808 /* ProcessKDPLog.cpp in Sources */,
263641191B34AEE200145B2F /* ABISysV_mips64.cpp in Sources */,
26957D9813D381C900670048 /* RegisterContextDarwin_arm.cpp in Sources */,
@@ -6932,6 +7124,7 @@
26E152261419CAD4007967D0 /* ObjectFilePECOFF.cpp in Sources */,
B2462247141AD37D00F3D409 /* OptionGroupWatchpoint.cpp in Sources */,
94B638631B8FB7F1004FE1E4 /* ObjCPlusPlusLanguage.cpp in Sources */,
+ 49DEF1251CD7C6DF006A7C7D /* BlockPointer.cpp in Sources */,
49A71FE7141FFA5C00D59478 /* IRInterpreter.cpp in Sources */,
49A71FE8141FFACF00D59478 /* DataEncoder.cpp in Sources */,
23DDF226196C3EE600BB8417 /* CommandOptionValidators.cpp in Sources */,
@@ -6972,6 +7165,7 @@
AE7F56291B8FE418001377A8 /* GoASTContext.cpp in Sources */,
260CC64E15D0440D002BF2E0 /* OptionValueFileSpec.cpp in Sources */,
AF2BCA6C18C7EFDE005B4526 /* JITLoaderGDB.cpp in Sources */,
+ 267F68571CC02EAE0086832B /* RegisterContextPOSIX_s390x.cpp in Sources */,
260CC64F15D0440D002BF2E0 /* OptionValueFileSpecLIst.cpp in Sources */,
490A36C0180F0E6F00BA31F8 /* PlatformWindows.cpp in Sources */,
260CC65015D0440D002BF2E0 /* OptionValueFormat.cpp in Sources */,
@@ -6981,6 +7175,7 @@
260CC65315D0440D002BF2E0 /* OptionValueUInt64.cpp in Sources */,
260CC65415D0440D002BF2E0 /* OptionValueUUID.cpp in Sources */,
94BA8B6D176F8C9B005A91B5 /* Range.cpp in Sources */,
+ 267F684A1CC02DED0086832B /* ABISysV_s390x.cpp in Sources */,
26DAED6315D327C200E15819 /* OptionValuePathMappings.cpp in Sources */,
B2B7CCEB15D1BD6700EEFB57 /* CommandObjectWatchpointCommand.cpp in Sources */,
E7E94ABC1B54961F00D0AE30 /* GDBRemoteSignals.cpp in Sources */,
@@ -7010,6 +7205,7 @@
94CB257116B0A4270059775D /* TypeSummary.cpp in Sources */,
94CB257216B0A4270059775D /* TypeSynthetic.cpp in Sources */,
94CB257416B1D3880059775D /* FormatCache.cpp in Sources */,
+ AF6335E21C87B21E00F7D554 /* SymbolFilePDB.cpp in Sources */,
A36FF33C17D8E94600244D40 /* OptionParser.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -7071,7 +7267,6 @@
266942351A6DC2AC0063BE93 /* MICmnMIValueTuple.cpp in Sources */,
2669422B1A6DC2AC0063BE93 /* MICmnLLDBProxySBValue.cpp in Sources */,
2669423E1A6DC2AC0063BE93 /* MIDriverBase.cpp in Sources */,
- 2669424C1A6DC2AC0063BE93 /* Platform.cpp in Sources */,
266942021A6DC2AC0063BE93 /* MICmdArgValBase.cpp in Sources */,
266942091A6DC2AC0063BE93 /* MICmdArgValOptionShort.cpp in Sources */,
266942291A6DC2AC0063BE93 /* MICmnLLDBDebugSessionInfo.cpp in Sources */,
@@ -7217,6 +7412,11 @@
target = 26DC6A0F1337FE6900FF7998 /* lldb-server */;
targetProxy = 94E829C8152D33B4006F96A3 /* PBXContainerItemProxy */;
};
+ AFCA21D21D18E556004386B8 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = "debugserver-mini";
+ targetProxy = AFCA21D11D18E556004386B8 /* PBXContainerItemProxy */;
+ };
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
@@ -7280,27 +7480,35 @@
"LLDB_COMPRESSION_CFLAGS[sdk=macosx10.11]" = "-DHAVE_LIBCOMPRESSION=1";
LLDB_COMPRESSION_LDFLAGS = "";
"LLDB_COMPRESSION_LDFLAGS[sdk=macosx10.11]" = "-weak-lcompression";
+ LLDB_COVERAGE_CFLAGS = "$(LLDB_COVERAGE_CFLAGS_$(LLDB_ENABLE_COVERAGE))";
+ LLDB_COVERAGE_CFLAGS_1 = "-fprofile-instr-generate -fcoverage-mapping";
+ LLDB_COVERAGE_LDFLAGS = "$(LLDB_COVERAGE_LDFLAGS_$(LLDB_ENABLE_COVERAGE))";
+ LLDB_COVERAGE_LDFLAGS_1 = "-fprofile-instr-generate";
LLDB_DISABLE_PYTHON = 0;
"LLDB_DISABLE_PYTHON[sdk=iphoneos*]" = 1;
+ LLDB_ENABLE_COVERAGE = 0;
LLDB_FRAMEWORK_INSTALL_DIR = /Applications/Xcode.app/Contents/SharedFrameworks;
LLDB_TOOLS_INSTALL_DIR = /usr/bin;
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
LLDB_ZLIB_LDFLAGS = "-lz";
LLVM_BUILD_DIR = "$(SRCROOT)/llvm-build/$(LLVM_CONFIGURATION)";
+ LLVM_BUILD_DIRTREE = "$(SRCROOT)/llvm-build";
LLVM_BUILD_DIR_ARCH = "$(CURRENT_ARCH)/";
LLVM_CONFIGURATION = "Release+Asserts";
LLVM_SOURCE_DIR = "$(SRCROOT)/llvm";
- MACOSX_DEPLOYMENT_TARGET = 10.8;
+ MACOSX_DEPLOYMENT_TARGET = 10.9;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = (
- "-flimit-debug-info",
"-Wparentheses",
"$(LLDB_ZLIB_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
+ "$(LLDB_COVERAGE_CFLAGS)",
+ "-Wimplicit-fallthrough",
);
OTHER_LDFLAGS = (
"$(LLDB_COMPRESSION_LDFLAGS)",
"$(LLDB_ZLIB_LDFLAGS)",
+ "$(LLDB_COVERAGE_LDFLAGS)",
);
PYTHON_FRAMEWORK_PATH = /System/Library/Frameworks/Python.framework;
PYTHON_VERSION_MAJOR = 2;
@@ -7365,27 +7573,35 @@
"LLDB_COMPRESSION_CFLAGS[sdk=macosx10.11]" = "-DHAVE_LIBCOMPRESSION=1";
LLDB_COMPRESSION_LDFLAGS = "";
"LLDB_COMPRESSION_LDFLAGS[sdk=macosx10.11]" = "-weak-lcompression";
+ LLDB_COVERAGE_CFLAGS = "$(LLDB_COVERAGE_CFLAGS_$(LLDB_ENABLE_COVERAGE))";
+ LLDB_COVERAGE_CFLAGS_1 = "-fprofile-instr-generate -fcoverage-mapping";
+ LLDB_COVERAGE_LDFLAGS = "$(LLDB_COVERAGE_LDFLAGS_$(LLDB_ENABLE_COVERAGE))";
+ LLDB_COVERAGE_LDFLAGS_1 = "-fprofile-instr-generate";
LLDB_DISABLE_PYTHON = 0;
"LLDB_DISABLE_PYTHON[sdk=iphoneos*]" = 1;
+ LLDB_ENABLE_COVERAGE = 0;
LLDB_FRAMEWORK_INSTALL_DIR = /Applications/Xcode.app/Contents/SharedFrameworks;
LLDB_TOOLS_INSTALL_DIR = /usr/bin;
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
LLDB_ZLIB_LDFLAGS = "-lz";
LLVM_BUILD_DIR = "$(SRCROOT)/llvm-build/$(LLVM_CONFIGURATION)";
+ LLVM_BUILD_DIRTREE = "$(SRCROOT)/llvm-build";
LLVM_BUILD_DIR_ARCH = "$(CURRENT_ARCH)/";
LLVM_CONFIGURATION = "Release+Asserts";
LLVM_SOURCE_DIR = "$(SRCROOT)/llvm";
- MACOSX_DEPLOYMENT_TARGET = 10.8;
+ MACOSX_DEPLOYMENT_TARGET = 10.9;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = (
- "-flimit-debug-info",
"-Wparentheses",
"$(LLDB_ZLIB_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
+ "$(LLDB_COVERAGE_CFLAGS)",
+ "-Wimplicit-fallthrough",
);
OTHER_LDFLAGS = (
"$(LLDB_COMPRESSION_LDFLAGS)",
"$(LLDB_ZLIB_LDFLAGS)",
+ "$(LLDB_COVERAGE_LDFLAGS)",
);
PYTHON_FRAMEWORK_PATH = /System/Library/Frameworks/Python.framework;
PYTHON_VERSION_MAJOR = 2;
@@ -7418,6 +7634,7 @@
);
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ LLDB_PYTHON_TESTSUITE_CC = "$(LLVM_BUILD_DIR)/x86_64/bin/clang";
MTL_ENABLE_DEBUG_INFO = YES;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
@@ -7446,6 +7663,7 @@
);
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ LLDB_PYTHON_TESTSUITE_CC = "$(LLVM_BUILD_DIR)/x86_64/bin/clang";
MTL_ENABLE_DEBUG_INFO = YES;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
@@ -7466,6 +7684,7 @@
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ LLDB_PYTHON_TESTSUITE_CC = "$(LLVM_BUILD_DIR)/x86_64/bin/clang";
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
@@ -7486,6 +7705,7 @@
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ LLDB_PYTHON_TESTSUITE_CC = "$(LLVM_BUILD_DIR)/x86_64/bin/clang";
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
@@ -7502,9 +7722,8 @@
"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
);
LLDB_GTESTS_CFLAGS = "-I $(LLVM_SOURCE_DIR)/utils/unittest/googletest/include -I $(LLVM_SOURCE_DIR)/include -I $(LLVM_BUILD_DIR)/x86_64/include -I include -I source -I $(PYTHON_FRAMEWORK_PATH)/Headers";
- LLDB_GTESTS_LDFLAGS = "$(LLVM_BUILD_DIR)/x86_64/$(LLVM_CONFIGURATION)/lib/libgtest.a -L $(PYTHON_FRAMEWORK_PATH)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib -l python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)";
+ LLDB_GTESTS_LDFLAGS = "$(LLVM_BUILD_DIR)/x86_64/lib/libgtest.a -L $(PYTHON_FRAMEWORK_PATH)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib -l python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)";
OTHER_CFLAGS = (
- "-flimit-debug-info",
"-Wparentheses",
"$(LLDB_ZLIB_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
@@ -7539,9 +7758,8 @@
"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
);
LLDB_GTESTS_CFLAGS = "-I $(LLVM_SOURCE_DIR)/utils/unittest/googletest/include -I $(LLVM_SOURCE_DIR)/include -I $(LLVM_BUILD_DIR)/x86_64/include -I include -I source -I $(PYTHON_FRAMEWORK_PATH)/Headers";
- LLDB_GTESTS_LDFLAGS = "$(LLVM_BUILD_DIR)/x86_64/$(LLVM_CONFIGURATION)/lib/libgtest.a -L $(PYTHON_FRAMEWORK_PATH)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib -l python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)";
+ LLDB_GTESTS_LDFLAGS = "$(LLVM_BUILD_DIR)/x86_64/lib/libgtest.a -L $(PYTHON_FRAMEWORK_PATH)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib -l python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)";
OTHER_CFLAGS = (
- "-flimit-debug-info",
"-Wparentheses",
"$(LLDB_ZLIB_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
@@ -7576,9 +7794,8 @@
"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
);
LLDB_GTESTS_CFLAGS = "-I $(LLVM_SOURCE_DIR)/utils/unittest/googletest/include -I $(LLVM_SOURCE_DIR)/include -I $(LLVM_BUILD_DIR)/x86_64/include -I include -I source -I $(PYTHON_FRAMEWORK_PATH)/Headers";
- LLDB_GTESTS_LDFLAGS = "$(LLVM_BUILD_DIR)/x86_64/$(LLVM_CONFIGURATION)/lib/libgtest.a -L $(PYTHON_FRAMEWORK_PATH)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib -l python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)";
+ LLDB_GTESTS_LDFLAGS = "$(LLVM_BUILD_DIR)/x86_64/lib/libgtest.a -L $(PYTHON_FRAMEWORK_PATH)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib -l python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)";
OTHER_CFLAGS = (
- "-flimit-debug-info",
"-Wparentheses",
"$(LLDB_ZLIB_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
@@ -7613,9 +7830,8 @@
"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
);
LLDB_GTESTS_CFLAGS = "-I $(LLVM_SOURCE_DIR)/utils/unittest/googletest/include -I $(LLVM_SOURCE_DIR)/include -I $(LLVM_BUILD_DIR)/x86_64/include -I include -I source -I $(PYTHON_FRAMEWORK_PATH)/Headers";
- LLDB_GTESTS_LDFLAGS = "$(LLVM_BUILD_DIR)/x86_64/$(LLVM_CONFIGURATION)/lib/libgtest.a -L $(PYTHON_FRAMEWORK_PATH)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib -l python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)";
+ LLDB_GTESTS_LDFLAGS = "$(LLVM_BUILD_DIR)/x86_64/lib/libgtest.a -L $(PYTHON_FRAMEWORK_PATH)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib -l python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)";
OTHER_CFLAGS = (
- "-flimit-debug-info",
"-Wparentheses",
"$(LLDB_ZLIB_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
@@ -7687,9 +7903,9 @@
CLANG_LINK_OBJC_RUNTIME = NO;
CLANG_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 350.99.0;
+ DYLIB_CURRENT_VERSION = 360.99.0;
EXPORTED_SYMBOLS_FILE = source/API/liblldb.xcode.exports;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -7760,10 +7976,10 @@
CLANG_LINK_OBJC_RUNTIME = NO;
CLANG_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEAD_CODE_STRIPPING = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 350.99.0;
+ DYLIB_CURRENT_VERSION = 360.99.0;
EXPORTED_SYMBOLS_FILE = source/API/liblldb.xcode.exports;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -7831,7 +8047,7 @@
buildSettings = {
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEBUGGING_SYMBOLS = YES;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
@@ -7856,7 +8072,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
OTHER_CFLAGS = "";
@@ -7872,7 +8088,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
OTHER_CFLAGS = "";
@@ -7886,8 +8102,8 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
- DYLIB_CURRENT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
+ DYLIB_CURRENT_VERSION = 360.99.0;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -7931,8 +8147,8 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
- DYLIB_CURRENT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
+ DYLIB_CURRENT_VERSION = 360.99.0;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -7976,8 +8192,8 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
- DYLIB_CURRENT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
+ DYLIB_CURRENT_VERSION = 360.99.0;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -8073,8 +8289,13 @@
"LLDB_COMPRESSION_CFLAGS[sdk=macosx10.11]" = "-DHAVE_LIBCOMPRESSION=1";
LLDB_COMPRESSION_LDFLAGS = "";
"LLDB_COMPRESSION_LDFLAGS[sdk=macosx10.11]" = "-weak-lcompression";
+ LLDB_COVERAGE_CFLAGS = "$(LLDB_COVERAGE_CFLAGS_$(LLDB_ENABLE_COVERAGE))";
+ LLDB_COVERAGE_CFLAGS_1 = "-fprofile-instr-generate -fcoverage-mapping";
+ LLDB_COVERAGE_LDFLAGS = "$(LLDB_COVERAGE_LDFLAGS_$(LLDB_ENABLE_COVERAGE))";
+ LLDB_COVERAGE_LDFLAGS_1 = "-fprofile-instr-generate";
LLDB_DISABLE_PYTHON = 0;
"LLDB_DISABLE_PYTHON[sdk=iphoneos*]" = 1;
+ LLDB_ENABLE_COVERAGE = 0;
LLDB_FRAMEWORK_INSTALL_DIR = /Applications/Xcode.app/Contents/SharedFrameworks;
"LLDB_FRAMEWORK_INSTALL_DIR[sdk=iphoneos*]" = /System/Library/PrivateFrameworks;
LLDB_TOOLS_INSTALL_DIR = /Applications/Xcode.app/Contents/Developer/usr/bin;
@@ -8082,19 +8303,22 @@
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
LLDB_ZLIB_LDFLAGS = "-lz";
LLVM_BUILD_DIR = "$(OBJROOT)/llvm";
+ LLVM_BUILD_DIRTREE = "$(OBJROOT)/llvm-build";
LLVM_BUILD_DIR_ARCH = "$(CURRENT_ARCH)/";
LLVM_CONFIGURATION = Release;
LLVM_SOURCE_DIR = "$(SRCROOT)/llvm";
MACOSX_DEPLOYMENT_TARGET = "";
OTHER_CFLAGS = (
- "-flimit-debug-info",
"-Wparentheses",
"$(LLDB_ZLIB_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
+ "$(LLDB_COVERAGE_CFLAGS)",
+ "-Wimplicit-fallthrough",
);
OTHER_LDFLAGS = (
"$(LLDB_COMPRESSION_LDFLAGS)",
"$(LLDB_ZLIB_LDFLAGS)",
+ "$(LLDB_COVERAGE_LDFLAGS)",
);
PYTHON_FRAMEWORK_PATH = /System/Library/Frameworks/Python.framework;
PYTHON_VERSION_MAJOR = 2;
@@ -8110,7 +8334,7 @@
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
@@ -8118,7 +8342,7 @@
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
HEADER_SEARCH_PATHS = "";
- INFOPLIST_FILE = "lldb-Info.plist";
+ INFOPLIST_FILE = "tools/driver/lldb-Info.plist";
INSTALL_PATH = "$(LLDB_TOOLS_INSTALL_DIR)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
"OTHER_LDFLAGS[sdk=iphoneos*]" = (
@@ -8142,7 +8366,7 @@
);
PRODUCT_NAME = lldb;
STRIP_INSTALLED_PRODUCT = YES;
- USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source";
+ USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include";
VERSIONING_SYSTEM = "apple-generic";
};
name = BuildAndIntegration;
@@ -8155,10 +8379,10 @@
CLANG_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEAD_CODE_STRIPPING = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 350.99.0;
+ DYLIB_CURRENT_VERSION = 360.99.0;
EXPORTED_SYMBOLS_FILE = source/API/liblldb.xcode.exports;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -8230,7 +8454,7 @@
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
@@ -8267,7 +8491,7 @@
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
@@ -8304,7 +8528,7 @@
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
@@ -8338,7 +8562,7 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
@@ -8405,7 +8629,6 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@@ -8414,7 +8637,6 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@@ -8488,12 +8710,10 @@
OTHER_CFLAGS = (
"$(inherited)",
"-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CFLAGS[sdk=iphoneos*]" = (
"$(inherited)",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*]" = "$(OTHER_CFLAGS)";
@@ -8561,12 +8781,10 @@
OTHER_CFLAGS = (
"$(inherited)",
"-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CFLAGS[sdk=iphoneos*]" = (
"$(inherited)",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*]" = "$(OTHER_CFLAGS)";
@@ -8634,12 +8852,10 @@
OTHER_CFLAGS = (
"$(inherited)",
"-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CFLAGS[sdk=iphoneos*]" = (
"$(inherited)",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*]" = "$(OTHER_CFLAGS)";
@@ -8676,7 +8892,7 @@
26F5C26C10F3D9A5009D5894 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
@@ -8686,10 +8902,9 @@
GCC_OPTIMIZATION_LEVEL = 0;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
HEADER_SEARCH_PATHS = "";
- INFOPLIST_FILE = "lldb-Info.plist";
+ INFOPLIST_FILE = "tools/driver/lldb-Info.plist";
INSTALL_PATH = "$(LLDB_TOOLS_INSTALL_DIR)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
- LLVM_BUILD_DIR_ARCH = "$(OBJROOT)/llvm";
OTHER_LDFLAGS = (
"$(inherited)",
"-sectcreate",
@@ -8699,7 +8914,7 @@
"-Wl,-rpath,@loader_path",
);
PRODUCT_NAME = lldb;
- USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source";
+ USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
@@ -8707,7 +8922,7 @@
26F5C26D10F3D9A5009D5894 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
@@ -8715,7 +8930,7 @@
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
HEADER_SEARCH_PATHS = "";
- INFOPLIST_FILE = "lldb-Info.plist";
+ INFOPLIST_FILE = "tools/driver/lldb-Info.plist";
INSTALL_PATH = "$(LLDB_TOOLS_INSTALL_DIR)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = (
@@ -8727,7 +8942,7 @@
"-Wl,-rpath,@loader_path",
);
PRODUCT_NAME = lldb;
- USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source";
+ USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
@@ -8792,27 +9007,35 @@
"LLDB_COMPRESSION_CFLAGS[sdk=macosx10.11internal]" = "-DHAVE_LIBCOMPRESSION=1";
LLDB_COMPRESSION_LDFLAGS = "";
"LLDB_COMPRESSION_LDFLAGS[sdk=macosx10.11]" = "-weak-lcompression";
+ LLDB_COVERAGE_CFLAGS = "$(LLDB_COVERAGE_CFLAGS_$(LLDB_ENABLE_COVERAGE))";
+ LLDB_COVERAGE_CFLAGS_1 = "-fprofile-instr-generate -fcoverage-mapping";
+ LLDB_COVERAGE_LDFLAGS = "$(LLDB_COVERAGE_LDFLAGS_$(LLDB_ENABLE_COVERAGE))";
+ LLDB_COVERAGE_LDFLAGS_1 = "-fprofile-instr-generate";
LLDB_DISABLE_PYTHON = 0;
"LLDB_DISABLE_PYTHON[sdk=iphoneos*]" = 1;
+ LLDB_ENABLE_COVERAGE = 0;
LLDB_FRAMEWORK_INSTALL_DIR = /Applications/Xcode.app/Contents/SharedFrameworks;
LLDB_TOOLS_INSTALL_DIR = /usr/bin;
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
LLDB_ZLIB_LDFLAGS = "-lz";
LLVM_BUILD_DIR = "$(SRCROOT)/llvm-build/$(LLVM_CONFIGURATION)";
+ LLVM_BUILD_DIRTREE = "$(SRCROOT)/llvm-build";
LLVM_BUILD_DIR_ARCH = "$(CURRENT_ARCH)/";
LLVM_CONFIGURATION = "Debug+Asserts";
LLVM_SOURCE_DIR = "$(SRCROOT)/llvm";
- MACOSX_DEPLOYMENT_TARGET = 10.8;
+ MACOSX_DEPLOYMENT_TARGET = 10.9;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = (
- "-flimit-debug-info",
"-Wparentheses",
"$(LLDB_ZLIB_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
+ "$(LLDB_COVERAGE_CFLAGS)",
+ "-Wimplicit-fallthrough",
);
OTHER_LDFLAGS = (
"$(LLDB_COMPRESSION_LDFLAGS)",
"$(LLDB_ZLIB_LDFLAGS)",
+ "$(LLDB_COVERAGE_LDFLAGS)",
);
PYTHON_FRAMEWORK_PATH = /System/Library/Frameworks/Python.framework;
PYTHON_VERSION_MAJOR = 2;
@@ -8828,7 +9051,6 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = DebugClang;
@@ -8852,7 +9074,7 @@
49BB8F381611172B00BDD462 /* DebugClang */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
@@ -8862,10 +9084,9 @@
GCC_OPTIMIZATION_LEVEL = 0;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
HEADER_SEARCH_PATHS = "";
- INFOPLIST_FILE = "lldb-Info.plist";
+ INFOPLIST_FILE = "tools/driver/lldb-Info.plist";
INSTALL_PATH = "$(LLDB_TOOLS_INSTALL_DIR)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
- LLVM_BUILD_DIR_ARCH = "$(OBJROOT)/llvm";
OTHER_LDFLAGS = (
"$(inherited)",
"-sectcreate",
@@ -8875,7 +9096,7 @@
"-Wl,-rpath,@loader_path",
);
PRODUCT_NAME = lldb;
- USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source";
+ USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include";
VERSIONING_SYSTEM = "apple-generic";
};
name = DebugClang;
@@ -8887,9 +9108,9 @@
CLANG_LINK_OBJC_RUNTIME = NO;
CLANG_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 350.99.0;
+ DYLIB_CURRENT_VERSION = 360.99.0;
EXPORTED_SYMBOLS_FILE = source/API/liblldb.xcode.exports;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -8970,8 +9191,8 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
- DYLIB_CURRENT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
+ DYLIB_CURRENT_VERSION = 360.99.0;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -9048,12 +9269,10 @@
OTHER_CFLAGS = (
"$(inherited)",
"-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CFLAGS[sdk=iphoneos*]" = (
"$(inherited)",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*]" = "$(OTHER_CFLAGS)";
@@ -9091,7 +9310,7 @@
buildSettings = {
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEBUGGING_SYMBOLS = YES;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
@@ -9135,17 +9354,14 @@
"$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)",
"$(inherited)",
);
- MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = YES;
OTHER_CFLAGS = (
"$(inherited)",
"-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CFLAGS[sdk=iphoneos*]" = (
"$(inherited)",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*]" = "$(OTHER_CFLAGS)";
@@ -9204,17 +9420,14 @@
"$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)",
"$(inherited)",
);
- MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = YES;
OTHER_CFLAGS = (
"$(inherited)",
"-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CFLAGS[sdk=iphoneos*]" = (
"$(inherited)",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*]" = "$(OTHER_CFLAGS)";
@@ -9270,17 +9483,14 @@
"$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)",
"$(inherited)",
);
- MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_CFLAGS = (
"$(inherited)",
"-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CFLAGS[sdk=iphoneos*]" = (
"$(inherited)",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*]" = "$(OTHER_CFLAGS)";
@@ -9338,17 +9548,14 @@
"$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)",
"$(inherited)",
);
- MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_CFLAGS = (
"$(inherited)",
"-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CFLAGS[sdk=iphoneos*]" = (
"$(inherited)",
- "-flimit-debug-info",
"-Wparentheses",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*]" = "$(OTHER_CFLAGS)";
diff --git a/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme b/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme
index e9240bb01118..17aedff2ce52 100644
--- a/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme
+++ b/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme
@@ -33,7 +33,7 @@
</AdditionalOptions>
</TestAction>
<LaunchAction
- buildConfiguration = "Debug"
+ buildConfiguration = "DebugClang"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
diff --git a/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme b/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme
index 01dea120349c..f13dc9703088 100644
--- a/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme
+++ b/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme
@@ -87,7 +87,7 @@
buildConfiguration = "DebugClang"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- launchStyle = "0"
+ launchStyle = "1"
useCustomWorkingDirectory = "NO"
customWorkingDirectory = "/Volumes/work/gclayton/Documents/devb/attach"
ignoresPersistentStateOnLaunch = "YES"
diff --git a/packages/Python/lldbsuite/support/encoded_file.py b/packages/Python/lldbsuite/support/encoded_file.py
new file mode 100644
index 000000000000..7581564f7e3a
--- /dev/null
+++ b/packages/Python/lldbsuite/support/encoded_file.py
@@ -0,0 +1,48 @@
+"""
+ The LLVM Compiler Infrastructure
+
+This file is distributed under the University of Illinois Open Source
+License. See LICENSE.TXT for details.
+
+Prepares language bindings for LLDB build process. Run with --help
+to see a description of the supported command line arguments.
+"""
+
+# Python modules:
+import io
+
+# Third party modules
+import six
+
+def _encoded_read(old_read, encoding):
+ def impl(size):
+ result = old_read(size)
+ # If this is Python 2 then we need to convert the resulting `unicode` back
+ # into a `str` before returning
+ if six.PY2:
+ result = result.encode(encoding)
+ return result
+ return impl
+
+def _encoded_write(old_write, encoding):
+ def impl(s):
+ # If we were asked to write a `str` (in Py2) or a `bytes` (in Py3) decode it
+ # as unicode before attempting to write.
+ if isinstance(s, six.binary_type):
+ s = s.decode(encoding)
+ return old_write(s)
+ return impl
+
+'''
+Create a Text I/O file object that can be written to with either unicode strings or byte strings
+under Python 2 and Python 3, and automatically encodes and decodes as necessary to return the
+native string type for the current Python version
+'''
+def open(file, encoding, mode='r', buffering=-1, errors=None, newline=None, closefd=True):
+ wrapped_file = io.open(file, mode=mode, buffering=buffering, encoding=encoding,
+ errors=errors, newline=newline, closefd=closefd)
+ new_read = _encoded_read(getattr(wrapped_file, 'read'), encoding)
+ new_write = _encoded_write(getattr(wrapped_file, 'write'), encoding)
+ setattr(wrapped_file, 'read', new_read)
+ setattr(wrapped_file, 'write', new_write)
+ return wrapped_file
diff --git a/packages/Python/lldbsuite/support/funcutils.py b/packages/Python/lldbsuite/support/funcutils.py
new file mode 100644
index 000000000000..53dd1fb370ba
--- /dev/null
+++ b/packages/Python/lldbsuite/support/funcutils.py
@@ -0,0 +1,16 @@
+from __future__ import print_function
+from __future__ import absolute_import
+
+# System modules
+import inspect
+
+# Third-party modules
+
+# LLDB modules
+
+def requires_self(func):
+ func_argc = len(inspect.getargspec(func).args)
+ if func_argc == 0 or (getattr(func,'im_self', None) is not None) or (hasattr(func, '__self__')):
+ return False
+ else:
+ return True
diff --git a/packages/Python/lldbsuite/support/gmodules.py b/packages/Python/lldbsuite/support/gmodules.py
new file mode 100644
index 000000000000..4f2fd9643b14
--- /dev/null
+++ b/packages/Python/lldbsuite/support/gmodules.py
@@ -0,0 +1,30 @@
+from __future__ import absolute_import
+from __future__ import print_function
+
+# System modules
+import os
+import re
+
+
+GMODULES_SUPPORT_MAP = {}
+GMODULES_HELP_REGEX = re.compile(r"\s-gmodules\s")
+
+
+def is_compiler_clang_with_gmodules(compiler_path):
+ # Before computing the result, check if we already have it cached.
+ if compiler_path in GMODULES_SUPPORT_MAP:
+ return GMODULES_SUPPORT_MAP[compiler_path]
+
+ def _gmodules_supported_internal():
+ compiler = os.path.basename(compiler_path)
+ if "clang" not in compiler:
+ return False
+ else:
+ # Check the compiler help for the -gmodules option.
+ clang_help = os.popen("%s --help" % compiler_path).read()
+ return GMODULES_HELP_REGEX.search(clang_help, re.DOTALL) is not None
+
+ GMODULES_SUPPORT_MAP[compiler_path] = _gmodules_supported_internal()
+ return GMODULES_SUPPORT_MAP[compiler_path]
+
+
diff --git a/packages/Python/lldbsuite/test/test_runner/lib/lldb_utils.py b/packages/Python/lldbsuite/support/optional_with.py
index e469bbf12207..41342288bc6a 100644
--- a/packages/Python/lldbsuite/test/test_runner/lib/lldb_utils.py
+++ b/packages/Python/lldbsuite/support/optional_with.py
@@ -1,18 +1,8 @@
-"""
-The LLVM Compiler Infrastructure
+# ====================================================================
+# Provides a with-style resource handler for optionally-None resources
+# ====================================================================
-This file is distributed under the University of Illinois Open Source
-License. See LICENSE.TXT for details.
-
-Provides classes used by the test results reporting infrastructure
-within the LLDB test suite.
-
-
-This module contains utilities used by the lldb test framwork.
-"""
-
-
-class OptionalWith(object):
+class optional_with(object):
# pylint: disable=too-few-public-methods
# This is a wrapper - it is not meant to provide any extra methods.
"""Provides a wrapper for objects supporting "with", allowing None.
@@ -22,13 +12,13 @@ class OptionalWith(object):
e.g.
- wrapped_lock = OptionalWith(thread.Lock())
+ wrapped_lock = optional_with(thread.Lock())
with wrapped_lock:
# Do something while the lock is obtained.
pass
might_be_none = None
- wrapped_none = OptionalWith(might_be_none)
+ wrapped_none = optional_with(might_be_none)
with wrapped_none:
# This code here still works.
pass
@@ -40,13 +30,13 @@ class OptionalWith(object):
lock.acquire()
try:
- code_fragament_always_run()
+ code_fragment_always_run()
finally:
if lock:
lock.release()
And I'd posit it is safer, as it becomes impossible to
- forget the try/finally using OptionalWith(), since
+ forget the try/finally using optional_with(), since
the with syntax can be used.
"""
def __init__(self, wrapped_object):
diff --git a/packages/Python/lldbsuite/test/android/platform/TestDefaultCacheLineSize.py b/packages/Python/lldbsuite/test/android/platform/TestDefaultCacheLineSize.py
index b925afe1b70c..2b6ac1818de7 100644
--- a/packages/Python/lldbsuite/test/android/platform/TestDefaultCacheLineSize.py
+++ b/packages/Python/lldbsuite/test/android/platform/TestDefaultCacheLineSize.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class DefaultCacheLineSizeTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/api/check_public_api_headers/TestPublicAPIHeaders.py b/packages/Python/lldbsuite/test/api/check_public_api_headers/TestPublicAPIHeaders.py
index 0d0507f1d70c..0ed2df3ceab1 100644
--- a/packages/Python/lldbsuite/test/api/check_public_api_headers/TestPublicAPIHeaders.py
+++ b/packages/Python/lldbsuite/test/api/check_public_api_headers/TestPublicAPIHeaders.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, re
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SBDirCheckerCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/api/listeners/Makefile b/packages/Python/lldbsuite/test/api/listeners/Makefile
new file mode 100644
index 000000000000..fbedeab4cb9b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/api/listeners/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
+
diff --git a/packages/Python/lldbsuite/test/api/listeners/TestListener.py b/packages/Python/lldbsuite/test/api/listeners/TestListener.py
new file mode 100644
index 000000000000..bd8c204e78cb
--- /dev/null
+++ b/packages/Python/lldbsuite/test/api/listeners/TestListener.py
@@ -0,0 +1,55 @@
+"""
+Test that we can listen to modules loaded events.
+"""
+
+from __future__ import print_function
+
+import copy
+import os
+import time
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+import six
+
+class ListenToModuleLoadedEvents (TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ self.build()
+
+ def test_receiving_breakpoint_added (self):
+ """Test that we get breakpoint added events, waiting on event classes on the debugger"""
+
+ my_listener = lldb.SBListener("test_listener")
+
+ my_listener.StartListeningForEventClass(self.dbg, lldb.SBTarget.GetBroadcasterClassName(), lldb.SBTarget.eBroadcastBitBreakpointChanged)
+
+ exe = os.path.join (os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+
+ bkpt = target.BreakpointCreateByName("main")
+
+ event = lldb.SBEvent()
+ my_listener.WaitForEvent(1, event)
+
+ self.assertTrue(event.IsValid(), "Got a valid event.")
+ self.assertTrue(lldb.SBBreakpoint.EventIsBreakpointEvent(event), "It is a breakpoint event.")
+ self.assertTrue(lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event) == lldb.eBreakpointEventTypeAdded, "It is a breakpoint added event.")
+ self.assertTrue(bkpt == lldb.SBBreakpoint.GetBreakpointFromEvent(event), "It is our breakpoint.")
+
+ # Now make sure if we stop listening for events we don't get them:
+
+ my_listener.StopListeningForEventClass(self.dbg, lldb.SBTarget.GetBroadcasterClassName(), lldb.SBTarget.eBroadcastBitBreakpointChanged)
+ my_listener.StopListeningForEvents(target.GetBroadcaster(), lldb.SBTarget.eBroadcastBitBreakpointChanged)
+
+ bkpt2 = target.BreakpointCreateByName("main")
+ my_listener.WaitForEvent(1, event)
+ self.assertTrue(not event.IsValid(), "We don't get events we aren't listening to.")
diff --git a/packages/Python/lldbsuite/test/api/listeners/main.c b/packages/Python/lldbsuite/test/api/listeners/main.c
new file mode 100644
index 000000000000..f930e5119158
--- /dev/null
+++ b/packages/Python/lldbsuite/test/api/listeners/main.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int
+main()
+{
+ printf ("Hello there.\n");
+}
diff --git a/packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py b/packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py
index 67dca2273d8a..ca2b986ce740 100644
--- a/packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py
+++ b/packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py
@@ -5,21 +5,21 @@ from __future__ import print_function
import os, re
-from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
-import lldb
import subprocess
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
class TestMultipleSimultaneousDebuggers(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipIfi386
@skipIfNoSBHeaders
- @expectedFailureFreeBSD("llvm.org/pr20282")
- @expectedFailureLinux("llvm.org/pr20282")
- @expectedFailureWindows # Test crashes
@expectedFlakeyDarwin()
+ @expectedFailureAll(archs="i[3-6]86", bugnumber="multi-process-driver.cpp creates an x64 target")
+ @expectedFailureAll(oslist=["windows", "linux", "freebsd"], bugnumber="llvm.org/pr20282")
def test_multiple_debuggers(self):
env = {self.dylibPath : self.getLLDBLibraryEnvVal()}
diff --git a/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py b/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py
index 9963cf23a8c6..7959bb73de02 100644
--- a/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py
+++ b/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, re
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
import subprocess
class SBBreakpointCallbackCase(TestBase):
@@ -36,7 +37,6 @@ class SBBreakpointCallbackCase(TestBase):
@skipIfNoSBHeaders
@skipIfWindows # clang-cl does not support throw or catch (llvm.org/pr24538)
@expectedFlakeyFreeBSD
- @expectedFlakeyLinux # Driver occasionally returns '1' as exit status
@expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["x86_64"])
def test_sb_api_listener_event_process_state(self):
""" Test that a registered SBListener receives events when a process
@@ -51,7 +51,7 @@ class SBBreakpointCallbackCase(TestBase):
@skipIfNoSBHeaders
@skipIfWindows # clang-cl does not support throw or catch (llvm.org/pr24538)
@expectedFlakeyFreeBSD
- @expectedFailureLinux
+ @expectedFailureAll(oslist=["linux"])
def test_sb_api_listener_resume(self):
""" Test that a process can be resumed from a non-main thread. """
self.build_and_test('driver.cpp listener_test.cpp test_listener_resume.cpp',
diff --git a/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp b/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp
index 0a698d1081d4..a79c5cb2a08b 100644
--- a/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp
+++ b/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp
@@ -18,7 +18,6 @@ using namespace std;
// listener thread control
extern atomic<bool> g_done;
-multithreaded_queue<string> g_thread_descriptions;
multithreaded_queue<string> g_frame_functions;
extern SBListener g_listener;
@@ -30,26 +29,21 @@ void listener_func() {
if (got_event) {
if (!event.IsValid())
throw Exception("event is not valid in listener thread");
-
- // send process description
- SBProcess process = SBProcess::GetProcessFromEvent(event);
- SBStream description;
-
- for (int i = 0; i < process.GetNumThreads(); ++i) {
- // send each thread description
- description.Clear();
- SBThread thread = process.GetThreadAtIndex(i);
- thread.GetDescription(description);
- g_thread_descriptions.push(description.GetData());
-
- // send each frame function name
- uint32_t num_frames = thread.GetNumFrames();
- for(int j = 0; j < num_frames; ++j) {
- const char* function_name = thread.GetFrameAtIndex(j).GetSymbol().GetName();
- if (function_name)
- g_frame_functions.push(function_name);
+ // send process description
+ SBProcess process = SBProcess::GetProcessFromEvent(event);
+ SBStream description;
+
+ for (int i = 0; i < process.GetNumThreads(); ++i) {
+ // send each thread description
+ SBThread thread = process.GetThreadAtIndex(i);
+ // send each frame function name
+ uint32_t num_frames = thread.GetNumFrames();
+ for(int j = 0; j < num_frames; ++j) {
+ const char* function_name = thread.GetFrameAtIndex(j).GetSymbol().GetName();
+ if (function_name)
+ g_frame_functions.push(string(function_name));
+ }
}
- }
}
}
}
@@ -57,12 +51,8 @@ void listener_func() {
void check_listener(SBDebugger &dbg) {
// check thread description
bool got_description = false;
- string desc = g_thread_descriptions.pop(5, got_description);
- if (!got_description)
- throw Exception("Expected at least one thread description string");
-
- // check at least one frame has a function name
- desc = g_frame_functions.pop(5, got_description);
- if (!got_description)
- throw Exception("Expected at least one frame function name string");
+ string func_name = g_frame_functions.pop(5, got_description);
+
+ if(got_description == false)
+ throw Exception("Expected at least one frame function");
}
diff --git a/packages/Python/lldbsuite/test/arm_emulation/TestEmulations.py b/packages/Python/lldbsuite/test/arm_emulation/TestEmulations.py
index 8a78d21e7978..d502b6dfca8a 100644
--- a/packages/Python/lldbsuite/test/arm_emulation/TestEmulations.py
+++ b/packages/Python/lldbsuite/test/arm_emulation/TestEmulations.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ARMEmulationTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/benchmarks/continue/TestBenchmarkContinue.py b/packages/Python/lldbsuite/test/benchmarks/continue/TestBenchmarkContinue.py
index 25ca13a3bfd9..f7c274522f9b 100644
--- a/packages/Python/lldbsuite/test/benchmarks/continue/TestBenchmarkContinue.py
+++ b/packages/Python/lldbsuite/test/benchmarks/continue/TestBenchmarkContinue.py
@@ -8,8 +8,10 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbbench import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestBenchmarkContinue(BenchBase):
diff --git a/packages/Python/lldbsuite/test/benchmarks/disassembly/TestDisassembly.py b/packages/Python/lldbsuite/test/benchmarks/disassembly/TestDisassembly.py
index a18cb2a64c76..8a0c044147a0 100644
--- a/packages/Python/lldbsuite/test/benchmarks/disassembly/TestDisassembly.py
+++ b/packages/Python/lldbsuite/test/benchmarks/disassembly/TestDisassembly.py
@@ -6,8 +6,10 @@ from __future__ import print_function
import os, sys
import lldb
-from lldbsuite.test import configuration
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbbench import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
def is_exe(fpath):
"""Returns true if fpath is an executable."""
@@ -40,7 +42,7 @@ class DisassembleDriverMainLoop(BenchBase):
@benchmarks_test
@no_debug_info_test
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_run_lldb_then_gdb(self):
"""Test disassembly on a large function with lldb vs. gdb."""
print()
@@ -56,7 +58,7 @@ class DisassembleDriverMainLoop(BenchBase):
@benchmarks_test
@no_debug_info_test
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_run_gdb_then_lldb(self):
"""Test disassembly on a large function with lldb vs. gdb."""
print()
diff --git a/packages/Python/lldbsuite/test/benchmarks/disassembly/TestDoAttachThenDisassembly.py b/packages/Python/lldbsuite/test/benchmarks/disassembly/TestDoAttachThenDisassembly.py
index b7b07090959e..f8e3d94b6577 100644
--- a/packages/Python/lldbsuite/test/benchmarks/disassembly/TestDoAttachThenDisassembly.py
+++ b/packages/Python/lldbsuite/test/benchmarks/disassembly/TestDoAttachThenDisassembly.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, sys
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbbench import *
-from lldbsuite.test import configuration
+from lldbsuite.test.lldbtest import *
class AttachThenDisassemblyBench(BenchBase):
diff --git a/packages/Python/lldbsuite/test/benchmarks/disassembly/TestXcode41Vs42GDBDisassembly.py b/packages/Python/lldbsuite/test/benchmarks/disassembly/TestXcode41Vs42GDBDisassembly.py
index 745e7b6a8c3b..618aac7eafcd 100644
--- a/packages/Python/lldbsuite/test/benchmarks/disassembly/TestXcode41Vs42GDBDisassembly.py
+++ b/packages/Python/lldbsuite/test/benchmarks/disassembly/TestXcode41Vs42GDBDisassembly.py
@@ -6,8 +6,11 @@ from __future__ import print_function
import os, sys
import lldb
-from lldbsuite.test import configuration
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbbench import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import configuration
+from lldbsuite.test import lldbutil
class XCode41Vs42GDBDisassembly(BenchBase):
@@ -25,7 +28,7 @@ class XCode41Vs42GDBDisassembly(BenchBase):
@benchmarks_test
@no_debug_info_test
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_run_41_then_42(self):
"""Test disassembly on a large function with 4.1 vs. 4.2's gdb."""
print()
@@ -39,7 +42,7 @@ class XCode41Vs42GDBDisassembly(BenchBase):
@benchmarks_test
@no_debug_info_test
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_run_42_then_41(self):
"""Test disassembly on a large function with 4.1 vs. 4.2's gdb."""
print()
diff --git a/packages/Python/lldbsuite/test/benchmarks/expression/TestExpressionCmd.py b/packages/Python/lldbsuite/test/benchmarks/expression/TestExpressionCmd.py
index abf45147d636..68d2bd9793e1 100644
--- a/packages/Python/lldbsuite/test/benchmarks/expression/TestExpressionCmd.py
+++ b/packages/Python/lldbsuite/test/benchmarks/expression/TestExpressionCmd.py
@@ -6,8 +6,11 @@ from __future__ import print_function
import os, sys
import lldb
-from lldbsuite.test import configuration
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbbench import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import configuration
+from lldbsuite.test import lldbutil
class ExpressionEvaluationCase(BenchBase):
@@ -20,7 +23,7 @@ class ExpressionEvaluationCase(BenchBase):
self.count = 25
@benchmarks_test
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_expr_cmd(self):
"""Test lldb's expression commands and collect statistics."""
self.build()
diff --git a/packages/Python/lldbsuite/test/benchmarks/expression/TestRepeatedExprs.py b/packages/Python/lldbsuite/test/benchmarks/expression/TestRepeatedExprs.py
index e5cada3563fa..2ad409e53b07 100644
--- a/packages/Python/lldbsuite/test/benchmarks/expression/TestRepeatedExprs.py
+++ b/packages/Python/lldbsuite/test/benchmarks/expression/TestRepeatedExprs.py
@@ -6,8 +6,11 @@ from __future__ import print_function
import os, sys
import lldb
+from lldbsuite.test.lldbbench import BenchBase
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
from lldbsuite.test import configuration
-from lldbsuite.test.lldbbench import *
+from lldbsuite.test import lldbutil
class RepeatedExprsCase(BenchBase):
@@ -22,7 +25,7 @@ class RepeatedExprsCase(BenchBase):
self.count = 100
@benchmarks_test
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_compare_lldb_to_gdb(self):
"""Test repeated expressions with lldb vs. gdb."""
self.build()
diff --git a/packages/Python/lldbsuite/test/benchmarks/frame_variable/TestFrameVariableResponse.py b/packages/Python/lldbsuite/test/benchmarks/frame_variable/TestFrameVariableResponse.py
index 5fdf05763fd1..9f5835297379 100644
--- a/packages/Python/lldbsuite/test/benchmarks/frame_variable/TestFrameVariableResponse.py
+++ b/packages/Python/lldbsuite/test/benchmarks/frame_variable/TestFrameVariableResponse.py
@@ -8,6 +8,7 @@ import os, sys
import lldb
from lldbsuite.test import configuration
from lldbsuite.test import lldbtest_config
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbbench import *
class FrameVariableResponseBench(BenchBase):
@@ -22,7 +23,7 @@ class FrameVariableResponseBench(BenchBase):
@benchmarks_test
@no_debug_info_test
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_startup_delay(self):
"""Test response time for the 'frame variable' command."""
print()
diff --git a/packages/Python/lldbsuite/test/benchmarks/libcxxlist/TestBenchmarkLibcxxList.py b/packages/Python/lldbsuite/test/benchmarks/libcxxlist/TestBenchmarkLibcxxList.py
index 7606bd1d3e8b..12e23e956943 100644
--- a/packages/Python/lldbsuite/test/benchmarks/libcxxlist/TestBenchmarkLibcxxList.py
+++ b/packages/Python/lldbsuite/test/benchmarks/libcxxlist/TestBenchmarkLibcxxList.py
@@ -8,8 +8,10 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbbench import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestBenchmarkLibcxxList(BenchBase):
diff --git a/packages/Python/lldbsuite/test/benchmarks/libcxxmap/TestBenchmarkLibcxxMap.py b/packages/Python/lldbsuite/test/benchmarks/libcxxmap/TestBenchmarkLibcxxMap.py
index 806bc0ee29e2..4466cd083ca3 100644
--- a/packages/Python/lldbsuite/test/benchmarks/libcxxmap/TestBenchmarkLibcxxMap.py
+++ b/packages/Python/lldbsuite/test/benchmarks/libcxxmap/TestBenchmarkLibcxxMap.py
@@ -9,7 +9,9 @@ from __future__ import print_function
import os, time
import lldb
from lldbsuite.test.lldbbench import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestBenchmarkLibcxxMap(BenchBase):
diff --git a/packages/Python/lldbsuite/test/benchmarks/startup/TestStartupDelays.py b/packages/Python/lldbsuite/test/benchmarks/startup/TestStartupDelays.py
index a215721ed52f..9d2356ab54f9 100644
--- a/packages/Python/lldbsuite/test/benchmarks/startup/TestStartupDelays.py
+++ b/packages/Python/lldbsuite/test/benchmarks/startup/TestStartupDelays.py
@@ -8,6 +8,7 @@ import os, sys
import lldb
from lldbsuite.test import configuration
from lldbsuite.test import lldbtest_config
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbbench import *
class StartupDelaysBench(BenchBase):
@@ -27,7 +28,7 @@ class StartupDelaysBench(BenchBase):
@benchmarks_test
@no_debug_info_test
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_startup_delay(self):
"""Test start up delays creating a target, setting a breakpoint, and run to breakpoint stop."""
print()
diff --git a/packages/Python/lldbsuite/test/benchmarks/stepping/TestSteppingSpeed.py b/packages/Python/lldbsuite/test/benchmarks/stepping/TestSteppingSpeed.py
index 14738a978e86..3ab760d4abe8 100644
--- a/packages/Python/lldbsuite/test/benchmarks/stepping/TestSteppingSpeed.py
+++ b/packages/Python/lldbsuite/test/benchmarks/stepping/TestSteppingSpeed.py
@@ -7,6 +7,9 @@ import lldb
from lldbsuite.test import configuration
from lldbsuite.test import lldbtest_config
from lldbsuite.test.lldbbench import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class SteppingSpeedBench(BenchBase):
@@ -23,7 +26,7 @@ class SteppingSpeedBench(BenchBase):
@benchmarks_test
@no_debug_info_test
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_run_lldb_steppings(self):
"""Test lldb steppings on a large executable."""
print()
diff --git a/packages/Python/lldbsuite/test/benchmarks/turnaround/TestCompileRunToBreakpointTurnaround.py b/packages/Python/lldbsuite/test/benchmarks/turnaround/TestCompileRunToBreakpointTurnaround.py
index 731eb13bbcfb..3106c4511f58 100644
--- a/packages/Python/lldbsuite/test/benchmarks/turnaround/TestCompileRunToBreakpointTurnaround.py
+++ b/packages/Python/lldbsuite/test/benchmarks/turnaround/TestCompileRunToBreakpointTurnaround.py
@@ -6,8 +6,11 @@ from __future__ import print_function
import os, sys
import lldb
-from lldbsuite.test import configuration
from lldbsuite.test.lldbbench import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import configuration
+from lldbsuite.test import lldbutil
class CompileRunToBreakpointBench(BenchBase):
@@ -24,7 +27,7 @@ class CompileRunToBreakpointBench(BenchBase):
@benchmarks_test
@no_debug_info_test
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_run_lldb_then_gdb(self):
"""Benchmark turnaround time with lldb vs. gdb."""
print()
diff --git a/packages/Python/lldbsuite/test/configuration.py b/packages/Python/lldbsuite/test/configuration.py
index 69ed9fc32e2b..d797b17c164e 100644
--- a/packages/Python/lldbsuite/test/configuration.py
+++ b/packages/Python/lldbsuite/test/configuration.py
@@ -100,6 +100,15 @@ regexp = None
# run. Use '-s session-dir-name' to specify a specific dir name.
sdir_name = None
+# Valid options:
+# f - test file name (without extension)
+# n - test class name
+# m - test method name
+# a - architecture
+# c - compiler path
+# The default is to write all fields.
+session_file_format = 'fnmac'
+
# Set this flag if there is any session info dumped during the test run.
sdir_has_content = False
diff --git a/packages/Python/lldbsuite/test/decorators.py b/packages/Python/lldbsuite/test/decorators.py
new file mode 100644
index 000000000000..93e48272c5d3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/decorators.py
@@ -0,0 +1,524 @@
+from __future__ import absolute_import
+from __future__ import print_function
+
+# System modules
+from distutils.version import LooseVersion, StrictVersion
+from functools import wraps
+import os
+import re
+import sys
+import tempfile
+
+# Third-party modules
+import six
+import unittest2
+
+# LLDB modules
+import use_lldb_suite
+
+import lldb
+from . import configuration
+from . import test_categories
+from lldbsuite.test_event.event_builder import EventBuilder
+from lldbsuite.support import funcutils
+from lldbsuite.test import lldbplatform
+from lldbsuite.test import lldbplatformutil
+
+class DecorateMode:
+ Skip, Xfail = range(2)
+
+
+# You can use no_match to reverse the test of the conditional that is used to match keyword
+# arguments in the skip / xfail decorators. If oslist=["windows", "linux"] skips windows
+# and linux, oslist=no_match(["windows", "linux"]) skips *unless* windows or linux.
+class no_match:
+ def __init__(self, item):
+ self.item = item
+
+def _check_expected_version(comparison, expected, actual):
+ def fn_leq(x,y): return x <= y
+ def fn_less(x,y): return x < y
+ def fn_geq(x,y): return x >= y
+ def fn_greater(x,y): return x > y
+ def fn_eq(x,y): return x == y
+ def fn_neq(x,y): return x != y
+
+ op_lookup = {
+ "==": fn_eq,
+ "=": fn_eq,
+ "!=": fn_neq,
+ "<>": fn_neq,
+ ">": fn_greater,
+ "<": fn_less,
+ ">=": fn_geq,
+ "<=": fn_leq
+ }
+ expected_str = '.'.join([str(x) for x in expected])
+ actual_str = '.'.join([str(x) for x in actual])
+
+ return op_lookup[comparison](LooseVersion(actual_str), LooseVersion(expected_str))
+
+def _match_decorator_property(expected, actual):
+ if actual is None or expected is None:
+ return True
+
+ if isinstance(expected, no_match):
+ return not _match_decorator_property(expected.item, actual)
+ elif isinstance(expected, (re._pattern_type,)+six.string_types):
+ return re.search(expected, actual) is not None
+ elif hasattr(expected, "__iter__"):
+ return any([x is not None and _match_decorator_property(x, actual) for x in expected])
+ else:
+ return expected == actual
+
+def expectedFailure(expected_fn, bugnumber=None):
+ def expectedFailure_impl(func):
+ if isinstance(func, type) and issubclass(func, unittest2.TestCase):
+ raise Exception("Decorator can only be used to decorate a test method")
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ self = args[0]
+ if funcutils.requires_self(expected_fn):
+ xfail_reason = expected_fn(self)
+ else:
+ xfail_reason = expected_fn()
+ if xfail_reason is not None:
+ if configuration.results_formatter_object is not None:
+ # Mark this test as expected to fail.
+ configuration.results_formatter_object.handle_event(
+ EventBuilder.event_for_mark_test_expected_failure(self))
+ xfail_func = unittest2.expectedFailure(func)
+ xfail_func(*args, **kwargs)
+ else:
+ func(*args, **kwargs)
+ return wrapper
+ # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows)
+ # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called
+ # the first way, the first argument will be the actual function because decorators are
+ # weird like that. So this is basically a check that says "which syntax was the original
+ # function decorated with?"
+ if six.callable(bugnumber):
+ return expectedFailure_impl(bugnumber)
+ else:
+ return expectedFailure_impl
+
+def skipTestIfFn(expected_fn, bugnumber=None):
+ def skipTestIfFn_impl(func):
+ if isinstance(func, type) and issubclass(func, unittest2.TestCase):
+ raise Exception("@skipTestIfFn can only be used to decorate a test method")
+
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ self = args[0]
+ if funcutils.requires_self(expected_fn):
+ reason = expected_fn(self)
+ else:
+ reason = expected_fn()
+
+ if reason is not None:
+ self.skipTest(reason)
+ else:
+ func(*args, **kwargs)
+ return wrapper
+
+ # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows)
+ # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called
+ # the first way, the first argument will be the actual function because decorators are
+ # weird like that. So this is basically a check that says "how was the decorator used"
+ if six.callable(bugnumber):
+ return skipTestIfFn_impl(bugnumber)
+ else:
+ return skipTestIfFn_impl
+
+def _decorateTest(mode,
+ bugnumber=None, oslist=None, hostoslist=None,
+ compiler=None, compiler_version=None,
+ archs=None, triple=None,
+ debug_info=None,
+ swig_version=None, py_version=None,
+ remote=None):
+ def fn(self):
+ skip_for_os = _match_decorator_property(lldbplatform.translate(oslist), self.getPlatform())
+ skip_for_hostos = _match_decorator_property(lldbplatform.translate(hostoslist), lldbplatformutil.getHostPlatform())
+ skip_for_compiler = _match_decorator_property(compiler, self.getCompiler()) and self.expectedCompilerVersion(compiler_version)
+ skip_for_arch = _match_decorator_property(archs, self.getArchitecture())
+ skip_for_debug_info = _match_decorator_property(debug_info, self.debug_info)
+ skip_for_triple = _match_decorator_property(triple, lldb.DBG.GetSelectedPlatform().GetTriple())
+ skip_for_remote = _match_decorator_property(remote, lldb.remote_platform is not None)
+
+ skip_for_swig_version = (swig_version is None) or (not hasattr(lldb, 'swig_version')) or (_check_expected_version(swig_version[0], swig_version[1], lldb.swig_version))
+ skip_for_py_version = (py_version is None) or _check_expected_version(py_version[0], py_version[1], sys.version_info)
+
+ # For the test to be skipped, all specified (e.g. not None) parameters must be True.
+ # An unspecified parameter means "any", so those are marked skip by default. And we skip
+ # the final test if all conditions are True.
+ conditions = [(oslist, skip_for_os, "target o/s"),
+ (hostoslist, skip_for_hostos, "host o/s"),
+ (compiler, skip_for_compiler, "compiler or version"),
+ (archs, skip_for_arch, "architecture"),
+ (debug_info, skip_for_debug_info, "debug info format"),
+ (triple, skip_for_triple, "target triple"),
+ (swig_version, skip_for_swig_version, "swig version"),
+ (py_version, skip_for_py_version, "python version"),
+ (remote, skip_for_remote, "platform locality (remote/local)")]
+ reasons = []
+ final_skip_result = True
+ for this_condition in conditions:
+ final_skip_result = final_skip_result and this_condition[1]
+ if this_condition[0] is not None and this_condition[1]:
+ reasons.append(this_condition[2])
+ reason_str = None
+ if final_skip_result:
+ mode_str = {DecorateMode.Skip : "skipping", DecorateMode.Xfail : "xfailing"}[mode]
+ if len(reasons) > 0:
+ reason_str = ",".join(reasons)
+ reason_str = "{} due to the following parameter(s): {}".format(mode_str, reason_str)
+ else:
+ reason_str = "{} unconditionally"
+ if bugnumber is not None and not six.callable(bugnumber):
+ reason_str = reason_str + " [" + str(bugnumber) + "]"
+ return reason_str
+
+ if mode == DecorateMode.Skip:
+ return skipTestIfFn(fn, bugnumber)
+ elif mode == DecorateMode.Xfail:
+ return expectedFailure(fn, bugnumber)
+ else:
+ return None
+
+# provide a function to xfail on defined oslist, compiler version, and archs
+# if none is specified for any argument, that argument won't be checked and thus means for all
+# for example,
+# @expectedFailureAll, xfail for all platform/compiler/arch,
+# @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture
+# @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386
+def expectedFailureAll(bugnumber=None,
+ oslist=None, hostoslist=None,
+ compiler=None, compiler_version=None,
+ archs=None, triple=None,
+ debug_info=None,
+ swig_version=None, py_version=None,
+ remote=None):
+ return _decorateTest(DecorateMode.Xfail,
+ bugnumber=bugnumber,
+ oslist=oslist, hostoslist=hostoslist,
+ compiler=compiler, compiler_version=compiler_version,
+ archs=archs, triple=triple,
+ debug_info=debug_info,
+ swig_version=swig_version, py_version=py_version,
+ remote=remote)
+
+
+# provide a function to skip on defined oslist, compiler version, and archs
+# if none is specified for any argument, that argument won't be checked and thus means for all
+# for example,
+# @skipIf, skip for all platform/compiler/arch,
+# @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
+# @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
+def skipIf(bugnumber=None,
+ oslist=None, hostoslist=None,
+ compiler=None, compiler_version=None,
+ archs=None, triple=None,
+ debug_info=None,
+ swig_version=None, py_version=None,
+ remote=None):
+ return _decorateTest(DecorateMode.Skip,
+ bugnumber=bugnumber,
+ oslist=oslist, hostoslist=hostoslist,
+ compiler=compiler, compiler_version=compiler_version,
+ archs=archs, triple=triple,
+ debug_info=debug_info,
+ swig_version=swig_version, py_version=py_version,
+ remote=remote)
+
+def _skip_for_android(reason, api_levels, archs):
+ def impl(obj):
+ result = lldbplatformutil.match_android_device(obj.getArchitecture(), valid_archs=archs, valid_api_levels=api_levels)
+ return reason if result else None
+ return impl
+
+def add_test_categories(cat):
+ """Add test categories to a TestCase method"""
+ cat = test_categories.validate(cat, True)
+ def impl(func):
+ if isinstance(func, type) and issubclass(func, unittest2.TestCase):
+ raise Exception("@add_test_categories can only be used to decorate a test method")
+ if hasattr(func, "categories"):
+ cat.extend(func.categories)
+ func.categories = cat
+ return func
+
+ return impl
+
+def benchmarks_test(func):
+ """Decorate the item as a benchmarks test."""
+ def should_skip_benchmarks_test():
+ return "benchmarks test"
+
+ # Mark this function as such to separate them from the regular tests.
+ result = skipTestIfFn(should_skip_benchmarks_test)(func)
+ result.__benchmarks_test__ = True
+ return result
+
+def no_debug_info_test(func):
+ """Decorate the item as a test what don't use any debug info. If this annotation is specified
+ then the test runner won't generate a separate test for each debug info format. """
+ if isinstance(func, type) and issubclass(func, unittest2.TestCase):
+ raise Exception("@no_debug_info_test can only be used to decorate a test method")
+ @wraps(func)
+ def wrapper(self, *args, **kwargs):
+ return func(self, *args, **kwargs)
+
+ # Mark this function as such to separate them from the regular tests.
+ wrapper.__no_debug_info_test__ = True
+ return wrapper
+
+def debugserver_test(func):
+ """Decorate the item as a debugserver test."""
+ def should_skip_debugserver_test():
+ return "debugserver tests" if configuration.dont_do_debugserver_test else None
+ return skipTestIfFn(should_skip_debugserver_test)(func)
+
+def llgs_test(func):
+ """Decorate the item as a lldb-server test."""
+ def should_skip_llgs_tests():
+ return "llgs tests" if configuration.dont_do_llgs_test else None
+ return skipTestIfFn(should_skip_llgs_tests)(func)
+
+def not_remote_testsuite_ready(func):
+ """Decorate the item as a test which is not ready yet for remote testsuite."""
+ def is_remote():
+ return "Not ready for remote testsuite" if lldb.remote_platform else None
+ return skipTestIfFn(is_remote)(func)
+
+def expectedFailureOS(oslist, bugnumber=None, compilers=None, debug_info=None, archs=None):
+ return expectedFailureAll(oslist=oslist, bugnumber=bugnumber, compiler=compilers, archs=archs, debug_info=debug_info)
+
+def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None):
+ # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
+ return expectedFailureOS(lldbplatform.darwin_all, bugnumber, compilers, debug_info=debug_info)
+
+def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
+ """ Mark a test as xfail for Android.
+
+ Arguments:
+ bugnumber - The LLVM pr associated with the problem.
+ api_levels - A sequence of numbers specifying the Android API levels
+ for which a test is expected to fail. None means all API level.
+ arch - A sequence of architecture names specifying the architectures
+ for which a test is expected to fail. None means all architectures.
+ """
+ return expectedFailure(_skip_for_android("xfailing on android", api_levels, archs), bugnumber)
+
+# Flakey tests get two chances to run. If they fail the first time round, the result formatter
+# makes sure it is run one more time.
+def expectedFlakey(expected_fn, bugnumber=None):
+ def expectedFailure_impl(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ self = args[0]
+ if expected_fn(self):
+ # Send event marking test as explicitly eligible for rerunning.
+ if configuration.results_formatter_object is not None:
+ # Mark this test as rerunnable.
+ configuration.results_formatter_object.handle_event(
+ EventBuilder.event_for_mark_test_rerun_eligible(self))
+ func(*args, **kwargs)
+ return wrapper
+ # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows)
+ # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called
+ # the first way, the first argument will be the actual function because decorators are
+ # weird like that. So this is basically a check that says "which syntax was the original
+ # function decorated with?"
+ if six.callable(bugnumber):
+ return expectedFailure_impl(bugnumber)
+ else:
+ return expectedFailure_impl
+
+def expectedFlakeyDwarf(bugnumber=None):
+ def fn(self):
+ return self.debug_info == "dwarf"
+ return expectedFlakey(fn, bugnumber)
+
+def expectedFlakeyDsym(bugnumber=None):
+ def fn(self):
+ return self.debug_info == "dwarf"
+ return expectedFlakey(fn, bugnumber)
+
+def expectedFlakeyOS(oslist, bugnumber=None, compilers=None):
+ def fn(self):
+ return (self.getPlatform() in oslist and
+ self.expectedCompiler(compilers))
+ return expectedFlakey(fn, bugnumber)
+
+def expectedFlakeyDarwin(bugnumber=None, compilers=None):
+ # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
+ return expectedFlakeyOS(lldbplatformutil.getDarwinOSTriples(), bugnumber, compilers)
+
+def expectedFlakeyFreeBSD(bugnumber=None, compilers=None):
+ return expectedFlakeyOS(['freebsd'], bugnumber, compilers)
+
+def expectedFlakeyLinux(bugnumber=None, compilers=None):
+ return expectedFlakeyOS(['linux'], bugnumber, compilers)
+
+def expectedFlakeyNetBSD(bugnumber=None, compilers=None):
+ return expectedFlakeyOS(['netbsd'], bugnumber, compilers)
+
+def expectedFlakeyCompiler(compiler, compiler_version=None, bugnumber=None):
+ if compiler_version is None:
+ compiler_version=['=', None]
+ def fn(self):
+ return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
+ return expectedFlakey(fn, bugnumber)
+
+# @expectedFlakeyClang('bugnumber', ['<=', '3.4'])
+def expectedFlakeyClang(bugnumber=None, compiler_version=None):
+ return expectedFlakeyCompiler('clang', compiler_version, bugnumber)
+
+# @expectedFlakeyGcc('bugnumber', ['<=', '3.4'])
+def expectedFlakeyGcc(bugnumber=None, compiler_version=None):
+ return expectedFlakeyCompiler('gcc', compiler_version, bugnumber)
+
+def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None):
+ return expectedFlakey(_skip_for_android("flakey on android", api_levels, archs), bugnumber)
+
+def skipIfRemote(func):
+ """Decorate the item to skip tests if testing remotely."""
+ def is_remote():
+ return "skip on remote platform" if lldb.remote_platform else None
+ return skipTestIfFn(is_remote)(func)
+
+def skipIfRemoteDueToDeadlock(func):
+ """Decorate the item to skip tests if testing remotely due to the test deadlocking."""
+ def is_remote():
+ return "skip on remote platform (deadlocks)" if lldb.remote_platform else None
+ return skipTestIfFn(is_remote)(func)
+
+def skipIfNoSBHeaders(func):
+ """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
+ def are_sb_headers_missing():
+ if lldbplatformutil.getHostPlatform() == 'darwin':
+ header = os.path.join(os.environ["LLDB_LIB_DIR"], 'LLDB.framework', 'Versions','Current','Headers','LLDB.h')
+ else:
+ header = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h")
+ if not os.path.exists(header):
+ return "skip because LLDB.h header not found"
+ return None
+
+ return skipTestIfFn(are_sb_headers_missing)(func)
+
+def skipIfiOSSimulator(func):
+ """Decorate the item to skip tests that should be skipped on the iOS Simulator."""
+ def is_ios_simulator():
+ return "skip on the iOS Simulator" if configuration.lldb_platform_name == 'ios-simulator' else None
+ return skipTestIfFn(is_ios_simulator)(func)
+
+def skipIfFreeBSD(func):
+ """Decorate the item to skip tests that should be skipped on FreeBSD."""
+ return skipIfPlatform(["freebsd"])(func)
+
+def skipIfNetBSD(func):
+ """Decorate the item to skip tests that should be skipped on NetBSD."""
+ return skipIfPlatform(["netbsd"])(func)
+
+def skipIfDarwin(func):
+ """Decorate the item to skip tests that should be skipped on Darwin."""
+ return skipIfPlatform(lldbplatform.translate(lldbplatform.darwin_all))(func)
+
+def skipIfLinux(func):
+ """Decorate the item to skip tests that should be skipped on Linux."""
+ return skipIfPlatform(["linux"])(func)
+
+def skipIfWindows(func):
+ """Decorate the item to skip tests that should be skipped on Windows."""
+ return skipIfPlatform(["windows"])(func)
+
+def skipUnlessWindows(func):
+ """Decorate the item to skip tests that should be skipped on any non-Windows platform."""
+ return skipUnlessPlatform(["windows"])(func)
+
+def skipUnlessDarwin(func):
+ """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
+ return skipUnlessPlatform(lldbplatformutil.getDarwinOSTriples())(func)
+
+def skipUnlessGoInstalled(func):
+ """Decorate the item to skip tests when no Go compiler is available."""
+ def is_go_missing(self):
+ compiler = self.getGoCompilerVersion()
+ if not compiler:
+ return "skipping because go compiler not found"
+ match_version = re.search(r"(\d+\.\d+(\.\d+)?)", compiler)
+ if not match_version:
+ # Couldn't determine version.
+ return "skipping because go version could not be parsed out of {}".format(compiler)
+ else:
+ min_strict_version = StrictVersion("1.4.0")
+ compiler_strict_version = StrictVersion(match_version.group(1))
+ if compiler_strict_version < min_strict_version:
+ return "skipping because available version ({}) does not meet minimum required version ({})".format(
+ compiler_strict_version, min_strict_version)
+ return None
+ return skipTestIfFn(is_go_missing)(func)
+
+def skipIfHostIncompatibleWithRemote(func):
+ """Decorate the item to skip tests if binaries built on this host are incompatible."""
+ def is_host_incompatible_with_remote(self):
+ host_arch = self.getLldbArchitecture()
+ host_platform = lldbplatformutil.getHostPlatform()
+ target_arch = self.getArchitecture()
+ target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform()
+ if not (target_arch == 'x86_64' and host_arch == 'i386') and host_arch != target_arch:
+ return "skipping because target %s is not compatible with host architecture %s" % (target_arch, host_arch)
+ elif target_platform != host_platform:
+ return "skipping because target is %s but host is %s" % (target_platform, host_platform)
+ return None
+ return skipTestIfFn(is_host_incompatible_with_remote)(func)
+
+def skipIfPlatform(oslist):
+ """Decorate the item to skip tests if running on one of the listed platforms."""
+ # This decorator cannot be ported to `skipIf` yet because it is used on entire
+ # classes, which `skipIf` explicitly forbids.
+ return unittest2.skipIf(lldbplatformutil.getPlatform() in oslist,
+ "skip on %s" % (", ".join(oslist)))
+
+def skipUnlessPlatform(oslist):
+ """Decorate the item to skip tests unless running on one of the listed platforms."""
+ # This decorator cannot be ported to `skipIf` yet because it is used on entire
+ # classes, which `skipIf` explicitly forbids.
+ return unittest2.skipUnless(lldbplatformutil.getPlatform() in oslist,
+ "requires on of %s" % (", ".join(oslist)))
+
+def skipIfTargetAndroid(api_levels=None, archs=None):
+ """Decorator to skip tests when the target is Android.
+
+ Arguments:
+ api_levels - The API levels for which the test should be skipped. If
+ it is None, then the test will be skipped for all API levels.
+ arch - A sequence of architecture names specifying the architectures
+ for which a test is skipped. None means all architectures.
+ """
+ return skipTestIfFn(_skip_for_android("skipping for android", api_levels, archs))
+
+def skipUnlessCompilerRt(func):
+ """Decorate the item to skip tests if testing remotely."""
+ def is_compiler_rt_missing():
+ compilerRtPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", "llvm","projects","compiler-rt")
+ return "compiler-rt not found" if not os.path.exists(compilerRtPath) else None
+ return skipTestIfFn(is_compiler_rt_missing)(func)
+
+def skipUnlessThreadSanitizer(func):
+ """Decorate the item to skip test unless Clang -fsanitize=thread is supported."""
+ def is_compiler_clang_with_thread_sanitizer(self):
+ compiler_path = self.getCompiler()
+ compiler = os.path.basename(compiler_path)
+ if not compiler.startswith("clang"):
+ return "Test requires clang as compiler"
+ f = tempfile.NamedTemporaryFile()
+ cmd = "echo 'int main() {}' | %s -x c -o %s -" % (compiler_path, f.name)
+ if os.popen(cmd).close() != None:
+ return None # The compiler cannot compile at all, let's *not* skip the test
+ cmd = "echo 'int main() {}' | %s -fsanitize=thread -x c -o %s -" % (compiler_path, f.name)
+ if os.popen(cmd).close() != None:
+ return "Compiler cannot compile with -fsanitize=thread"
+ return None
+ return skipTestIfFn(is_compiler_clang_with_thread_sanitizer)(func)
diff --git a/packages/Python/lldbsuite/test/dosep.py b/packages/Python/lldbsuite/test/dosep.py
index 87a410fa090f..37ca91adb140 100644
--- a/packages/Python/lldbsuite/test/dosep.py
+++ b/packages/Python/lldbsuite/test/dosep.py
@@ -30,8 +30,8 @@ ulimit -c unlimited
echo core.%p | sudo tee /proc/sys/kernel/core_pattern
"""
-from __future__ import print_function
from __future__ import absolute_import
+from __future__ import print_function
# system packages and modules
import asyncore
@@ -53,18 +53,13 @@ import lldbsuite
import lldbsuite.support.seven as seven
from . import configuration
-from . import dotest_channels
from . import dotest_args
-from . import result_formatter
-
-from .result_formatter import EventBuilder
+from lldbsuite.support import optional_with
+from lldbsuite.test_event import dotest_channels
+from lldbsuite.test_event.event_builder import EventBuilder
+from lldbsuite.test_event import formatter
-
-# Todo: Convert this folder layout to be relative-import friendly and
-# don't hack up sys.path like this
-sys.path.append(os.path.join(os.path.dirname(__file__), "test_runner", "lib"))
-import lldb_utils
-import process_control
+from .test_runner import process_control
# Status codes for running command with timeout.
eTimedOut, ePassed, eFailed = 124, 0, 1
@@ -109,13 +104,17 @@ def setup_global_variables(
global GET_WORKER_INDEX
GET_WORKER_INDEX = get_worker_index_use_pid
-def report_test_failure(name, command, output):
+def report_test_failure(name, command, output, timeout):
global output_lock
with output_lock:
if not (RESULTS_FORMATTER and RESULTS_FORMATTER.is_using_terminal()):
print(file=sys.stderr)
print(output, file=sys.stderr)
- print("[%s FAILED]" % name, file=sys.stderr)
+ if timeout:
+ timeout_str = " (TIMEOUT)"
+ else:
+ timeout_str = ""
+ print("[%s FAILED]%s" % (name, timeout_str), file=sys.stderr)
print("Command invoked: %s" % ' '.join(command), file=sys.stderr)
update_progress(name)
@@ -173,7 +172,7 @@ class DoTestProcessDriver(process_control.ProcessDriver):
super(DoTestProcessDriver, self).__init__(
soft_terminate_timeout=soft_terminate_timeout)
self.output_file = output_file
- self.output_lock = lldb_utils.OptionalWith(output_file_lock)
+ self.output_lock = optional_with.optional_with(output_file_lock)
self.pid_events = pid_events
self.results = None
self.file_name = file_name
@@ -211,7 +210,7 @@ class DoTestProcessDriver(process_control.ProcessDriver):
# only stderr does.
report_test_pass(self.file_name, output[1])
else:
- report_test_failure(self.file_name, command, output[1])
+ report_test_failure(self.file_name, command, output[1], was_timeout)
# Save off the results for the caller.
self.results = (
@@ -299,9 +298,9 @@ def send_events_to_collector(events, command):
event_port = int(command[arg_index])
# Create results formatter connected back to collector via socket.
- config = result_formatter.FormatterConfig()
+ config = formatter.FormatterConfig()
config.port = event_port
- formatter_spec = result_formatter.create_results_formatter(config)
+ formatter_spec = formatter.create_results_formatter(config)
if formatter_spec is None or formatter_spec.formatter is None:
raise Exception(
"Failed to create socket-based ResultsFormatter "
@@ -420,9 +419,14 @@ def process_dir(root, files, dotest_argv, inferior_pid_events):
results = []
for (base_name, full_test_path) in files:
import __main__ as main
+ global dotest_options
+ if dotest_options.p and not re.search(dotest_options.p, base_name):
+ continue
+
script_file = main.__file__
command = ([sys.executable, script_file] +
dotest_argv +
+ ["-S", dotest_options.session_file_format] +
["--inferior", "-p", base_name, root])
timeout_name = os.path.basename(os.path.splitext(base_name)[0]).upper()
@@ -1135,34 +1139,27 @@ def walk_and_invoke(test_files, dotest_argv, num_workers, test_runner_func):
def getExpectedTimeouts(platform_name):
# returns a set of test filenames that might timeout
# are we running against a remote target?
- host = sys.platform
+
+ # Figure out the target system for which we're collecting
+ # the set of expected timeout test filenames.
if platform_name is None:
target = sys.platform
else:
m = re.search(r'remote-(\w+)', platform_name)
- target = m.group(1)
+ if m is not None:
+ target = m.group(1)
+ else:
+ target = platform_name
expected_timeout = set()
- if target.startswith("android"):
- expected_timeout |= {
- "TestExitDuringStep.py",
- "TestHelloWorld.py",
- }
- elif target.startswith("freebsd"):
+ if target.startswith("freebsd"):
expected_timeout |= {
"TestBreakpointConditions.py",
"TestChangeProcessGroup.py",
"TestValueObjectRecursion.py",
"TestWatchpointConditionAPI.py",
}
- elif target.startswith("darwin"):
- expected_timeout |= {
- # times out on MBP Retina, Mid 2012
- "TestThreadSpecificBreakpoint.py",
- "TestExitDuringStep.py",
- "TestIntegerTypesExpr.py",
- }
return expected_timeout
diff --git a/packages/Python/lldbsuite/test/dotest.py b/packages/Python/lldbsuite/test/dotest.py
index 723f26a417e4..702e57e99871 100644
--- a/packages/Python/lldbsuite/test/dotest.py
+++ b/packages/Python/lldbsuite/test/dotest.py
@@ -23,7 +23,6 @@ from __future__ import print_function
# System modules
import atexit
-import importlib
import os
import errno
import platform
@@ -31,7 +30,6 @@ import signal
import socket
import subprocess
import sys
-import inspect
# Third-party modules
import six
@@ -43,9 +41,9 @@ from . import configuration
from . import dotest_args
from . import lldbtest_config
from . import test_categories
-from . import result_formatter
+from lldbsuite.test_event import formatter
from . import test_result
-from .result_formatter import EventBuilder
+from lldbsuite.test_event.event_builder import EventBuilder
from ..support import seven
def is_exe(fpath):
@@ -309,7 +307,7 @@ def parseOptionsAndInitTestdirs():
configuration.lldbFrameworkPath = args.framework
if args.executable:
- lldbtest_config.lldbExec = args.executable
+ lldbtest_config.lldbExec = os.path.realpath(args.executable)
if args.p:
if args.p.startswith('-'):
@@ -323,6 +321,7 @@ def parseOptionsAndInitTestdirs():
if args.s.startswith('-'):
usage(parser)
configuration.sdir_name = args.s
+ configuration.session_file_format = args.session_file_format
if args.t:
os.environ['LLDB_COMMAND_TRACE'] = 'YES'
@@ -359,7 +358,7 @@ def parseOptionsAndInitTestdirs():
# Capture test results-related args.
if args.curses and not args.inferior:
# Act as if the following args were set.
- args.results_formatter = "lldbsuite.test.curses_results.Curses"
+ args.results_formatter = "lldbsuite.test_event.formatter.curses.Curses"
args.results_file = "stdout"
if args.results_file:
@@ -383,7 +382,7 @@ def parseOptionsAndInitTestdirs():
# and we're not a test inferior.
if not args.inferior and configuration.results_formatter_name is None:
configuration.results_formatter_name = (
- "lldbsuite.test.result_formatter.ResultsFormatter")
+ "lldbsuite.test_event.formatter.results_formatter.ResultsFormatter")
# rerun-related arguments
configuration.rerun_all_issues = args.rerun_all_issues
@@ -412,7 +411,7 @@ def parseOptionsAndInitTestdirs():
# Tell the event builder to create all events with these
# key/val pairs in them.
if len(entries) > 0:
- result_formatter.EventBuilder.add_entries_to_all_events(entries)
+ EventBuilder.add_entries_to_all_events(entries)
# Gather all the dirs passed on the command line.
if len(args.args) > 0:
@@ -453,7 +452,7 @@ def createSocketToLocalPort(port):
def setupTestResults():
"""Sets up test results-related objects based on arg settings."""
# Setup the results formatter configuration.
- formatter_config = result_formatter.FormatterConfig()
+ formatter_config = formatter.FormatterConfig()
formatter_config.filename = configuration.results_filename
formatter_config.formatter_name = configuration.results_formatter_name
formatter_config.formatter_options = (
@@ -461,12 +460,12 @@ def setupTestResults():
formatter_config.port = configuration.results_port
# Create the results formatter.
- formatter_spec = result_formatter.create_results_formatter(
+ formatter_spec = formatter.create_results_formatter(
formatter_config)
if formatter_spec is not None and formatter_spec.formatter is not None:
configuration.results_formatter_object = formatter_spec.formatter
- # Send an intialize message to the formatter.
+ # Send an initialize message to the formatter.
initialize_event = EventBuilder.bare_event("initialize")
if isMultiprocessTestRunner():
if (configuration.test_runner_name is not None and
@@ -640,16 +639,15 @@ def setupSysPath():
if not lldbPythonDir:
if platform.system() == "Darwin":
python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
- outputPaths = getXcodeOutputPaths()
+ outputPaths = getXcodeOutputPaths(lldbRootDirectory)
for outputPath in outputPaths:
- candidatePath = os.path.join(outputPath, python_resource_dir)
+ candidatePath = os.path.join(outputPath, *python_resource_dir)
if os.path.isfile(os.path.join(candidatePath, init_in_python_dir)):
lldbPythonDir = candidatePath
break
if not lldbPythonDir:
- print('This script requires lldb.py to be in either ' + dbgPath + ',', end=' ')
- print(relPath + ', or ' + baiPath + '. Some tests might fail.')
+ print("lldb.py is not found, some tests may fail.")
else:
print("Unable to load lldb extension module. Possible reasons for this include:")
print(" 1) LLDB was built with LLDB_DISABLE_PYTHON=1")
@@ -659,7 +657,7 @@ def setupSysPath():
print(" location of LLDB\'s site-packages folder.")
print(" 3) A different version of Python than that which was built against is exported in")
print(" the system\'s PATH environment variable, causing conflicts.")
- print(" 4) The executable '%s' could not be found. Please check " % lldbExecutable)
+ print(" 4) The executable '%s' could not be found. Please check " % lldbtest_config.lldbExec)
print(" that it exists and is executable.")
if lldbPythonDir:
@@ -678,73 +676,98 @@ def setupSysPath():
# This is to locate the lldb.py module. Insert it right after sys.path[0].
sys.path[1:1] = [lldbPythonDir]
+
+def visit_file(dir, name):
+ # Try to match the regexp pattern, if specified.
+ if configuration.regexp:
+ import re
+ if not re.search(configuration.regexp, name):
+ # We didn't match the regex, we're done.
+ return
+
+ # We found a match for our test. Add it to the suite.
+
+ # Update the sys.path first.
+ if not sys.path.count(dir):
+ sys.path.insert(0, dir)
+ base = os.path.splitext(name)[0]
+
+ # Thoroughly check the filterspec against the base module and admit
+ # the (base, filterspec) combination only when it makes sense.
+ filterspec = None
+ for filterspec in configuration.filters:
+ # Optimistically set the flag to True.
+ filtered = True
+ module = __import__(base)
+ parts = filterspec.split('.')
+ obj = module
+ for part in parts:
+ try:
+ parent, obj = obj, getattr(obj, part)
+ except AttributeError:
+ # The filterspec has failed.
+ filtered = False
+ break
+
+ # If filtered, we have a good filterspec. Add it.
+ if filtered:
+ # print("adding filter spec %s to module %s" % (filterspec, module))
+ configuration.suite.addTests(
+ unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
+ continue
+
+ # Forgo this module if the (base, filterspec) combo is invalid
+ if configuration.filters and not filtered:
+ return
+
+ if not filterspec or not filtered:
+ # Add the entire file's worth of tests since we're not filtered.
+ # Also the fail-over case when the filterspec branch
+ # (base, filterspec) combo doesn't make sense.
+ configuration.suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
+
+
def visit(prefix, dir, names):
"""Visitor function for os.path.walk(path, visit, arg)."""
dir_components = set(dir.split(os.sep))
excluded_components = set(['.svn', '.git'])
if dir_components.intersection(excluded_components):
- #print("Detected an excluded dir component: %s" % dir)
return
- for name in names:
- if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
+ # Gather all the Python test file names that follow the Test*.py pattern.
+ python_test_files = [
+ name
+ for name in names
+ if name.endswith('.py') and name.startswith(prefix)]
+ # Visit all the python test files.
+ for name in python_test_files:
+ try:
+ # Ensure we error out if we have multiple tests with the same
+ # base name.
+ # Future improvement: find all the places where we work with base
+ # names and convert to full paths. We have directory structure
+ # to disambiguate these, so we shouldn't need this constraint.
if name in configuration.all_tests:
raise Exception("Found multiple tests with the name %s" % name)
configuration.all_tests.add(name)
- # Try to match the regexp pattern, if specified.
- if configuration.regexp:
- import re
- if re.search(configuration.regexp, name):
- #print("Filename: '%s' matches pattern: '%s'" % (name, regexp))
- pass
- else:
- #print("Filename: '%s' does not match pattern: '%s'" % (name, regexp))
- continue
-
- # We found a match for our test. Add it to the suite.
-
- # Update the sys.path first.
- if not sys.path.count(dir):
- sys.path.insert(0, dir)
- base = os.path.splitext(name)[0]
-
- # Thoroughly check the filterspec against the base module and admit
- # the (base, filterspec) combination only when it makes sense.
- filterspec = None
- for filterspec in configuration.filters:
- # Optimistically set the flag to True.
- filtered = True
- module = __import__(base)
- parts = filterspec.split('.')
- obj = module
- for part in parts:
- try:
- parent, obj = obj, getattr(obj, part)
- except AttributeError:
- # The filterspec has failed.
- filtered = False
- break
+ # Run the relevant tests in the python file.
+ visit_file(dir, name)
+ except Exception as ex:
+ # Convert this exception to a test event error for the file.
+ test_filename = os.path.abspath(os.path.join(dir, name))
+ if configuration.results_formatter_object is not None:
+ # Grab the backtrace for the exception.
+ import traceback
+ backtrace = traceback.format_exc()
- # If filtered, we have a good filterspec. Add it.
- if filtered:
- #print("adding filter spec %s to module %s" % (filterspec, module))
- configuration.suite.addTests(
- unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
- continue
-
- # Forgo this module if the (base, filterspec) combo is invalid
- if configuration.filters and not filtered:
- continue
-
- # Add either the filtered test case(s) (which is done before) or the entire test class.
- if not filterspec or not filtered:
- # A simple case of just the module name. Also the failover case
- # from the filterspec branch when the (base, filterspec) combo
- # doesn't make sense.
- configuration.suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
+ # Generate the test event.
+ configuration.results_formatter_object.handle_event(
+ EventBuilder.event_for_job_test_add_error(
+ test_filename, ex, backtrace))
+ raise
def disabledynamics():
@@ -987,12 +1010,6 @@ def run_suite():
except OSError as exception:
if exception.errno != errno.EEXIST:
raise
- where_to_save_session = os.getcwd()
- fname = os.path.join(configuration.sdir_name, "TestStarted-%d" % os.getpid())
- with open(fname, "w") as f:
- print("Test started at: %s\n" % timestamp_started, file=f)
- print(configuration.svn_info, file=f)
- print("Command invoked: %s\n" % getMyCommandLine(), file=f)
#
# Invoke the default TextTestRunner to run the test suite, possibly iterating
@@ -1092,7 +1109,7 @@ def run_suite():
# mark __ignore_singleton__ flag as True so the signleton pattern is
# not enforced.
test_result.LLDBTestResult.__ignore_singleton__ = True
- for i in range(count):
+ for i in range(configuration.count):
result = unittest2.TextTestRunner(stream=sys.stderr,
verbosity=v,
@@ -1109,11 +1126,6 @@ def run_suite():
for category in configuration.failuresPerCategory:
sys.stderr.write("%s - %d\n" % (category, configuration.failuresPerCategory[category]))
- os.chdir(where_to_save_session)
- fname = os.path.join(configuration.sdir_name, "TestFinished-%d" % os.getpid())
- with open(fname, "w") as f:
- print("Test finished at: %s\n" % datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S"), file=f)
-
# Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
# This should not be necessary now.
if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
diff --git a/packages/Python/lldbsuite/test/dotest_args.py b/packages/Python/lldbsuite/test/dotest_args.py
index 105156df7e84..8bbc29c98f00 100644
--- a/packages/Python/lldbsuite/test/dotest_args.py
+++ b/packages/Python/lldbsuite/test/dotest_args.py
@@ -11,6 +11,7 @@ import textwrap
# Third-party modules
# LLDB modules
+from . import configuration
class ArgParseNamespace(object):
pass
@@ -70,6 +71,7 @@ def create_parser():
group.add_argument('--framework', metavar='framework-path', help='The path to LLDB.framework')
group.add_argument('--executable', metavar='executable-path', help='The path to the lldb executable')
group.add_argument('-s', metavar='name', help='Specify the name of the dir created to store the session files of tests with errored or failed status. If not specified, the test driver uses the timestamp as the session dir name')
+ group.add_argument('-S', '--session-file-format', default=configuration.session_file_format, metavar='format', help='Specify session file name format. See configuration.py for a description.')
group.add_argument('-y', type=int, metavar='count', help="Specify the iteration count used to collect our benchmarks. An example is the number of times to do 'thread step-over' to measure stepping speed.")
group.add_argument('-#', type=int, metavar='sharp', dest='sharp', help='Repeat the test suite for a specified number of times')
group.add_argument('--channel', metavar='channel', dest='channels', action='append', help=textwrap.dedent("Specify the log channels (and optional categories) e.g. 'lldb all' or 'gdb-remote packets' if no categories are specified, 'default' is used"))
diff --git a/packages/Python/lldbsuite/test/driver/batch_mode/TestBatchMode.py b/packages/Python/lldbsuite/test/driver/batch_mode/TestBatchMode.py
index 0a9edd2755c9..6713a5a764e4 100644
--- a/packages/Python/lldbsuite/test/driver/batch_mode/TestBatchMode.py
+++ b/packages/Python/lldbsuite/test/driver/batch_mode/TestBatchMode.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class DriverBatchModeTest (TestBase):
@@ -34,7 +36,7 @@ class DriverBatchModeTest (TestBase):
@skipIfRemote # test not remote-ready llvm.org/pr24813
@expectedFlakeyFreeBSD("llvm.org/pr25172 fails rarely on the buildbot")
@expectedFlakeyLinux("llvm.org/pr25172")
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_batch_mode_run_crash (self):
"""Test that the lldb driver's batch mode works correctly."""
self.build()
@@ -71,7 +73,7 @@ class DriverBatchModeTest (TestBase):
@skipIfRemote # test not remote-ready llvm.org/pr24813
@expectedFlakeyFreeBSD("llvm.org/pr25172 fails rarely on the buildbot")
@expectedFlakeyLinux("llvm.org/pr25172")
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_batch_mode_run_exit (self):
"""Test that the lldb driver's batch mode works correctly."""
self.build()
@@ -108,7 +110,7 @@ class DriverBatchModeTest (TestBase):
@skipIfRemote # test not remote-ready llvm.org/pr24813
@expectedFlakeyFreeBSD("llvm.org/pr25172 fails rarely on the buildbot")
@expectedFlakeyLinux("llvm.org/pr25172")
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_batch_mode_attach_exit (self):
"""Test that the lldb driver's batch mode works correctly."""
self.build()
diff --git a/packages/Python/lldbsuite/test/expression_command/anonymous-struct/Makefile b/packages/Python/lldbsuite/test/expression_command/anonymous-struct/Makefile
new file mode 100644
index 000000000000..7df664ac43e3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/anonymous-struct/Makefile
@@ -0,0 +1,12 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/expression_command/anonymous-struct/TestCallUserAnonTypedef.py b/packages/Python/lldbsuite/test/expression_command/anonymous-struct/TestCallUserAnonTypedef.py
new file mode 100644
index 000000000000..e1a53305a0d0
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/anonymous-struct/TestCallUserAnonTypedef.py
@@ -0,0 +1,42 @@
+"""
+Test calling user defined functions using expression evaluation.
+This test checks that typesystem lookup works correctly for typedefs of
+untagged structures.
+
+Ticket: https://llvm.org/bugs/show_bug.cgi?id=26790
+"""
+
+from __future__ import print_function
+
+import lldb
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestExprLookupAnonStructTypedef(TestBase):
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ TestBase.setUp(self)
+ # Find the breakpoint
+ self.line = line_number('main.cpp', '// lldb testsuite break')
+
+ @expectedFailureAll(oslist=["windows"])
+ @expectedFailureAll(oslist=['linux'], archs=['arm'], bugnumber="llvm.org/pr27868")
+ def test(self):
+ """Test typedeffed untagged struct arguments for function call expressions"""
+ self.build()
+
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+ lldbutil.run_break_set_by_file_and_line(
+ self,
+ "main.cpp",
+ self.line,
+ num_expected_locations=-1,
+ loc_exact=True
+ )
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.expect("expr multiply(&s)", substrs=['$0 = 1'])
diff --git a/packages/Python/lldbsuite/test/expression_command/anonymous-struct/main.cpp b/packages/Python/lldbsuite/test/expression_command/anonymous-struct/main.cpp
new file mode 100644
index 000000000000..5b170c5f943a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/anonymous-struct/main.cpp
@@ -0,0 +1,26 @@
+#include <tgmath.h>
+
+typedef struct {
+ float f;
+ int i;
+} my_untagged_struct;
+
+double multiply(my_untagged_struct *s)
+{
+ return s->f * s->i;
+}
+
+double multiply(my_untagged_struct *s, int x)
+{
+ return multiply(s) * x;
+}
+
+int main(int argc, char **argv)
+{
+ my_untagged_struct s = {
+ .f = (float)argc,
+ .i = argc,
+ };
+ // lldb testsuite break
+ return !(multiply(&s, argc) == pow(argc, 3));
+}
diff --git a/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py
index 3756b4a8cea4..61702ee88033 100644
--- a/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py
+++ b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ExprCommandCallFunctionTestCase(TestBase):
@@ -21,9 +22,9 @@ class ExprCommandCallFunctionTestCase(TestBase):
self.line = line_number('main.cpp',
'// Please test these expressions while stopped at this line:')
- @expectedFailureIcc # llvm.org/pr14437, fails with ICC 13.1
- @expectedFailureFreeBSD('llvm.org/pr17807') # Fails on FreeBSD buildbot
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(compiler="icc", bugnumber="llvm.org/pr14437, fails with ICC 13.1")
+ @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr17807 Fails on FreeBSD buildbot')
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_with(self):
"""Test calling std::String member function."""
self.build()
diff --git a/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStopAndContinue.py b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStopAndContinue.py
index f6d63885248a..4d18cfc980f2 100644
--- a/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStopAndContinue.py
+++ b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStopAndContinue.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ExprCommandCallStopContinueTestCase(TestBase):
@@ -24,7 +25,7 @@ class ExprCommandCallStopContinueTestCase(TestBase):
'{ 5, "five" }')
@expectedFlakeyDarwin("llvm.org/pr20274")
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows")
def test(self):
"""Test gathering result from interrupted function call."""
self.build()
diff --git a/packages/Python/lldbsuite/test/expression_command/call-function/TestCallUserDefinedFunction.py b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallUserDefinedFunction.py
index 9138af0b0b47..c0727a84fc02 100644
--- a/packages/Python/lldbsuite/test/expression_command/call-function/TestCallUserDefinedFunction.py
+++ b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallUserDefinedFunction.py
@@ -12,8 +12,9 @@ from __future__ import print_function
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ExprCommandCallUserDefinedFunction(TestBase):
@@ -26,7 +27,7 @@ class ExprCommandCallUserDefinedFunction(TestBase):
self.line = line_number('main.cpp',
'// Please test these expressions while stopped at this line:')
@expectedFlakeyDsym("llvm.org/pr20274")
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows")
def test(self):
"""Test return values of user defined function calls."""
self.build()
diff --git a/packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py b/packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py
index abf48742567d..6b754a76878b 100644
--- a/packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py
+++ b/packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ExprCommandThatRestartsTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py b/packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py
index 0e766ac2953a..a6eb1bddc005 100644
--- a/packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py
+++ b/packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ExprCommandWithThrowTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py b/packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py
index 5e1f307f622d..66fa69cdfff2 100644
--- a/packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py
+++ b/packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py
@@ -3,8 +3,9 @@ from __future__ import print_function
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ExprCharTestCase(TestBase):
@@ -52,19 +53,17 @@ class ExprCharTestCase(TestBase):
self.assertTrue(value.GetError().Success())
self.assertEqual(value.GetValueAsSigned(0), 3)
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_default_char(self):
self.do_test()
- @expectedFailureArch("arm", "llvm.org/pr23069")
- @expectedFailureArch("aarch64", "llvm.org/pr23069")
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(archs=["arm", "aarch64", "s390x"], bugnumber="llvm.org/pr23069")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_signed_char(self):
self.do_test(dictionary={'CFLAGS_EXTRAS': '-fsigned-char'})
- @expectedFailurei386("llvm.org/pr23069")
- @expectedFailurex86_64("llvm.org/pr23069")
- @expectedFailureWindows("llvm.org/pr21765")
- @expectedFailureAll(bugnumber="llvm.org/pr23069", triple = 'mips*')
+ @expectedFailureAll(archs=["i[3-6]86", "x86_64"], bugnumber="llvm.org/pr23069")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
+ @expectedFailureAll(triple = 'mips*', bugnumber="llvm.org/pr23069")
def test_unsigned_char(self):
self.do_test(dictionary={'CFLAGS_EXTRAS': '-funsigned-char'})
diff --git a/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/TestExpressionInSyscall.py b/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/TestExpressionInSyscall.py
index 0430fa55f995..a715ee31e5fa 100644
--- a/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/TestExpressionInSyscall.py
+++ b/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/TestExpressionInSyscall.py
@@ -6,15 +6,16 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ExprSyscallTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr21765") # Also getpid() is not a function on Windows anyway
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765, getpid() does not exist on Windows")
def test_setpgid(self):
self.build()
self.expr_syscall()
diff --git a/packages/Python/lldbsuite/test/expression_command/fixits/Makefile b/packages/Python/lldbsuite/test/expression_command/fixits/Makefile
new file mode 100644
index 000000000000..7df664ac43e3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/fixits/Makefile
@@ -0,0 +1,12 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py b/packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py
new file mode 100644
index 000000000000..7e11f2b201f2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py
@@ -0,0 +1,81 @@
+"""
+Test calling an expression with errors that a FixIt can fix.
+"""
+
+from __future__ import print_function
+
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class ExprCommandWithFixits(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ self.main_source = "main.cpp"
+ self.main_source_spec = lldb.SBFileSpec (self.main_source)
+
+ @skipUnlessDarwin
+ def test(self):
+ """Test calling a function that throws and ObjC exception."""
+ self.build()
+ self.try_expressions()
+
+ def try_expressions(self):
+ """Test calling expressions with errors that can be fixed by the FixIts."""
+ exe_name = "a.out"
+ exe = os.path.join(os.getcwd(), exe_name)
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ breakpoint = target.BreakpointCreateBySourceRegex('Stop here to evaluate expressions',self.main_source_spec)
+ self.assertTrue(breakpoint.GetNumLocations() > 0, VALID_BREAKPOINT)
+
+ # Launch the process, and do not stop at the entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Frame #0 should be at our breakpoint.
+ threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
+
+ self.assertTrue(len(threads) == 1)
+ self.thread = threads[0]
+
+ options = lldb.SBExpressionOptions()
+ options.SetAutoApplyFixIts(True)
+
+ frame = self.thread.GetFrameAtIndex(0)
+
+ # Try with one error:
+ value = frame.EvaluateExpression("my_pointer.first", options)
+ self.assertTrue(value.IsValid())
+ self.assertTrue(value.GetError().Success())
+ self.assertTrue(value.GetValueAsUnsigned() == 10)
+
+ # Try with two errors:
+ two_error_expression = "my_pointer.second->a"
+ value = frame.EvaluateExpression(two_error_expression, options)
+ self.assertTrue(value.IsValid())
+ self.assertTrue(value.GetError().Success())
+ self.assertTrue(value.GetValueAsUnsigned() == 20)
+
+ # Now turn off the fixits, and the expression should fail:
+ options.SetAutoApplyFixIts(False)
+ value = frame.EvaluateExpression(two_error_expression, options)
+ self.assertTrue(value.IsValid())
+ self.assertTrue(value.GetError().Fail())
+ error_string = value.GetError().GetCString()
+ self.assertTrue(error_string.find("fixed expression suggested:") != -1, "Fix was suggested")
+ self.assertTrue(error_string.find("my_pointer->second.a") != -1, "Fix was right")
+
+
+
diff --git a/packages/Python/lldbsuite/test/expression_command/fixits/main.cpp b/packages/Python/lldbsuite/test/expression_command/fixits/main.cpp
new file mode 100644
index 000000000000..371d8333763b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/fixits/main.cpp
@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+struct SubStruct
+{
+ int a;
+ int b;
+};
+
+struct MyStruct
+{
+ int first;
+ struct SubStruct second;
+};
+
+int
+main()
+{
+ struct MyStruct my_struct = {10, {20, 30}};
+ struct MyStruct *my_pointer = &my_struct;
+ printf ("Stop here to evaluate expressions: %d %d %p\n", my_pointer->first, my_pointer->second.a, my_pointer);
+ return 0;
+}
+
+
+
diff --git a/packages/Python/lldbsuite/test/expression_command/formatters/TestFormatters.py b/packages/Python/lldbsuite/test/expression_command/formatters/TestFormatters.py
index 3f47206480c3..4a99dc479019 100644
--- a/packages/Python/lldbsuite/test/expression_command/formatters/TestFormatters.py
+++ b/packages/Python/lldbsuite/test/expression_command/formatters/TestFormatters.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ExprFormattersTestCase(TestBase):
@@ -22,9 +23,8 @@ class ExprFormattersTestCase(TestBase):
'// Stop here')
@skipIfFreeBSD # llvm.org/pr24691 skipping to avoid crashing the test runner
- @expectedFailureFreeBSD('llvm.org/pr19011') # Newer Clang omits C1 complete object constructor
- @expectedFailureFreeBSD('llvm.org/pr24691') # we hit an assertion in clang
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr19011 Newer Clang omits C1 complete object constructor')
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
@skipIfTargetAndroid() # skipping to avoid crashing the test runner
@expectedFailureAndroid('llvm.org/pr24691') # we hit an assertion in clang
def test(self):
diff --git a/packages/Python/lldbsuite/test/expression_command/ir-interpreter-phi-nodes/Makefile b/packages/Python/lldbsuite/test/expression_command/ir-interpreter-phi-nodes/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/ir-interpreter-phi-nodes/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/expression_command/ir-interpreter-phi-nodes/TestIRInterpreterPHINodes.py b/packages/Python/lldbsuite/test/expression_command/ir-interpreter-phi-nodes/TestIRInterpreterPHINodes.py
new file mode 100644
index 000000000000..c4f176703225
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/ir-interpreter-phi-nodes/TestIRInterpreterPHINodes.py
@@ -0,0 +1,40 @@
+"""
+Test PHI nodes work in the IR interpreter.
+"""
+
+import os, os.path
+
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class IRInterpreterPHINodesTestCase(TestBase):
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_phi_node_support(self):
+ """Test support for PHI nodes in the IR interpreter."""
+
+ self.build()
+ exe = os.path.join(os.getcwd(), 'a.out')
+ self.runCmd('file ' + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break on the first assignment to i
+ line = line_number('main.cpp', 'i = 5')
+ lldbutil.run_break_set_by_file_and_line(self, 'main.cpp', line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd('run', RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint
+ self.expect('thread list', STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ self.runCmd('s')
+
+ # The logical 'or' causes a PHI node to be generated. Execute without JIT
+ # to test that the interpreter can handle this
+ self.expect('expr -j 0 -- i == 3 || i == 5', substrs=['true'])
+
+ self.runCmd('s')
+ self.expect('expr -j 0 -- i == 3 || i == 5', substrs=['false'])
+ self.runCmd('s')
+ self.expect('expr -j 0 -- i == 3 || i == 5', substrs=['true'])
diff --git a/packages/Python/lldbsuite/test/expression_command/ir-interpreter-phi-nodes/main.cpp b/packages/Python/lldbsuite/test/expression_command/ir-interpreter-phi-nodes/main.cpp
new file mode 100644
index 000000000000..b144f9cc1b47
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/ir-interpreter-phi-nodes/main.cpp
@@ -0,0 +1,17 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+ int i;
+ i = 5;
+ i = 2;
+ i = 3;
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/expression_command/ir-interpreter/Makefile b/packages/Python/lldbsuite/test/expression_command/ir-interpreter/Makefile
new file mode 100644
index 000000000000..c4169a9b1012
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/ir-interpreter/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../make
+
+default: a.out
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/expression_command/ir-interpreter/TestIRInterpreter.py b/packages/Python/lldbsuite/test/expression_command/ir-interpreter/TestIRInterpreter.py
new file mode 100644
index 000000000000..2a21d0473715
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/ir-interpreter/TestIRInterpreter.py
@@ -0,0 +1,72 @@
+"""
+Test the IR interpreter
+"""
+
+from __future__ import print_function
+
+import unittest2
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class IRInterpreterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break for main.c.
+ self.line = line_number('main.c',
+ '// Set breakpoint here')
+
+ # Disable confirmation prompt to avoid infinite wait
+ self.runCmd("settings set auto-confirm true")
+ self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
+ def build_and_run(self):
+ """Test the IR interpreter"""
+ self.build()
+
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=False)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ @add_test_categories(['pyapi'])
+ @expectedFailureAll(oslist=['windows'], bugnumber="http://llvm.org/pr21765") # getpid() is POSIX, among other problems, see bug
+ @expectedFailureAll(oslist=['linux'], archs=['arm'], bugnumber="llvm.org/pr27868")
+ def test_ir_interpreter(self):
+ self.build_and_run()
+
+ options = lldb.SBExpressionOptions()
+ options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+
+ set_up_expressions = ["int $i = 9", "int $j = 3", "int $k = 5"]
+
+ expressions = ["$i + $j",
+ "$i - $j",
+ "$i * $j",
+ "$i / $j",
+ "$i % $k",
+ "$i << $j",
+ "$i & $j",
+ "$i | $j",
+ "$i ^ $j"]
+
+ for expression in set_up_expressions:
+ self.frame().EvaluateExpression(expression, options)
+
+ for expression in expressions:
+ interp_expression = expression
+ jit_expression = "(int)getpid(); " + expression
+
+ interp_result = self.frame().EvaluateExpression(interp_expression, options).GetValueAsSigned()
+ jit_result = self.frame().EvaluateExpression(jit_expression, options).GetValueAsSigned()
+
+ self.assertEqual(interp_result, jit_result, "While evaluating " + expression)
+
diff --git a/packages/Python/lldbsuite/test/expression_command/ir-interpreter/main.c b/packages/Python/lldbsuite/test/expression_command/ir-interpreter/main.c
new file mode 100644
index 000000000000..31204b21d972
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/ir-interpreter/main.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("This is a dummy\n"); // Set breakpoint here
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py b/packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py
index fdc981ea178d..2d0b23b4e5ba 100644
--- a/packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py
+++ b/packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py
@@ -10,14 +10,15 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class Issue11581TestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_11581_commands(self):
# This is the function to remove the custom commands in order to have a
# clean slate for the next test case.
diff --git a/packages/Python/lldbsuite/test/expression_command/macros/TestMacros.py b/packages/Python/lldbsuite/test/expression_command/macros/TestMacros.py
index c3d6306c5a63..939d2e45d7d5 100644
--- a/packages/Python/lldbsuite/test/expression_command/macros/TestMacros.py
+++ b/packages/Python/lldbsuite/test/expression_command/macros/TestMacros.py
@@ -1,13 +1,17 @@
+from __future__ import print_function
+
+
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestMacros(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureClang("clang does not emit .debug_macro[.dwo] sections.")
- @expectedFailureDwo("GCC produces multiple .debug_macro.dwo sections and the spec is unclear as to what it means")
+ @expectedFailureAll(compiler="clang", bugnumber="clang does not emit .debug_macro[.dwo] sections.")
+ @expectedFailureAll(debug_info="dwo", bugnumber="GCC produces multiple .debug_macro.dwo sections and the spec is unclear as to what it means")
@expectedFailureAll(hostoslist=["windows"], compiler="gcc", triple='.*-android')
def test_expr_with_macros(self):
self.build()
diff --git a/packages/Python/lldbsuite/test/expression_command/multiline/Makefile b/packages/Python/lldbsuite/test/expression_command/multiline/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/multiline/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py b/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py
new file mode 100644
index 000000000000..0691a866743b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py
@@ -0,0 +1,57 @@
+"""Test multiline expressions."""
+
+from __future__ import print_function
+
+import os
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class MultilineExpressionsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break on inside main.cpp.
+ self.line = line_number('main.c', 'break')
+
+ @skipIfRemote
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
+ def test_with_run_commands(self):
+ """Test that multiline expressions work correctly"""
+ self.build()
+ import pexpect
+ exe = os.path.join(os.getcwd(), "a.out")
+ prompt = "(lldb) "
+
+ # So that the child gets torn down after the test.
+ self.child = pexpect.spawn('%s %s %s' % (lldbtest_config.lldbExec, self.lldbOption, exe))
+ child = self.child
+ # Turn on logging for what the child sends back.
+ if self.TraceOn():
+ child.logfile_read = sys.stdout
+
+ # Set the breakpoint, run the inferior, when it breaks, issue print on
+ # the various convenience variables.
+ child.expect_exact(prompt)
+ child.sendline('breakpoint set -f main.c -l %d' % self.line)
+ child.expect_exact(prompt)
+ child.sendline('run')
+ child.expect_exact("stop reason = breakpoint 1.1")
+ child.expect_exact(prompt)
+ child.sendline('expr')
+ child.expect_exact('1:')
+
+ child.sendline('2+')
+ child.expect_exact('2:')
+
+ child.sendline('3')
+ child.expect_exact('3:')
+
+ child.sendline('')
+ child.expect_exact(prompt)
+ self.expect(child.before, exe=False,
+ patterns = ['= 5'])
diff --git a/packages/Python/lldbsuite/test/expression_command/multiline/main.c b/packages/Python/lldbsuite/test/expression_command/multiline/main.c
new file mode 100644
index 000000000000..da16b1e7846f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/multiline/main.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(int argc, char const *argv[]) {
+ printf("Hello world.\n"); // break here
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py b/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py
index 7b0707cdf22c..d3ce10d8f2ab 100644
--- a/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py
+++ b/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class PersistObjCPointeeType(TestBase):
diff --git a/packages/Python/lldbsuite/test/expression_command/persistent_types/TestNestedPersistentTypes.py b/packages/Python/lldbsuite/test/expression_command/persistent_types/TestNestedPersistentTypes.py
index 3ea5b7040655..9099ae1806e3 100644
--- a/packages/Python/lldbsuite/test/expression_command/persistent_types/TestNestedPersistentTypes.py
+++ b/packages/Python/lldbsuite/test/expression_command/persistent_types/TestNestedPersistentTypes.py
@@ -8,13 +8,15 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class NestedPersistentTypesTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_persistent_types(self):
"""Test that nested persistent types work."""
self.build()
diff --git a/packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py b/packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py
index 47c6675511fd..59e0f0b84f69 100644
--- a/packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py
+++ b/packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py
@@ -8,13 +8,15 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class PersistenttypesTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_persistent_types(self):
"""Test that lldb persistent types works correctly."""
self.build()
diff --git a/packages/Python/lldbsuite/test/expression_command/po_verbosity/TestPoVerbosity.py b/packages/Python/lldbsuite/test/expression_command/po_verbosity/TestPoVerbosity.py
index e415b92a43a6..da87bcee9cfc 100644
--- a/packages/Python/lldbsuite/test/expression_command/po_verbosity/TestPoVerbosity.py
+++ b/packages/Python/lldbsuite/test/expression_command/po_verbosity/TestPoVerbosity.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class PoVerbosityTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/expression_command/radar_9531204/TestPrintfAfterUp.py b/packages/Python/lldbsuite/test/expression_command/radar_9531204/TestPrintfAfterUp.py
index fb16d2a93326..e0b219dbe2b9 100644
--- a/packages/Python/lldbsuite/test/expression_command/radar_9531204/TestPrintfAfterUp.py
+++ b/packages/Python/lldbsuite/test/expression_command/radar_9531204/TestPrintfAfterUp.py
@@ -8,15 +8,16 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class Radar9531204TestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
# rdar://problem/9531204
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_expr_commands(self):
"""The evaluating printf(...) after break stop and then up a stack frame."""
self.build()
diff --git a/packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py b/packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py
index ce3e51d05149..a1505b08c508 100644
--- a/packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py
+++ b/packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class Radar9673644TestCase(TestBase):
@@ -22,7 +23,7 @@ class Radar9673644TestCase(TestBase):
self.main_source = "main.c"
self.line = line_number(self.main_source, '// Set breakpoint here.')
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_expr_commands(self):
"""The following expression commands should just work."""
self.build()
diff --git a/packages/Python/lldbsuite/test/expression_command/test/TestExprs.py b/packages/Python/lldbsuite/test/expression_command/test/TestExprs.py
index ec3e7f93af26..8c9a9a5a27e7 100644
--- a/packages/Python/lldbsuite/test/expression_command/test/TestExprs.py
+++ b/packages/Python/lldbsuite/test/expression_command/test/TestExprs.py
@@ -19,8 +19,9 @@ import unittest2
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class BasicExprCommandsTestCase(TestBase):
@@ -56,7 +57,6 @@ class BasicExprCommandsTestCase(TestBase):
patterns = ["\(float\) \$.* = 2\.234"])
# (float) $2 = 2.234
- @expectedFailureWindows("llvm.org/pr21765")
def test_many_expr_commands(self):
self.build_and_run()
@@ -98,7 +98,7 @@ class BasicExprCommandsTestCase(TestBase):
# (const char *) $8 = 0x... "/Volumes/data/lldb/svn/trunk/test/expression_command/test/a.out"
@add_test_categories(['pyapi'])
- @expectedFailureWindows # Test crashes
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_evaluate_expression_python(self):
"""Test SBFrame.EvaluateExpression() API for evaluating an expression."""
self.build()
@@ -130,12 +130,8 @@ class BasicExprCommandsTestCase(TestBase):
"instead the actual state is: '%s'" %
lldbutil.state_type_to_str(process.GetState()))
- # The stop reason of the thread should be breakpoint.
- thread = process.GetThreadAtIndex(0)
- if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
- from lldbsuite.test.lldbutil import stop_reason_to_str
- self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
- stop_reason_to_str(thread.GetStopReason()))
+ thread = lldbutil.get_one_thread_stopped_at_breakpoint(process, breakpoint)
+ self.assertIsNotNone(thread, "Expected one thread to be stopped at the breakpoint")
# The filename of frame #0 should be 'main.cpp' and function is main.
self.expect(lldbutil.get_filenames(thread)[0],
@@ -198,7 +194,7 @@ class BasicExprCommandsTestCase(TestBase):
# rdar://problem/8686536
# CommandInterpreter::HandleCommand is stripping \'s from input for WantsRawCommand commands
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_expr_commands_can_handle_quotes(self):
"""Throw some expression commands with quotes at lldb."""
self.build()
diff --git a/packages/Python/lldbsuite/test/expression_command/test/TestExprs2.py b/packages/Python/lldbsuite/test/expression_command/test/TestExprs2.py
index 578a037e9f0f..523ee51a9f18 100644
--- a/packages/Python/lldbsuite/test/expression_command/test/TestExprs2.py
+++ b/packages/Python/lldbsuite/test/expression_command/test/TestExprs2.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ExprCommands2TestCase(TestBase):
@@ -22,7 +23,7 @@ class ExprCommands2TestCase(TestBase):
self.line = line_number('main.cpp',
'// Please test many expressions while stopped at this line:')
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows")
def test_more_expr_commands(self):
"""Test some more expression commands."""
self.build()
diff --git a/packages/Python/lldbsuite/test/expression_command/timeout/TestCallWithTimeout.py b/packages/Python/lldbsuite/test/expression_command/timeout/TestCallWithTimeout.py
index a602afc47edb..7cb4a647efb4 100644
--- a/packages/Python/lldbsuite/test/expression_command/timeout/TestCallWithTimeout.py
+++ b/packages/Python/lldbsuite/test/expression_command/timeout/TestCallWithTimeout.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ExprCommandWithTimeoutsTestCase(TestBase):
@@ -23,8 +24,7 @@ class ExprCommandWithTimeoutsTestCase(TestBase):
@expectedFlakeyFreeBSD("llvm.org/pr19605")
- @expectedFlakeyLinux("llvm.org/pr20275")
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=["windows", "macosx"], bugnumber="llvm.org/pr21765")
def test(self):
"""Test calling std::String member function."""
self.build()
@@ -57,7 +57,7 @@ class ExprCommandWithTimeoutsTestCase(TestBase):
frame = thread.GetFrameAtIndex(0)
- value = frame.EvaluateExpression ("wait_a_while (200000)", options)
+ value = frame.EvaluateExpression("wait_a_while(300000)", options)
self.assertTrue (value.IsValid())
self.assertFalse (value.GetError().Success())
@@ -65,7 +65,7 @@ class ExprCommandWithTimeoutsTestCase(TestBase):
interp = self.dbg.GetCommandInterpreter()
result = lldb.SBCommandReturnObject()
- return_value = interp.HandleCommand ("expr -t 100 -u true -- wait_a_while(200000)", result)
+ return_value = interp.HandleCommand("expr -t 100 -u true -- wait_a_while(300000)", result)
self.assertTrue (return_value == lldb.eReturnStatusFailed)
# Okay, now do it again with long enough time outs:
diff --git a/packages/Python/lldbsuite/test/expression_command/top-level/Makefile b/packages/Python/lldbsuite/test/expression_command/top-level/Makefile
new file mode 100644
index 000000000000..7146f227b98a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/top-level/Makefile
@@ -0,0 +1,12 @@
+LEVEL = ../../make
+
+default: a.out dummy
+
+CXX_SOURCES := main.cpp test.cpp
+
+dummy: dummy.cpp
+
+clean::
+ rm -rf dummy dummy.dSYM
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/expression_command/top-level/TestTopLevelExprs.py b/packages/Python/lldbsuite/test/expression_command/top-level/TestTopLevelExprs.py
new file mode 100644
index 000000000000..9a17624cb8e6
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/top-level/TestTopLevelExprs.py
@@ -0,0 +1,89 @@
+"""
+Test top-level expressions.
+"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TopLevelExpressionsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break for main.c.
+ self.line = line_number('main.cpp',
+ '// Set breakpoint here')
+ self.dummy_line = line_number('dummy.cpp',
+ '// Set breakpoint here')
+
+ # Disable confirmation prompt to avoid infinite wait
+ self.runCmd("settings set auto-confirm true")
+ self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
+
+ def build_and_run(self):
+ """Test top-level expressions."""
+ self.build()
+
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=False)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ def run_dummy(self):
+ self.runCmd("file dummy", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "dummy.cpp", self.dummy_line, num_expected_locations=1, loc_exact=False)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ @add_test_categories(['pyapi'])
+ @expectedFailureAndroid(api_levels=[21, 22], bugnumber="llvm.org/pr27787")
+ @expectedFailureAll(oslist=["linux"], archs=["arm", "aarch64"], bugnumber="llvm.org/pr27787")
+ @expectedFailureAll(bugnumber="llvm.org/pr28353", oslist=["linux"], archs=["i386", "x86_64"], compiler="gcc", compiler_version=["<", "4.9"])
+ @skipIf(debug_info="gmodules") # not relevant
+ @skipIf(oslist=["windows"]) # Error in record layout on Windows
+ def test_top_level_expressions(self):
+ self.build_and_run()
+
+ resultFromCode = self.frame().EvaluateExpression("doTest()").GetValueAsUnsigned()
+
+ self.runCmd("kill")
+
+ self.run_dummy()
+
+ codeFile = open('test.cpp', 'r')
+
+ expressions = []
+ current_expression = ""
+
+ for line in codeFile:
+ if line.startswith("// --"):
+ expressions.append(current_expression)
+ current_expression = ""
+ else:
+ current_expression += line
+
+ options = lldb.SBExpressionOptions()
+ options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+ options.SetTopLevel(True)
+
+ for expression in expressions:
+ self.frame().EvaluateExpression(expression, options)
+
+ resultFromTopLevel = self.frame().EvaluateExpression("doTest()")
+
+ self.assertTrue(resultFromTopLevel.IsValid())
+ self.assertEqual(resultFromCode, resultFromTopLevel.GetValueAsUnsigned())
diff --git a/packages/Python/lldbsuite/test/expression_command/top-level/dummy.cpp b/packages/Python/lldbsuite/test/expression_command/top-level/dummy.cpp
new file mode 100644
index 000000000000..31204b21d972
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/top-level/dummy.cpp
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("This is a dummy\n"); // Set breakpoint here
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/expression_command/top-level/main.cpp b/packages/Python/lldbsuite/test/expression_command/top-level/main.cpp
new file mode 100644
index 000000000000..f9b2dd4c6d9d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/top-level/main.cpp
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+extern int doTest();
+
+int main()
+{
+ printf("%d\n", doTest()); // Set breakpoint here
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/expression_command/top-level/test.cpp b/packages/Python/lldbsuite/test/expression_command/top-level/test.cpp
new file mode 100644
index 000000000000..ce2ea3bbb131
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/top-level/test.cpp
@@ -0,0 +1,107 @@
+class MyClass
+{
+public:
+ int memberResult()
+ {
+ return 1;
+ }
+ static int staticResult()
+ {
+ return 1;
+ }
+ int externResult();
+};
+
+// --
+
+int MyClass::externResult()
+{
+ return 1;
+}
+
+// --
+
+MyClass m;
+
+// --
+
+enum MyEnum {
+ myEnumOne = 1,
+ myEnumTwo,
+ myEnumThree
+};
+
+// --
+
+class AnotherClass
+{
+public:
+ __attribute__ ((always_inline)) int complicatedFunction()
+ {
+ struct {
+ int i;
+ } s = { 15 };
+
+ int as[4] = { 2, 3, 4, 5 };
+
+ for (signed char a : as)
+ {
+ s.i -= a;
+ }
+
+ return s.i;
+ }
+};
+
+// --
+
+class DiamondA
+{
+private:
+ struct {
+ int m_i;
+ };
+public:
+ DiamondA(int i) : m_i(i) { }
+ int accessor() { return m_i; }
+};
+
+// --
+
+class DiamondB : public virtual DiamondA
+{
+public:
+ DiamondB(int i) : DiamondA(i) { }
+};
+
+// --
+
+class DiamondC : public virtual DiamondA
+{
+public:
+ DiamondC(int i) : DiamondA(i) { }
+};
+
+// --
+
+class DiamondD : public DiamondB, public DiamondC
+{
+public:
+ DiamondD(int i) : DiamondA(i), DiamondB(i), DiamondC(i) { }
+};
+
+// --
+
+int doTest()
+{
+ int a = m.memberResult();
+ a += MyClass::staticResult();
+ a += m.externResult();
+ a += MyEnum::myEnumThree;
+ a += myEnumOne;
+ a += AnotherClass().complicatedFunction();
+ a += DiamondD(3).accessor();
+ return a;
+}
+
+// --
diff --git a/packages/Python/lldbsuite/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py b/packages/Python/lldbsuite/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py
index 5b0233509112..2b37faad807b 100644
--- a/packages/Python/lldbsuite/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py
+++ b/packages/Python/lldbsuite/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ObjCTypeQueryTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/expression_command/unwind_expression/Makefile b/packages/Python/lldbsuite/test/expression_command/unwind_expression/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/unwind_expression/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/expression_command/unwind_expression/TestUnwindExpression.py b/packages/Python/lldbsuite/test/expression_command/unwind_expression/TestUnwindExpression.py
new file mode 100644
index 000000000000..6e9af641d038
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/unwind_expression/TestUnwindExpression.py
@@ -0,0 +1,83 @@
+"""
+Test stopping at a breakpoint in an expression, and unwinding from there.
+"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class UnwindFromExpressionTest(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ @add_test_categories(['pyapi'])
+
+ def test_unwind_expression(self):
+ """Test unwinding from an expression."""
+ self.build()
+
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Create the breakpoint.
+ main_spec = lldb.SBFileSpec("main.cpp", False)
+ breakpoint = target.BreakpointCreateBySourceRegex("// Set a breakpoint here to get started", main_spec)
+ self.assertTrue(breakpoint, VALID_BREAKPOINT)
+
+ # Launch the process, and do not stop at the entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ if not process:
+ self.fail("SBTarget.LaunchProcess() failed")
+
+ if process.GetState() != lldb.eStateStopped:
+ self.fail("Process should be in the 'stopped' state, "
+ "instead the actual state is: '%s'" %
+ lldbutil.state_type_to_str(process.GetState()))
+
+ thread = lldbutil.get_one_thread_stopped_at_breakpoint(process, breakpoint)
+ self.assertIsNotNone(thread, "Expected one thread to be stopped at the breakpoint")
+
+ #
+ # Use Python API to evaluate expressions while stopped in a stack frame.
+ #
+ main_frame = thread.GetFrameAtIndex(0)
+
+ # Next set a breakpoint in this function, set up Expression options to stop on
+ # breakpoint hits, and call the function.
+ fun_bkpt = target.BreakpointCreateBySourceRegex("// Stop inside the function here.", main_spec)
+ self.assertTrue(fun_bkpt, VALID_BREAKPOINT)
+ options = lldb.SBExpressionOptions()
+ options.SetIgnoreBreakpoints(False)
+ options.SetUnwindOnError(False)
+
+ val = main_frame.EvaluateExpression("a_function_to_call()", options)
+
+ self.assertTrue(val.GetError().Fail(), "We did not complete the execution.")
+ error_str = val.GetError().GetCString()
+ self.assertTrue("Execution was interrupted, reason: breakpoint" in error_str, "And the reason was right.")
+
+ thread = lldbutil.get_one_thread_stopped_at_breakpoint(process, fun_bkpt)
+ self.assertTrue(thread.IsValid(), "We are indeed stopped at our breakpoint")
+
+ # Now unwind the expression, and make sure we got back to where we started.
+ error = thread.UnwindInnermostExpression()
+ self.assertTrue(error.Success(), "We succeeded in unwinding")
+
+ cur_frame = thread.GetFrameAtIndex(0)
+ self.assertTrue(cur_frame.IsEqual(main_frame), "We got back to the main frame.")
+
diff --git a/packages/Python/lldbsuite/test/expression_command/unwind_expression/main.cpp b/packages/Python/lldbsuite/test/expression_command/unwind_expression/main.cpp
new file mode 100644
index 000000000000..e93c34a30b03
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/unwind_expression/main.cpp
@@ -0,0 +1,14 @@
+static int static_value = 0;
+
+int
+a_function_to_call()
+{
+ static_value++; // Stop inside the function here.
+ return static_value;
+}
+
+int main (int argc, char const *argv[])
+{
+ a_function_to_call(); // Set a breakpoint here to get started
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/abbreviation/TestAbbreviations.py b/packages/Python/lldbsuite/test/functionalities/abbreviation/TestAbbreviations.py
index 1bce5bed491f..6423ecf27aeb 100644
--- a/packages/Python/lldbsuite/test/functionalities/abbreviation/TestAbbreviations.py
+++ b/packages/Python/lldbsuite/test/functionalities/abbreviation/TestAbbreviations.py
@@ -8,14 +8,14 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class AbbreviationsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFlakeyFreeBSD("llvm.org/pr22611 thread race condition breaks prompt setting")
@no_debug_info_test
def test_command_abbreviations_and_aliases (self):
command_interpreter = self.dbg.GetCommandInterpreter()
diff --git a/packages/Python/lldbsuite/test/functionalities/abbreviation/TestCommonShortSpellings.py b/packages/Python/lldbsuite/test/functionalities/abbreviation/TestCommonShortSpellings.py
index 9edbf212278c..fa6f3f306898 100644
--- a/packages/Python/lldbsuite/test/functionalities/abbreviation/TestCommonShortSpellings.py
+++ b/packages/Python/lldbsuite/test/functionalities/abbreviation/TestCommonShortSpellings.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CommonShortSpellingsTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/apropos_with_process/Makefile b/packages/Python/lldbsuite/test/functionalities/apropos_with_process/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/apropos_with_process/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/apropos_with_process/TestAproposWithProcess.py b/packages/Python/lldbsuite/test/functionalities/apropos_with_process/TestAproposWithProcess.py
new file mode 100644
index 000000000000..66ed3ff73298
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/apropos_with_process/TestAproposWithProcess.py
@@ -0,0 +1,44 @@
+"""
+Test that apropos env doesn't crash trying to touch the process plugin commmand
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class AproposWithProcessTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.cpp', '// break here')
+
+ def test_apropos_with_process(self):
+ """Test that apropos env doesn't crash trying to touch the process plugin commmand."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break in main() aftre the variables are assigned values.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
+
+ self.runCmd('apropos env')
diff --git a/packages/Python/lldbsuite/test/functionalities/apropos_with_process/main.cpp b/packages/Python/lldbsuite/test/functionalities/apropos_with_process/main.cpp
new file mode 100644
index 000000000000..44c149687f21
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/apropos_with_process/main.cpp
@@ -0,0 +1,15 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+int main (int argc, char const *argv[])
+{
+ return 0; // break here
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/archives/TestBSDArchives.py b/packages/Python/lldbsuite/test/functionalities/archives/TestBSDArchives.py
index 02e1b9551853..b419ad97a694 100644
--- a/packages/Python/lldbsuite/test/functionalities/archives/TestBSDArchives.py
+++ b/packages/Python/lldbsuite/test/functionalities/archives/TestBSDArchives.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class BSDArchivesTestCase(TestBase):
@@ -19,7 +20,8 @@ class BSDArchivesTestCase(TestBase):
# Find the line number in a(int) to break at.
self.line = line_number('a.c', '// Set file and line breakpoint inside a().')
- @expectedFailureWindows("llvm.org/pr24527") # Makefile.rules doesn't know how to build static libs on Windows.
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24527. Makefile.rules doesn't know how to build static libs on Windows")
+ @expectedFailureAll(oslist=["linux"], archs=["arm", "aarch64"], bugnumber="llvm.org/pr27795")
def test(self):
"""Break inside a() and b() defined within libfoo.a."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/asan/TestMemoryHistory.py b/packages/Python/lldbsuite/test/functionalities/asan/TestMemoryHistory.py
index e92b967d8adf..6416bccc483d 100644
--- a/packages/Python/lldbsuite/test/functionalities/asan/TestMemoryHistory.py
+++ b/packages/Python/lldbsuite/test/functionalities/asan/TestMemoryHistory.py
@@ -8,18 +8,19 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbplatform
+from lldbsuite.test import lldbutil
class AsanTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureLinux # non-core functionality, need to reenable and fix later (DES 2014.11.07)
+ @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)")
@skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
@skipIfRemote
@skipUnlessCompilerRt
- @expectedFailureDarwin
def test (self):
self.build ()
self.asan_tests ()
@@ -45,11 +46,10 @@ class AsanTestCase(TestBase):
self.runCmd("run")
- # ASan will relaunch the process to insert its library.
- self.expect("thread list", "Process should be stopped due to exec.",
- substrs = ['stopped', 'stop reason = '])
-
- self.runCmd("continue")
+ stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()
+ if stop_reason == lldb.eStopReasonExec:
+ # On OS X 10.10 and older, we need to re-exec to enable interceptors.
+ self.runCmd("continue")
# the stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
@@ -62,8 +62,8 @@ class AsanTestCase(TestBase):
# test the 'memory history' command
self.expect("memory history 'pointer'",
substrs = [
- 'Memory allocated at', 'a.out`f1', 'main.c:%d' % self.line_malloc,
- 'Memory deallocated at', 'a.out`f2', 'main.c:%d' % self.line_free])
+ 'Memory allocated by Thread', 'a.out`f1', 'main.c:%d' % self.line_malloc,
+ 'Memory deallocated by Thread', 'a.out`f2', 'main.c:%d' % self.line_free])
# do the same using SB API
process = self.dbg.GetSelectedTarget().process
@@ -87,17 +87,14 @@ class AsanTestCase(TestBase):
self.assertTrue(history_thread.num_frames >= 2)
self.assertEqual(history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(), "main.c")
self.assertEqual(history_thread.frames[1].GetLineEntry().GetLine(), self.line_malloc)
-
- # now let's break when an ASan report occurs and try the API then
- self.runCmd("breakpoint set -n __asan_report_error")
-
+
+ # ASan will break when a report occurs and we'll try the API then
self.runCmd("continue")
- # the stop reason of the thread should be breakpoint.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
- substrs = ['stopped', 'stop reason = breakpoint'])
+ self.expect("thread list", "Process should be stopped due to ASan report",
+ substrs = ['stopped', 'stop reason = Use of deallocated memory detected'])
# make sure the 'memory history' command still works even when we're generating a report now
self.expect("memory history 'another_pointer'",
substrs = [
- 'Memory allocated at', 'a.out`f1', 'main.c:%d' % self.line_malloc2])
+ 'Memory allocated by Thread', 'a.out`f1', 'main.c:%d' % self.line_malloc2])
diff --git a/packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py b/packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py
index 4ef587895196..b02732ddeddf 100644
--- a/packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py
+++ b/packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py
@@ -7,20 +7,20 @@ from __future__ import print_function
import os, time
+import json
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
-import json
+from lldbsuite.test import lldbutil
class AsanTestReportDataCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureLinux # non-core functionality, need to reenable and fix later (DES 2014.11.07)
+ @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)")
@skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
@skipIfRemote
@skipUnlessCompilerRt
- @expectedFailureDarwin
def test(self):
self.build ()
self.asan_tests ()
@@ -39,16 +39,10 @@ class AsanTestReportDataCase(TestBase):
self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ])
self.runCmd("run")
- # ASan will relaunch the process to insert its library.
- self.expect("thread list", "Process should be stopped due to exec.",
- substrs = ['stopped', 'stop reason = '])
-
- # no extended info when we have no ASan report
- thread = self.dbg.GetSelectedTarget().process.GetSelectedThread()
- s = lldb.SBStream()
- self.assertFalse(thread.GetStopReasonExtendedInfoAsJSON(s))
-
- self.runCmd("continue")
+ stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()
+ if stop_reason == lldb.eStopReasonExec:
+ # On OS X 10.10 and older, we need to re-exec to enable interceptors.
+ self.runCmd("continue")
self.expect("thread list", "Process should be stopped due to ASan report",
substrs = ['stopped', 'stop reason = Use of deallocated memory detected'])
@@ -62,7 +56,7 @@ class AsanTestReportDataCase(TestBase):
substrs = ["access_size", "access_type", "address", "pc", "description", "heap-use-after-free"])
output_lines = self.res.GetOutput().split('\n')
- json_line = output_lines[2]
+ json_line = '\n'.join(output_lines[2:])
data = json.loads(json_line)
self.assertEqual(data["description"], "heap-use-after-free")
self.assertEqual(data["instrumentation_class"], "AddressSanitizer")
diff --git a/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py b/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py
index 693c0a70fd62..54463c56827a 100644
--- a/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py
+++ b/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
exe_name = "AttachResume" # Must match Makefile
@@ -18,8 +19,8 @@ class AttachResumeTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfRemote
- @expectedFailureFreeBSD('llvm.org/pr19310')
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr19310')
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_attach_continue_interrupt_detach(self):
"""Test attach/continue/interrupt/detach"""
self.build()
@@ -37,19 +38,20 @@ class AttachResumeTestCase(TestBase):
self.setAsync(True)
listener = self.dbg.GetListener()
+ process = self.dbg.GetSelectedTarget().GetProcess()
self.runCmd("c")
- lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning])
+ lldbutil.expect_state_changes(self, listener, process, [lldb.eStateRunning])
self.runCmd("process interrupt")
- lldbutil.expect_state_changes(self, listener, [lldb.eStateStopped])
+ lldbutil.expect_state_changes(self, listener, process, [lldb.eStateStopped])
# be sure to continue/interrupt/continue (r204504)
self.runCmd("c")
- lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning])
+ lldbutil.expect_state_changes(self, listener, process, [lldb.eStateRunning])
self.runCmd("process interrupt")
- lldbutil.expect_state_changes(self, listener, [lldb.eStateStopped])
+ lldbutil.expect_state_changes(self, listener, process, [lldb.eStateStopped])
# Second interrupt should have no effect.
self.expect("process interrupt", patterns=["Process is not running"], error=True)
@@ -58,7 +60,7 @@ class AttachResumeTestCase(TestBase):
self.runCmd("br set -f main.cpp -l %u" % (line_number('main.cpp', '// Set breakpoint here')))
self.runCmd("c")
- lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning, lldb.eStateStopped])
+ lldbutil.expect_state_changes(self, listener, process, [lldb.eStateRunning, lldb.eStateStopped])
self.expect('br list', 'Breakpoint not hit',
substrs = ['hit count = 1'])
@@ -66,8 +68,8 @@ class AttachResumeTestCase(TestBase):
self.expect("expr debugger_flag = false", substrs=[" = false"]);
self.runCmd("c")
- lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning])
+ lldbutil.expect_state_changes(self, listener, process, [lldb.eStateRunning])
# make sure to detach while in running state (r204759)
self.runCmd("detach")
- lldbutil.expect_state_changes(self, listener, [lldb.eStateDetached])
+ lldbutil.expect_state_changes(self, listener, process, [lldb.eStateDetached])
diff --git a/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/TestFdLeak.py b/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/TestFdLeak.py
index e4bc08711f4c..e31eac48ad7a 100644
--- a/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/TestFdLeak.py
+++ b/packages/Python/lldbsuite/test/functionalities/avoids-fd-leak/TestFdLeak.py
@@ -8,29 +8,34 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test import lldbutil
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
def python_leaky_fd_version(test):
import sys
# Python random module leaks file descriptors on some versions.
- return sys.version_info >= (2, 7, 8) and sys.version_info < (2, 7, 10)
+ if sys.version_info >= (2, 7, 8) and sys.version_info < (2, 7, 10):
+ return "Python random module leaks file descriptors in this python version"
+ return None
class AvoidsFdLeakTestCase(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
mydir = TestBase.compute_mydir(__file__)
@expectedFailure(python_leaky_fd_version, "bugs.freebsd.org/197376")
- @expectedFailureFreeBSD("llvm.org/pr25624 still failing with Python 2.7.10")
+ @expectedFailureAll(oslist=['freebsd'], bugnumber="llvm.org/pr25624 still failing with Python 2.7.10")
@skipIfWindows # The check for descriptor leakage needs to be implemented differently here.
@skipIfTargetAndroid() # Android have some other file descriptors open by the shell
def test_fd_leak_basic (self):
self.do_test([])
@expectedFailure(python_leaky_fd_version, "bugs.freebsd.org/197376")
- @expectedFailureFreeBSD("llvm.org/pr25624 still failing with Python 2.7.10")
+ @expectedFailureAll(oslist=['freebsd'], bugnumber="llvm.org/pr25624 still failing with Python 2.7.10")
@skipIfWindows # The check for descriptor leakage needs to be implemented differently here.
@skipIfTargetAndroid() # Android have some other file descriptors open by the shell
def test_fd_leak_log (self):
@@ -53,8 +58,7 @@ class AvoidsFdLeakTestCase(TestBase):
"Process returned non-zero status. Were incorrect file descriptors passed?")
@expectedFailure(python_leaky_fd_version, "bugs.freebsd.org/197376")
- @expectedFailureFreeBSD("llvm.org/pr25624 still failing with Python 2.7.10")
- @expectedFlakeyLinux
+ @expectedFailureAll(oslist=['freebsd'], bugnumber="llvm.org/pr25624 still failing with Python 2.7.10")
@skipIfWindows # The check for descriptor leakage needs to be implemented differently here.
@skipIfTargetAndroid() # Android have some other file descriptors open by the shell
def test_fd_leak_multitarget (self):
diff --git a/packages/Python/lldbsuite/test/functionalities/backticks/TestBackticksWithoutATarget.py b/packages/Python/lldbsuite/test/functionalities/backticks/TestBackticksWithoutATarget.py
index d31412bc783c..851e4d376b38 100644
--- a/packages/Python/lldbsuite/test/functionalities/backticks/TestBackticksWithoutATarget.py
+++ b/packages/Python/lldbsuite/test/functionalities/backticks/TestBackticksWithoutATarget.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class BackticksWithNoTargetTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py
new file mode 100644
index 000000000000..73b3ef5eae28
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py
@@ -0,0 +1,77 @@
+"""
+Test that breakpoints set on a bad address say they are bad.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class BadAddressBreakpointTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_bad_address_breakpoints (self):
+ """Test that breakpoints set on a bad address say they are bad."""
+ self.build()
+ self.address_breakpoints()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def address_breakpoints(self):
+ """Test that breakpoints set on a bad address say they are bad."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Now create a breakpoint on main.c by name 'c'.
+ breakpoint = target.BreakpointCreateBySourceRegex("Set a breakpoint here", lldb.SBFileSpec("main.c"))
+ self.assertTrue(breakpoint and
+ breakpoint.GetNumLocations() == 1,
+ VALID_BREAKPOINT)
+
+ # Get the breakpoint location from breakpoint after we verified that,
+ # indeed, it has one location.
+ location = breakpoint.GetLocationAtIndex(0)
+ self.assertTrue(location and
+ location.IsEnabled(),
+ VALID_BREAKPOINT_LOCATION)
+
+ launch_info = lldb.SBLaunchInfo(None)
+
+ error = lldb.SBError()
+
+ process = target.Launch (launch_info, error)
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Did we hit our breakpoint?
+ from lldbsuite.test.lldbutil import get_threads_stopped_at_breakpoint
+ threads = get_threads_stopped_at_breakpoint (process, breakpoint)
+ self.assertTrue(len(threads) == 1, "There should be a thread stopped at our breakpoint")
+
+ # The hit count for the breakpoint should be 1.
+ self.assertTrue(breakpoint.GetHitCount() == 1)
+
+ # Now see if we can read from 0. If I can't do that, I don't have a good way to know
+ # what an illegal address is...
+ error.Clear()
+
+ ptr = process.ReadPointerFromMemory(0x0, error)
+
+ if not error.Success():
+ bkpt = target.BreakpointCreateByAddress(0x0)
+ for bp_loc in bkpt:
+ self.assertTrue(bp_loc.IsResolved() == False)
+ else:
+ self.fail("Could not find an illegal address at which to set a bad breakpoint.")
+
+
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/Makefile
new file mode 100644
index 000000000000..6067ee45e984
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+CFLAGS_EXTRAS += -std=c99
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/TestBreakpointCaseSensitivity.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/TestBreakpointCaseSensitivity.py
new file mode 100644
index 000000000000..aa4ee14ffc5a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/TestBreakpointCaseSensitivity.py
@@ -0,0 +1,121 @@
+"""
+Test case sensitivity of paths on Windows / POSIX
+llvm.org/pr22667
+"""
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbplatform, lldbplatformutil
+
+class BreakpointCaseSensitivityTestCase(TestBase):
+ mydir = TestBase.compute_mydir(__file__)
+ BREAKPOINT_TEXT = 'Set a breakpoint here'
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ self.line = line_number('main.c', self.BREAKPOINT_TEXT)
+
+ @skipIf(oslist=no_match(['windows'])) # Skip for non-windows platforms
+ def test_breakpoint_matches_file_with_different_case(self):
+ """Set breakpoint on file, should match files with different case on Windows"""
+ self.build()
+ self.case_sensitivity_breakpoint(True)
+
+ @skipIf(oslist=['windows']) # Skip for windows platforms
+ @expectedFailureAll() # Failing for unknown reason on non-Windows platforms.
+ def test_breakpoint_doesnt_match_file_with_different_case(self):
+ """Set breakpoint on file, shouldn't match files with different case on POSIX systems"""
+ self.build()
+ self.case_sensitivity_breakpoint(False)
+
+ def case_sensitivity_breakpoint(self, case_insensitive):
+ """Set breakpoint on file, should match files with different case if case_insensitive is True"""
+
+ # use different case to check CreateTarget
+ exe = 'a.out'
+ if case_insensitive:
+ exe = exe.upper()
+
+ exe = os.path.join(os.getcwd(), exe)
+
+ # Create a target by the debugger.
+ self.target = self.dbg.CreateTarget(exe)
+ self.assertTrue(self.target, VALID_TARGET)
+ cwd = self.get_process_working_directory();
+
+ # try both BreakpointCreateByLocation and BreakpointCreateBySourceRegex
+ for regex in [False, True]:
+ # should always hit
+ self.check_breakpoint('main.c', regex, True)
+ # should always hit
+ self.check_breakpoint(os.path.join(cwd, 'main.c'), regex, True)
+ # different case for directory
+ self.check_breakpoint(os.path.join(cwd.upper(), 'main.c'),
+ regex,
+ case_insensitive)
+ # different case for file
+ self.check_breakpoint('Main.c',
+ regex,
+ case_insensitive)
+ # different case for both
+ self.check_breakpoint(os.path.join(cwd.upper(), 'Main.c'),
+ regex,
+ case_insensitive)
+
+ def check_breakpoint(self, file, source_regex, should_hit):
+ """
+ Check breakpoint hit at given file set by given method
+
+ file:
+ File where insert the breakpoint
+
+ source_regex:
+ True for testing using BreakpointCreateBySourceRegex,
+ False for BreakpointCreateByLocation
+
+ should_hit:
+ True if the breakpoint should hit, False otherwise
+ """
+
+ desc = ' file %s set by %s' % (file, 'regex' if source_regex else 'location')
+ if source_regex:
+ breakpoint = self.target.BreakpointCreateBySourceRegex(self.BREAKPOINT_TEXT,
+ lldb.SBFileSpec(file))
+ else:
+ breakpoint = self.target.BreakpointCreateByLocation(file, self.line)
+
+ self.assertEqual(breakpoint and breakpoint.GetNumLocations() == 1,
+ should_hit,
+ VALID_BREAKPOINT + desc)
+
+ # Get the breakpoint location from breakpoint after we verified that,
+ # indeed, it has one location.
+ location = breakpoint.GetLocationAtIndex(0)
+ self.assertEqual(location and location.IsEnabled(),
+ should_hit,
+ VALID_BREAKPOINT_LOCATION + desc)
+
+ process = self.target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID + desc)
+
+ if should_hit:
+ # Did we hit our breakpoint?
+ from lldbsuite.test.lldbutil import get_threads_stopped_at_breakpoint
+ threads = get_threads_stopped_at_breakpoint (process, breakpoint)
+ self.assertEqual(len(threads), 1, "There should be a thread stopped at breakpoint" + desc)
+ # The hit count for the breakpoint should be 1.
+ self.assertEqual(breakpoint.GetHitCount(), 1)
+
+ else:
+ # check the breakpoint was not hit
+ self.assertEqual(lldb.eStateExited, process.GetState())
+ self.assertEqual(breakpoint.GetHitCount(), 0)
+
+ # let process finish
+ process.Continue()
+
+ # cleanup
+ self.target.BreakpointDelete(breakpoint.GetID())
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/main.c
new file mode 100644
index 000000000000..281ddfe7ef67
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/main.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int
+main()
+{
+ printf("Set a breakpoint here.\n");
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
index 8cf7539432ba..78d14b7d7705 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class BreakpointCommandTestCase(TestBase):
@@ -21,7 +22,7 @@ class BreakpointCommandTestCase(TestBase):
cls.RemoveTempFile("output.txt")
cls.RemoveTempFile("output2.txt")
- @expectedFailureWindows("llvm.org/pr24528")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
def test(self):
"""Test a sequence of breakpoint command add, list, and delete."""
self.build()
@@ -142,7 +143,7 @@ class BreakpointCommandTestCase(TestBase):
self.expect("breakpoint command list 1",
startstr = "Breakpoint 1 does not have an associated command.")
self.expect("breakpoint command list 2", error=True,
- startstr = "error: '2' is not a currently valid breakpoint id.")
+ startstr = "error: '2' is not a currently valid breakpoint ID.")
# The breakpoint list now only contains breakpoint 1.
self.expect("breakpoint list -f", "Breakpoint 1 exists",
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py
index 7a9cc744d528..4f8ab9e115de 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py
@@ -8,10 +8,11 @@ from __future__ import print_function
import os
import re
-import lldb
-import lldbsuite.test.lldbutil as lldbutil
import sys
+import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class PythonBreakpointCommandSettingTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py
index 8c22c8fe869c..0d34dd85dc50 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class BreakpointConditionsTestCase(TestBase):
@@ -107,11 +108,13 @@ class BreakpointConditionsTestCase(TestBase):
if arch in ['x86_64', 'i386']:
self.runCmd("breakpoint modify -c ($eax&&i)")
elif arch in ['aarch64']:
- self.runCmd("breakpoint modify -c ($x1&&i)")
+ self.runCmd("breakpoint modify -c ($x0&&i)")
elif arch in ['arm']:
self.runCmd("breakpoint modify -c ($r0&&i)")
elif re.match("mips",arch):
self.runCmd("breakpoint modify -c ($r2&&i)")
+ elif arch in ['s390x']:
+ self.runCmd("breakpoint modify -c ($r2&&i)")
self.runCmd("run")
self.expect("process status", PROCESS_STOPPED,
@@ -178,4 +181,8 @@ class BreakpointConditionsTestCase(TestBase):
# The hit count for the breakpoint should be 1.
self.assertTrue(breakpoint.GetHitCount() == 1)
+ # Test that the condition expression didn't create a result variable:
+ options = lldb.SBExpressionOptions()
+ value = frame0.EvaluateExpression("$0", options)
+ self.assertTrue(value.GetError().Fail(), "Conditions should not make result variables.")
process.Continue()
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py
index 8a83cb627f7a..05ef1c6d94c7 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class BreakpointIgnoreCountTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/TestAvoidBreakpointInDelaySlot.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/TestAvoidBreakpointInDelaySlot.py
index 324401ff44e1..b1e0d3deeae7 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/TestAvoidBreakpointInDelaySlot.py
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/TestAvoidBreakpointInDelaySlot.py
@@ -8,14 +8,15 @@ import os, time
import re
import unittest2
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class AvoidBreakpointInDelaySlotAPITestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipUnlessArch(archs=re.compile('mips*'))
+ @skipIf(archs=no_match(re.compile('mips*')))
def test(self):
self.build()
exe = os.path.join(os.getcwd(), "a.out")
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py
index 5c4dc219a106..707b6502e91c 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py
@@ -8,15 +8,15 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class BreakpointLocationsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr24528")
- @expectedFailureAll(oslist=["linux"], compiler="clang", compiler_version=["=", "3.8"], archs=["i386"], debug_info="dwo")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
def test(self):
"""Test breakpoint enable/disable for a breakpoint ID with multiple locations."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_set_restart/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_set_restart/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_set_restart/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_set_restart/TestBreakpointSetRestart.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_set_restart/TestBreakpointSetRestart.py
new file mode 100644
index 000000000000..4ca93765b656
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_set_restart/TestBreakpointSetRestart.py
@@ -0,0 +1,43 @@
+"""
+Test inferior restart when breakpoint is set on running target.
+"""
+
+import os
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class BreakpointSetRestart(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+ BREAKPOINT_TEXT = 'Set a breakpoint here'
+
+ def test_breakpoint_set_restart(self):
+ self.build()
+
+ cwd = os.getcwd()
+ exe = os.path.join(cwd, 'a.out')
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ self.dbg.SetAsync(True)
+ process = target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ event = lldb.SBEvent()
+ # Wait for inferior to transition to running state
+ while self.dbg.GetListener().WaitForEvent(2, event):
+ if lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateRunning:
+ break
+
+ bp = target.BreakpointCreateBySourceRegex(self.BREAKPOINT_TEXT,
+ lldb.SBFileSpec(os.path.join(cwd, 'main.cpp')))
+ self.assertTrue(bp.IsValid() and bp.GetNumLocations() == 1, VALID_BREAKPOINT)
+
+ while self.dbg.GetListener().WaitForEvent(2, event):
+ if lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateStopped and lldb.SBProcess.GetRestartedFromEvent(event):
+ continue
+ if lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateRunning:
+ continue
+ self.fail("Setting a breakpoint generated an unexpected event: %s" % lldb.SBDebugger.StateAsCString(lldb.SBProcess.GetStateFromEvent(event)))
+
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_set_restart/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_set_restart/main.cpp
new file mode 100644
index 000000000000..e6d3a95d017f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_set_restart/main.cpp
@@ -0,0 +1,25 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <chrono>
+#include <stdio.h>
+#include <thread>
+
+
+int main(int argc, char const *argv[])
+{
+ static bool done = false;
+ while (!done)
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds{100});
+ }
+ printf("Set a breakpoint here.\n");
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py
index e1de38bcad8c..4933d6d01d44 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py
@@ -6,10 +6,11 @@ from __future__ import print_function
import os
+import shutil
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
-import shutil
+from lldbsuite.test import lldbutil
_EXE_NAME = 'CompDirSymLink' # Must match Makefile
@@ -27,21 +28,21 @@ class CompDirSymLinkTestCase(TestBase):
self.line = line_number(_SRC_FILE, '// Set break point at this line.')
self.src_path = os.path.join(os.getcwd(), _SRC_FILE)
- @skipIfHostWindows
+ @skipIf(hostoslist=["windows"])
def test_symlink_paths_set(self):
pwd_symlink = self.create_src_symlink()
self.doBuild(pwd_symlink)
self.runCmd("settings set %s %s" % (_COMP_DIR_SYM_LINK_PROP, pwd_symlink))
lldbutil.run_break_set_by_file_and_line(self, self.src_path, self.line)
- @skipUnlessHostLinux
+ @skipIf(hostoslist=no_match(["linux"]))
def test_symlink_paths_set_procselfcwd(self):
pwd_symlink = '/proc/self/cwd'
self.doBuild(pwd_symlink)
self.runCmd("settings set %s %s" % (_COMP_DIR_SYM_LINK_PROP, pwd_symlink))
lldbutil.run_break_set_by_file_and_line(self, self.src_path, self.line)
- @skipIfHostWindows
+ @skipIf(hostoslist=["windows"])
def test_symlink_paths_unset(self):
pwd_symlink = self.create_src_symlink()
self.doBuild(pwd_symlink)
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/TestConsecutiveBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/TestConsecutiveBreakpoints.py
deleted file mode 100644
index af6df3764829..000000000000
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/TestConsecutiveBreakpoints.py
+++ /dev/null
@@ -1,59 +0,0 @@
-"""
-Test continue from a breakpoint when there is a breakpoint on the next instruction also.
-"""
-
-from __future__ import print_function
-
-
-
-import unittest2
-import lldb
-import lldbsuite.test.lldbutil as lldbutil
-from lldbsuite.test.lldbtest import *
-
-class ConsecutiveBreakpoitsTestCase(TestBase):
-
- mydir = TestBase.compute_mydir(__file__)
-
- @expectedFailureAll("llvm.org/pr23478", oslist = not_in(["macosx"]))
- def test (self):
- self.build ()
- self.consecutive_breakpoints_tests()
-
- def consecutive_breakpoints_tests(self):
- exe = os.path.join (os.getcwd(), "a.out")
-
- # Create a target by the debugger.
- target = self.dbg.CreateTarget(exe)
- self.assertTrue(target, VALID_TARGET)
-
- breakpoint = target.BreakpointCreateBySourceRegex("Set breakpoint here", lldb.SBFileSpec("main.cpp"))
- self.assertTrue(breakpoint and
- breakpoint.GetNumLocations() == 1,
- VALID_BREAKPOINT)
-
- # Now launch the process, and do not stop at entry point.
- process = target.LaunchSimple (None, None, self.get_process_working_directory())
- self.assertTrue(process, PROCESS_IS_VALID)
-
- # We should be stopped at the first breakpoint
- thread = process.GetThreadAtIndex(0)
- self.assertEqual(thread.GetStopReason(), lldb.eStopReasonBreakpoint)
-
- # Set breakpoint to the next instruction
- frame = thread.GetFrameAtIndex(0)
-
- address = frame.GetPCAddress()
- instructions = target.ReadInstructions(address, 2)
- self.assertTrue(len(instructions) == 2)
- address = instructions[1].GetAddress()
-
- target.BreakpointCreateByAddress(address.GetLoadAddress(target))
- process.Continue()
-
- # We should be stopped at the second breakpoint
- thread = process.GetThreadAtIndex(0)
- self.assertEqual(thread.GetStopReason(), lldb.eStopReasonBreakpoint)
-
- # Run the process until termination
- process.Continue()
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/Makefile
index f89b52a972e9..f89b52a972e9 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/Makefile
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/Makefile
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/TestConsecutiveBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/TestConsecutiveBreakpoints.py
new file mode 100644
index 000000000000..472479391c02
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/TestConsecutiveBreakpoints.py
@@ -0,0 +1,101 @@
+"""
+Test that we handle breakpoints on consecutive instructions correctly.
+"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class ConsecutiveBreakpointsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def prepare_test(self):
+ self.build()
+ exe = os.path.join (os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ self.target = self.dbg.CreateTarget(exe)
+ self.assertTrue(self.target, VALID_TARGET)
+
+ breakpoint1 = self.target.BreakpointCreateBySourceRegex("Set breakpoint here", lldb.SBFileSpec("main.cpp"))
+ self.assertTrue(breakpoint1 and breakpoint1.GetNumLocations() == 1, VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ self.process = self.target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertIsNotNone(self.process, PROCESS_IS_VALID)
+
+ # We should be stopped at the first breakpoint
+ self.thread = lldbutil.get_one_thread_stopped_at_breakpoint(self.process, breakpoint1)
+ self.assertIsNotNone(self.thread, "Expected one thread to be stopped at breakpoint 1")
+
+ # Set breakpoint to the next instruction
+ frame = self.thread.GetFrameAtIndex(0)
+
+ address = frame.GetPCAddress()
+ instructions = self.target.ReadInstructions(address, 2)
+ self.assertTrue(len(instructions) == 2)
+ self.bkpt_address = instructions[1].GetAddress()
+ self.breakpoint2 = self.target.BreakpointCreateByAddress(self.bkpt_address.GetLoadAddress(self.target))
+ self.assertTrue(self.breakpoint2 and self.breakpoint2.GetNumLocations() == 1, VALID_BREAKPOINT)
+
+ def finish_test(self):
+ # Run the process until termination
+ self.process.Continue()
+ self.assertEquals(self.process.GetState(), lldb.eStateExited)
+
+ @no_debug_info_test
+ def test_continue(self):
+ """Test that continue stops at the second breakpoint."""
+ self.prepare_test()
+
+ self.process.Continue()
+ self.assertEquals(self.process.GetState(), lldb.eStateStopped)
+ # We should be stopped at the second breakpoint
+ self.thread = lldbutil.get_one_thread_stopped_at_breakpoint(self.process, self.breakpoint2)
+ self.assertIsNotNone(self.thread, "Expected one thread to be stopped at breakpoint 2")
+
+ self.finish_test()
+
+ @no_debug_info_test
+ def test_single_step(self):
+ """Test that single step stops at the second breakpoint."""
+ self.prepare_test()
+
+ step_over = False
+ self.thread.StepInstruction(step_over)
+
+ self.assertEquals(self.process.GetState(), lldb.eStateStopped)
+ self.assertEquals(self.thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(self.target),
+ self.bkpt_address.GetLoadAddress(self.target))
+ self.thread = lldbutil.get_one_thread_stopped_at_breakpoint(self.process, self.breakpoint2)
+ self.assertIsNotNone(self.thread, "Expected one thread to be stopped at breakpoint 2")
+
+ self.finish_test()
+
+ @no_debug_info_test
+ def test_single_step_thread_specific(self):
+ """Test that single step stops, even though the second breakpoint is not valid."""
+ self.prepare_test()
+
+ # Choose a thread other than the current one. A non-existing thread is fine.
+ thread_index = self.process.GetNumThreads()+1
+ self.assertFalse(self.process.GetThreadAtIndex(thread_index).IsValid())
+ self.breakpoint2.SetThreadIndex(thread_index)
+
+ step_over = False
+ self.thread.StepInstruction(step_over)
+
+ self.assertEquals(self.process.GetState(), lldb.eStateStopped)
+ self.assertEquals(self.thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(self.target),
+ self.bkpt_address.GetLoadAddress(self.target))
+ self.assertEquals(self.thread.GetStopReason(), lldb.eStopReasonPlanComplete,
+ "Stop reason should be 'plan complete'")
+
+ self.finish_test()
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/main.cpp
index c1943f03dbf1..c1943f03dbf1 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoins/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/main.cpp
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/TestCPPBreakpointLocations.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/TestCPPBreakpointLocations.py
index dea206b9e9d2..c2aa597214ed 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/TestCPPBreakpointLocations.py
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/TestCPPBreakpointLocations.py
@@ -8,14 +8,15 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestCPPBreakpointLocations(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr24764")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")
def test (self):
self.build ()
self.breakpoint_id_tests ()
@@ -25,7 +26,7 @@ class TestCPPBreakpointLocations(TestBase):
name = bp_dict['name']
names = bp_dict['loc_names']
bp = target.BreakpointCreateByName (name)
- self.assertTrue (bp.GetNumLocations() == len(names), "Make sure we find the right number of breakpoint locations")
+ self.assertEquals(bp.GetNumLocations(), len(names), "Make sure we find the right number of breakpoint locations")
bp_loc_names = list()
for bp_loc in bp:
@@ -60,3 +61,35 @@ class TestCPPBreakpointLocations(TestBase):
for bp_dict in bp_dicts:
self.verify_breakpoint_locations(target, bp_dict)
+
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")
+ def test_destructors(self):
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+
+ # Don't skip prologue, so we can check the breakpoint address more easily
+ self.runCmd("settings set target.skip-prologue false")
+ try:
+ names = ['~c', 'c::~c', 'c::~c()']
+ loc_names = {'a::c::~c()', 'b::c::~c()'}
+ # TODO: For windows targets we should put windows mangled names here
+ symbols = ['_ZN1a1cD1Ev', '_ZN1a1cD2Ev', '_ZN1b1cD1Ev', '_ZN1b1cD2Ev']
+
+ for name in names:
+ bp = target.BreakpointCreateByName(name)
+
+ bp_loc_names = { bp_loc.GetAddress().GetFunction().GetName() for bp_loc in bp }
+ self.assertEquals(bp_loc_names, loc_names, "Breakpoint set on the correct symbol")
+
+ bp_addresses = { bp_loc.GetLoadAddress() for bp_loc in bp }
+ symbol_addresses = set()
+ for symbol in symbols:
+ sc_list = target.FindSymbols(symbol, lldb.eSymbolTypeCode)
+ self.assertEquals(sc_list.GetSize(), 1, "Found symbol " + symbol)
+ symbol = sc_list.GetContextAtIndex(0).GetSymbol()
+ symbol_addresses.add(symbol.GetStartAddress().GetLoadAddress(target))
+
+ self.assertEquals(symbol_addresses, bp_addresses, "Breakpoint set on correct address")
+ finally:
+ self.runCmd("settings clear target.skip-prologue")
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/main.cpp
index ef582aa36ebb..01f679139249 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp/main.cpp
@@ -12,8 +12,8 @@
namespace a {
class c {
public:
- c () {}
- ~c() {}
+ c();
+ ~c();
void func1()
{
puts (__PRETTY_FUNCTION__);
@@ -27,13 +27,16 @@ namespace a {
puts (__PRETTY_FUNCTION__);
}
};
+
+ c::c() {}
+ c::~c() {}
}
namespace b {
class c {
public:
- c () {}
- ~c() {}
+ c();
+ ~c();
void func1()
{
puts (__PRETTY_FUNCTION__);
@@ -43,6 +46,9 @@ namespace b {
puts (__PRETTY_FUNCTION__);
}
};
+
+ c::c() {}
+ c::~c() {}
}
namespace c {
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/TestCPPExceptionBreakpoint.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/TestCPPExceptionBreakpoint.py
index f7a19098b492..2aac3a9600d3 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/TestCPPExceptionBreakpoint.py
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/cpp_exception/TestCPPExceptionBreakpoint.py
@@ -8,10 +8,11 @@ from __future__ import print_function
import os
import re
-import lldb
-import lldbsuite.test.lldbutil as lldbutil
import sys
+import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestCPPExceptionBreakpoint (TestBase):
@@ -19,7 +20,7 @@ class TestCPPExceptionBreakpoint (TestBase):
my_var = 10
@add_test_categories(['pyapi'])
- @expectedFailureWindows("llvm.org/pr24538") # clang-cl does not support throw or catch
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24538")
def test_cpp_exception_breakpoint(self):
"""Test setting and hitting the C++ exception breakpoint."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/debugbreak/TestDebugBreak.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/debugbreak/TestDebugBreak.py
index b32c970301c9..de61f9e88f1b 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/debugbreak/TestDebugBreak.py
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/debugbreak/TestDebugBreak.py
@@ -6,14 +6,15 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class DebugBreakTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipIf(archs=not_in(["i386", "i686"]))
+ @skipIf(archs=no_match(["i386", "i686", "x86_64"]))
@no_debug_info_test
def test_asm_int_3(self):
"""Test that intrinsics like `__debugbreak();` and `asm {"int3"}` are treated like breakpoints."""
@@ -26,13 +27,15 @@ class DebugBreakTestCase(TestBase):
# We've hit the first stop, so grab the frame.
self.assertEqual(process.GetState(), lldb.eStateStopped)
- thread = process.GetThreadAtIndex(0)
+ stop_reason = lldb.eStopReasonException if (lldbplatformutil.getPlatform()=="windows" or lldbplatformutil.getPlatform()=="macosx") else lldb.eStopReasonSignal
+ thread = lldbutil.get_stopped_thread(process, stop_reason)
+ self.assertIsNotNone(thread, "Unable to find thread stopped at the __debugbreak()")
frame = thread.GetFrameAtIndex(0)
# We should be in funciton 'bar'.
self.assertTrue(frame.IsValid())
function_name = frame.GetFunctionName()
- self.assertTrue('bar' in function_name)
+ self.assertTrue('bar' in function_name, "Unexpected function name {}".format(function_name))
# We should be able to evaluate the parameter foo.
value = frame.EvaluateExpression('*foo')
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/TestObjCBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/TestObjCBreakpoints.py
index 648a0f5ea07c..c48cee1bd2b2 100644
--- a/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/TestObjCBreakpoints.py
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/objc/TestObjCBreakpoints.py
@@ -8,11 +8,12 @@ from __future__ import print_function
import os, time
-import lldb
-from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
import shutil
import subprocess
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class TestObjCBreakpoints(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/Makefile
new file mode 100644
index 000000000000..ac984f101c18
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c a.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/TestSourceRegexBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/TestSourceRegexBreakpoints.py
new file mode 100644
index 000000000000..81cab927d214
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/TestSourceRegexBreakpoints.py
@@ -0,0 +1,100 @@
+"""
+Test lldb breakpoint setting by source regular expression.
+This test just tests the source file & function restrictions.
+"""
+
+from __future__ import print_function
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestSourceRegexBreakpoints(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_location (self):
+ self.build()
+ self.source_regex_locations()
+
+ def test_restrictions (self):
+ self.build ()
+ self.source_regex_restrictions ()
+
+
+ def source_regex_locations (self):
+ """ Test that restricting source expressions to files & to functions. """
+ # Create a target by the debugger.
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # First look just in main:
+ target_files = lldb.SBFileSpecList()
+ target_files.Append(lldb.SBFileSpec("a.c"))
+
+ func_names = lldb.SBStringList()
+ func_names.AppendString("a_func")
+
+ source_regex = "Set . breakpoint here"
+ main_break = target.BreakpointCreateBySourceRegex (source_regex,
+ lldb.SBFileSpecList(),
+ target_files,
+ func_names)
+ num_locations = main_break.GetNumLocations()
+ self.assertTrue(num_locations == 1, "a.c in a_func should give one breakpoint, got %d."%(num_locations))
+
+ loc = main_break.GetLocationAtIndex(0)
+ self.assertTrue(loc.IsValid(), "Got a valid location.")
+ address = loc.GetAddress()
+ self.assertTrue(address.IsValid(), "Got a valid address from the location.")
+
+ a_func_line = line_number("a.c", "Set A breakpoint here")
+ line_entry = address.GetLineEntry()
+ self.assertTrue(line_entry.IsValid(), "Got a valid line entry.")
+ self.assertTrue(line_entry.line == a_func_line, "Our line number matches the one lldbtest found.")
+
+ def source_regex_restrictions (self):
+ """ Test that restricting source expressions to files & to functions. """
+ # Create a target by the debugger.
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # First look just in main:
+ target_files = lldb.SBFileSpecList()
+ target_files.Append(lldb.SBFileSpec("main.c"))
+ source_regex = "Set . breakpoint here"
+ main_break = target.BreakpointCreateBySourceRegex (source_regex,
+ lldb.SBFileSpecList(),
+ target_files,
+ lldb.SBStringList())
+
+ num_locations = main_break.GetNumLocations()
+ self.assertTrue(num_locations == 2, "main.c should have 2 matches, got %d."%(num_locations))
+
+ # Now look in both files:
+ target_files.Append(lldb.SBFileSpec("a.c"))
+
+ main_break = target.BreakpointCreateBySourceRegex (source_regex,
+ lldb.SBFileSpecList(),
+ target_files,
+ lldb.SBStringList())
+
+ num_locations =main_break.GetNumLocations()
+ self.assertTrue(num_locations == 4, "main.c and a.c should have 4 matches, got %d."%(num_locations))
+
+ # Now restrict it to functions:
+ func_names = lldb.SBStringList()
+ func_names.AppendString("main_func")
+ main_break = target.BreakpointCreateBySourceRegex (source_regex,
+ lldb.SBFileSpecList(),
+ target_files,
+ func_names)
+
+ num_locations =main_break.GetNumLocations()
+ self.assertTrue(num_locations == 2, "main_func in main.c and a.c should have 2 matches, got %d."%(num_locations))
+
+
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/a.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/a.c
new file mode 100644
index 000000000000..056583f1c42c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/a.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+#include "a.h"
+
+static int
+main_func(int input)
+{
+ return printf("Set B breakpoint here: %d", input);
+}
+
+int
+a_func(int input)
+{
+ input += 1; // Set A breakpoint here;
+ return main_func(input);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/a.h b/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/a.h
new file mode 100644
index 000000000000..f578ac0304cd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/a.h
@@ -0,0 +1 @@
+int a_func(int);
diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/main.c
new file mode 100644
index 000000000000..9c8625e877f5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/source_regexp/main.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include "a.h"
+
+int
+main_func(int input)
+{
+ return printf("Set B breakpoint here: %d.\n", input);
+}
+
+int
+main()
+{
+ a_func(10);
+ main_func(10);
+ printf("Set a breakpoint here:\n");
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/command_history/TestCommandHistory.py b/packages/Python/lldbsuite/test/functionalities/command_history/TestCommandHistory.py
index 312c91517f98..66ba8d07622d 100644
--- a/packages/Python/lldbsuite/test/functionalities/command_history/TestCommandHistory.py
+++ b/packages/Python/lldbsuite/test/functionalities/command_history/TestCommandHistory.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class CommandHistoryTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/command_regex/TestCommandRegex.py b/packages/Python/lldbsuite/test/functionalities/command_regex/TestCommandRegex.py
index 2c48efa863b4..5b680ec65de5 100644
--- a/packages/Python/lldbsuite/test/functionalities/command_regex/TestCommandRegex.py
+++ b/packages/Python/lldbsuite/test/functionalities/command_regex/TestCommandRegex.py
@@ -8,13 +8,15 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class CommandRegexTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureHostWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@no_debug_info_test
def test_command_regex(self):
"""Test a simple scenario of 'command regex' invocation and subsequent use."""
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/TestCommandScript.py b/packages/Python/lldbsuite/test/functionalities/command_script/TestCommandScript.py
index 542ee7a1e5f3..97e52231e818 100644
--- a/packages/Python/lldbsuite/test/functionalities/command_script/TestCommandScript.py
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/TestCommandScript.py
@@ -87,8 +87,8 @@ class CmdPythonTestCase(TestBase):
'For more information run'])
self.expect("help targetname",
- substrs = ['This', 'command', 'takes', '\'raw\'', 'input',
- 'quote', 'stuff'])
+ substrs = ['Expects', '\'raw\'', 'input',
+ 'help', 'raw-input'])
self.expect("longwait",
substrs = ['Done; if you saw the delays I am doing OK'])
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/TestImport.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/TestImport.py
index 691045ae82ed..01c3f35bf300 100644
--- a/packages/Python/lldbsuite/test/functionalities/command_script/import/TestImport.py
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/TestImport.py
@@ -6,7 +6,9 @@ from __future__ import print_function
import os, sys, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ImportTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/TestRdar12586188.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/TestRdar12586188.py
index 9800a08c06de..4f7ebebd4dd2 100644
--- a/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/TestRdar12586188.py
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/rdar-12586188/TestRdar12586188.py
@@ -6,7 +6,9 @@ from __future__ import print_function
import os, sys, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class Rdar12586188TestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/__init__.py b/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/__init__.py
index faa4e3b0cbff..1181462af868 100644
--- a/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/__init__.py
+++ b/packages/Python/lldbsuite/test/functionalities/command_script/import/thepackage/__init__.py
@@ -1,5 +1,7 @@
-import TPunitA
-import TPunitB
+from __future__ import absolute_import
+
+from . import TPunitA
+from . import TPunitB
def __lldb_init_module(debugger,*args):
debugger.HandleCommand("command script add -f thepackage.TPunitA.command TPcommandA")
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script_alias/.categories b/packages/Python/lldbsuite/test/functionalities/command_script_alias/.categories
new file mode 100644
index 000000000000..3a3f4df6416b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script_alias/.categories
@@ -0,0 +1 @@
+cmdline
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script_alias/TestCommandScriptAlias.py b/packages/Python/lldbsuite/test/functionalities/command_script_alias/TestCommandScriptAlias.py
new file mode 100644
index 000000000000..694728a9f9c0
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script_alias/TestCommandScriptAlias.py
@@ -0,0 +1,37 @@
+"""
+Test lldb Python commands.
+"""
+
+from __future__ import print_function
+
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+
+class CommandScriptAliasTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test (self):
+ self.pycmd_tests ()
+
+ def pycmd_tests (self):
+ self.runCmd("command script import tcsacmd.py")
+ self.runCmd("command script add -f tcsacmd.some_command_here attach")
+
+ # This is the function to remove the custom commands in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('command script delete attach', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # We don't want to display the stdout if not in TraceOn() mode.
+ if not self.TraceOn():
+ self.HideStdout()
+
+ self.expect('attach a', substrs = ['Victory is mine']);
+ self.runCmd("command script delete attach")
+ self.runCmd('attach noprocessexistswiththisname', check=False) # this can't crash but we don't care whether the actual attach works
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script_alias/tcsacmd.py b/packages/Python/lldbsuite/test/functionalities/command_script_alias/tcsacmd.py
new file mode 100644
index 000000000000..6c60e3ca1a55
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script_alias/tcsacmd.py
@@ -0,0 +1,11 @@
+from __future__ import print_function
+import lldb, sys
+
+def some_command_here(debugger, command, result, d):
+ if command == "a":
+ print("Victory is mine", file=result)
+ return True
+ else:
+ print("Sadness for all", file=result)
+ return False
+
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/TestCommandScriptImmediateOutput.py b/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/TestCommandScriptImmediateOutput.py
new file mode 100644
index 000000000000..a843d08a97d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/TestCommandScriptImmediateOutput.py
@@ -0,0 +1,86 @@
+"""
+Test that LLDB correctly allows scripted commands to set an immediate output file
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.lldbpexpect import *
+from lldbsuite.test import lldbutil
+
+class CommandScriptImmediateOutputTestCase (PExpectTest):
+
+ mydir = TestBase.compute_mydir(__file__)
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def setUp(self):
+ # Call super's setUp().
+ PExpectTest.setUp(self)
+
+ @skipIfRemote # test not remote-ready llvm.org/pr24813
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr26139")
+ def test_command_script_immediate_output_console (self):
+ """Test that LLDB correctly allows scripted commands to set immediate output to the console."""
+ self.launch(timeout=10)
+
+ script = os.path.join(os.getcwd(), 'custom_command.py')
+ prompt = "\(lldb\) "
+
+ self.sendline('command script import %s' % script, patterns=[prompt])
+ self.sendline('command script add -f custom_command.command_function mycommand', patterns=[prompt])
+ self.sendline('mycommand', patterns='this is a test string, just a test string')
+ self.sendline('command script delete mycommand', patterns=[prompt])
+ self.quit(gracefully=False)
+
+ @skipIfRemote # test not remote-ready llvm.org/pr24813
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr26139")
+ def test_command_script_immediate_output_file (self):
+ """Test that LLDB correctly allows scripted commands to set immediate output to a file."""
+ self.launch(timeout=10)
+
+ test_files = {os.path.join(os.getcwd(), 'read.txt') :'r',
+ os.path.join(os.getcwd(), 'write.txt') :'w',
+ os.path.join(os.getcwd(), 'append.txt') :'a',
+ os.path.join(os.getcwd(), 'write_plus.txt') :'w+',
+ os.path.join(os.getcwd(), 'read_plus.txt') :'r+',
+ os.path.join(os.getcwd(), 'append_plus.txt') :'a+'}
+
+ starter_string = 'Starter Garbage\n'
+ write_string = 'writing to file with mode: '
+
+ for path, mode in test_files.iteritems():
+ with open(path, 'w+') as init:
+ init.write(starter_string)
+
+ script = os.path.join(os.getcwd(), 'custom_command.py')
+ prompt = "\(lldb\) "
+
+ self.sendline('command script import %s' % script, patterns=[prompt])
+
+ self.sendline('command script add -f custom_command.write_file mywrite', patterns=[prompt])
+ for path, mode in test_files.iteritems():
+ command = 'mywrite "' + path + '" ' + mode
+
+ self.sendline(command, patterns=[prompt])
+
+ self.sendline('command script delete mywrite', patterns=[prompt])
+
+ self.quit(gracefully=False)
+
+ for path, mode in test_files.iteritems():
+ with open(path, 'r') as result:
+ if mode in ['r', 'a', 'a+']:
+ self.assertEquals(result.readline(), starter_string)
+ if mode in ['w', 'w+', 'r+', 'a', 'a+']:
+ self.assertEquals(result.readline(), write_string + mode + '\n')
+
+ self.assertTrue(os.path.isfile(path))
+ os.remove(path)
+
diff --git a/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/custom_command.py b/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/custom_command.py
new file mode 100644
index 000000000000..30a3cfb9093c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/custom_command.py
@@ -0,0 +1,17 @@
+from __future__ import print_function
+
+import sys
+import shlex
+
+def command_function(debugger, command, exe_ctx, result, internal_dict):
+ result.SetImmediateOutputFile(sys.__stdout__)
+ print('this is a test string, just a test string', file=result)
+
+def write_file(debugger, command, exe_ctx, result, internal_dict):
+ args = shlex.split(command)
+ path = args[0]
+ mode = args[1]
+ with open(path, mode) as f:
+ result.SetImmediateOutputFile(f)
+ if not mode in ['r']:
+ print('writing to file with mode: ' + mode, file=result)
diff --git a/packages/Python/lldbsuite/test/functionalities/command_source/TestCommandSource.py b/packages/Python/lldbsuite/test/functionalities/command_source/TestCommandSource.py
index 013803e698af..0d4eb0776e79 100644
--- a/packages/Python/lldbsuite/test/functionalities/command_source/TestCommandSource.py
+++ b/packages/Python/lldbsuite/test/functionalities/command_source/TestCommandSource.py
@@ -10,7 +10,9 @@ from __future__ import print_function
import os, sys
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class CommandSourceTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py
index d7aab03c0830..7a9ded03ad20 100644
--- a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py
+++ b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py
@@ -8,7 +8,10 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbplatform
+from lldbsuite.test import lldbutil
class CommandLineCompletionTestCase(TestBase):
@@ -23,21 +26,21 @@ class CommandLineCompletionTestCase(TestBase):
except:
pass
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_at(self):
"""Test that 'at' completes to 'attach '."""
self.complete_from_to('at', 'attach ')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_de(self):
"""Test that 'de' completes to 'detach '."""
self.complete_from_to('de', 'detach ')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_process_attach_dash_dash_con(self):
@@ -45,7 +48,7 @@ class CommandLineCompletionTestCase(TestBase):
self.complete_from_to('process attach --con', 'process attach --continue ')
# <rdar://problem/11052829>
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_infinite_loop_while_completing(self):
@@ -53,147 +56,147 @@ class CommandLineCompletionTestCase(TestBase):
self.complete_from_to('process print hello\\', 'process print hello\\',
turn_off_re_match=True)
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_watchpoint_co(self):
"""Test that 'watchpoint co' completes to 'watchpoint command '."""
self.complete_from_to('watchpoint co', 'watchpoint command ')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_watchpoint_command_space(self):
"""Test that 'watchpoint command ' completes to ['Available completions:', 'add', 'delete', 'list']."""
self.complete_from_to('watchpoint command ', ['Available completions:', 'add', 'delete', 'list'])
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_watchpoint_command_a(self):
"""Test that 'watchpoint command a' completes to 'watchpoint command add '."""
self.complete_from_to('watchpoint command a', 'watchpoint command add ')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_watchpoint_set_variable_dash_w(self):
"""Test that 'watchpoint set variable -w' completes to 'watchpoint set variable -w '."""
self.complete_from_to('watchpoint set variable -w', 'watchpoint set variable -w ')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_watchpoint_set_variable_dash_w_space(self):
"""Test that 'watchpoint set variable -w ' completes to ['Available completions:', 'read', 'write', 'read_write']."""
self.complete_from_to('watchpoint set variable -w ', ['Available completions:', 'read', 'write', 'read_write'])
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_watchpoint_set_ex(self):
"""Test that 'watchpoint set ex' completes to 'watchpoint set expression '."""
self.complete_from_to('watchpoint set ex', 'watchpoint set expression ')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_watchpoint_set_var(self):
"""Test that 'watchpoint set var' completes to 'watchpoint set variable '."""
self.complete_from_to('watchpoint set var', 'watchpoint set variable ')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_watchpoint_set_variable_dash_w_read_underbar(self):
"""Test that 'watchpoint set variable -w read_' completes to 'watchpoint set variable -w read_write'."""
self.complete_from_to('watchpoint set variable -w read_', 'watchpoint set variable -w read_write')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_help_fi(self):
"""Test that 'help fi' completes to ['Available completions:', 'file', 'finish']."""
self.complete_from_to('help fi', ['Available completions:', 'file', 'finish'])
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_help_watchpoint_s(self):
"""Test that 'help watchpoint s' completes to 'help watchpoint set '."""
self.complete_from_to('help watchpoint s', 'help watchpoint set ')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_append_target_er(self):
"""Test that 'settings append target.er' completes to 'settings append target.error-path'."""
self.complete_from_to('settings append target.er', 'settings append target.error-path')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_insert_after_target_en(self):
"""Test that 'settings insert-after target.env' completes to 'settings insert-after target.env-vars'."""
self.complete_from_to('settings insert-after target.env', 'settings insert-after target.env-vars')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_insert_before_target_en(self):
"""Test that 'settings insert-before target.env' completes to 'settings insert-before target.env-vars'."""
self.complete_from_to('settings insert-before target.env', 'settings insert-before target.env-vars')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_replace_target_ru(self):
"""Test that 'settings replace target.ru' completes to 'settings replace target.run-args'."""
self.complete_from_to('settings replace target.ru', 'settings replace target.run-args')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_s(self):
"""Test that 'settings s' completes to ['Available completions:', 'set', 'show']."""
self.complete_from_to('settings s', ['Available completions:', 'set', 'show'])
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_set_th(self):
"""Test that 'settings set th' completes to 'settings set thread-format'."""
self.complete_from_to('settings set th', 'settings set thread-format')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_s_dash(self):
"""Test that 'settings set -' completes to 'settings set -g'."""
self.complete_from_to('settings set -', 'settings set -g')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_clear_th(self):
"""Test that 'settings clear th' completes to 'settings clear thread-format'."""
self.complete_from_to('settings clear th', 'settings clear thread-format')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_set_ta(self):
"""Test that 'settings set ta' completes to 'settings set target.'."""
self.complete_from_to('settings set target.ma', 'settings set target.max-')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_set_target_exec(self):
"""Test that 'settings set target.exec' completes to 'settings set target.exec-search-paths '."""
self.complete_from_to('settings set target.exec', 'settings set target.exec-search-paths')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_set_target_pr(self):
@@ -204,21 +207,21 @@ class CommandLineCompletionTestCase(TestBase):
'target.prefer-dynamic-value',
'target.process.'])
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_set_target_process(self):
"""Test that 'settings set target.process' completes to 'settings set target.process.'."""
self.complete_from_to('settings set target.process', 'settings set target.process.')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_set_target_process_dot(self):
"""Test that 'settings set target.process.t' completes to 'settings set target.process.thread.'."""
self.complete_from_to('settings set target.process.t', 'settings set target.process.thread.')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_settings_set_target_process_thread_dot(self):
@@ -229,7 +232,7 @@ class CommandLineCompletionTestCase(TestBase):
'target.process.thread.step-avoid-regexp',
'target.process.thread.trace-thread'])
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_target_space(self):
@@ -239,22 +242,22 @@ class CommandLineCompletionTestCase(TestBase):
['Available completions:', 'create', 'delete', 'list',
'modules', 'select', 'stop-hook', 'variable'])
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_target_create_dash_co(self):
"""Test that 'target create --co' completes to 'target variable --core '."""
self.complete_from_to('target create --co', 'target create --core ')
- @expectedFailureHostWindows("llvm.org/pr24679")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
@skipIfFreeBSD # timing out on the FreeBSD buildbot
@no_debug_info_test
def test_target_va(self):
"""Test that 'target va' completes to 'target variable '."""
self.complete_from_to('target va', 'target variable ')
- @expectedFailureHostWindows("llvm.org/pr24679")
- @expectedFailureDarwin("llvm.org/pr25485")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr24679")
+ @expectedFailureAll(oslist=lldbplatform.darwin_all, bugnumber="llvm.org/pr25485")
def test_symbol_name(self):
self.build()
self.complete_from_to('''file a.out
diff --git a/packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py b/packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py
index 3ae7a20b4c7d..7fcb44f0b3ec 100644
--- a/packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py
+++ b/packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
# rdar://problem/8532131
# lldb not able to digest the clang-generated debug info correctly with respect to function name
@@ -32,6 +33,7 @@ class ConditionalBreakTestCase(TestBase):
self.build()
self.simulate_conditional_break_by_user()
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr26265: args in frames other than #0 are not evaluated correctly")
def do_conditional_break(self):
"""Exercise some thread and frame APIs to break if c() is called by a()."""
exe = os.path.join(os.getcwd(), "a.out")
@@ -64,7 +66,8 @@ class ConditionalBreakTestCase(TestBase):
for j in range(10):
if self.TraceOn():
print("j is: ", j)
- thread = process.GetThreadAtIndex(0)
+ thread = lldbutil.get_one_thread_stopped_at_breakpoint(process, breakpoint)
+ self.assertIsNotNone(thread, "Expected one thread to be stopped at the breakpoint")
if thread.GetNumFrames() >= 2:
frame0 = thread.GetFrameAtIndex(0)
@@ -82,8 +85,8 @@ class ConditionalBreakTestCase(TestBase):
# And the local variable 'val' should have a value of (int) 3.
val = frame1.FindVariable("val")
- self.assertTrue(val.GetTypeName() == "int", "'val' has int type")
- self.assertTrue(val.GetValue() == "3", "'val' has a value of 3")
+ self.assertEqual("int", val.GetTypeName())
+ self.assertEqual("3", val.GetValue())
break
process.Continue()
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/TestFormattersBoolRefPtr.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/TestFormattersBoolRefPtr.py
index 94cdfdfeb343..fb3511ebd91d 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/TestFormattersBoolRefPtr.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/TestFormattersBoolRefPtr.py
@@ -6,11 +6,12 @@ from __future__ import print_function
+import datetime
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import datetime
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class DataFormatterBoolRefPtr(TestBase):
@@ -56,6 +57,8 @@ class DataFormatterBoolRefPtr(TestBase):
substrs = ['YES'])
self.expect('frame variable no_ref',
substrs = ['NO'])
+ self.expect('frame variable unset_ref',
+ substrs = ['12'])
# Now check that we use the right summary for BOOL*
@@ -63,6 +66,8 @@ class DataFormatterBoolRefPtr(TestBase):
substrs = ['YES'])
self.expect('frame variable no_ptr',
substrs = ['NO'])
+ self.expect('frame variable unset_ptr',
+ substrs = ['12'])
# Now check that we use the right summary for BOOL
@@ -70,3 +75,5 @@ class DataFormatterBoolRefPtr(TestBase):
substrs = ['YES'])
self.expect('frame variable no',
substrs = ['NO'])
+ self.expect('frame variable unset',
+ substrs = ['12'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/main.mm b/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/main.mm
index a2461fd9da91..22c8790a7541 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/main.mm
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/boolreference/main.mm
@@ -11,17 +11,19 @@
int main (int argc, const char * argv[])
{
-
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
BOOL yes = YES;
BOOL no = NO;
+ BOOL unset = 12;
BOOL &yes_ref = yes;
BOOL &no_ref = no;
+ BOOL &unset_ref = unset;
BOOL* yes_ptr = &yes;
BOOL* no_ptr = &no;
+ BOOL* unset_ptr = &unset;
[pool drain];// Set break point at this line.
return 0;
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/TestCompactVectors.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/TestCompactVectors.py
index 7cd2a49b4717..914c5260ac24 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/TestCompactVectors.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/compactvectors/TestCompactVectors.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CompactVectorsFormattingTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
index db426cac6e59..f8209f03d0c2 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CategoriesDataFormatterTestCase(TestBase):
@@ -154,6 +155,7 @@ class CategoriesDataFormatterTestCase(TestBase):
self.runCmd("type category enable Category1")
self.runCmd("type summary list -w Category1")
+ self.expect("type summary list -w NoSuchCategoryHere", substrs=['no matching results found'])
self.expect("frame variable r1 r2 r3",
substrs = ['r1 = Category1',
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
index 2ca737156a1a..99443a04f672 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CppDataFormatterTestCase(TestBase):
@@ -21,7 +22,7 @@ class CppDataFormatterTestCase(TestBase):
# Find the line number to break at.
self.line = line_number('main.cpp', '// Set break point at this line.')
- @expectedFailureWindows("llvm.org/pr24462") # Data formatters have problems on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24462: Data formatters have problems on Windows")
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py
index 0f254a67d5a6..2c2e08431175 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-disabling/TestDataFormatterDisabling.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class DataFormatterDisablingTestCase(TestBase):
@@ -21,7 +22,7 @@ class DataFormatterDisablingTestCase(TestBase):
# Find the line number to break at.
self.line = line_number('main.cpp', '// Set break point at this line.')
- @expectedFailureWindows("llvm.org/pr24462") # Data formatters have problems on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24462, Data formatters have problems on Windows")
def test_with_run_command(self):
"""Check that we can properly disable all data formatter categories."""
self.build()
@@ -61,6 +62,8 @@ class DataFormatterDisablingTestCase(TestBase):
self.expect('frame variable string1', matching=False, substrs = ['hello world'])
+ self.expect('type summary list', substrs=['Category: system (disabled)'])
+
self.expect('type category list', substrs = ['system','disabled',])
# now enable and check that we are back to normal
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py
index 94df520d29b3..e9ac79ad08e2 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py
@@ -48,7 +48,9 @@ class NamedSummariesDataFormatterTestCase(TestBase):
self.runCmd("type summary add --summary-string \"First: x=${var.x} y=${var.y} dummy=${var.dummy}\" First")
self.runCmd("type summary add --summary-string \"Second: x=${var.x} y=${var.y%hex}\" Second")
self.runCmd("type summary add --summary-string \"Third: x=${var.x} z=${var.z}\" Third")
-
+
+ self.expect('type summary list', substrs=['AllUseIt'])
+
self.expect("frame variable first",
substrs = ['First: x=12'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
index e12ddca2eea7..d7d4118d1d6a 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
@@ -7,11 +7,12 @@ from __future__ import print_function
+import datetime
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import datetime
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ObjCDataFormatterTestCase(TestBase):
@@ -66,11 +67,6 @@ class ObjCDataFormatterTestCase(TestBase):
"""Test formatters for NSException."""
self.appkit_tester_impl(self.nsexception_data_formatter_commands)
- @skipUnlessDarwin
- def test_nsmisc_with_run_command(self):
- """Test formatters for misc NS classes."""
- self.appkit_tester_impl(self.nsmisc_data_formatter_commands)
-
@skipUnlessDarwin
def test_nsdate_with_run_command(self):
@@ -191,7 +187,7 @@ class ObjCDataFormatterTestCase(TestBase):
def nsnumber_data_formatter_commands(self):
# Now enable AppKit and check we are displaying Cocoa classes correctly
- self.expect('frame variable num1 num2 num3 num4 num5 num6 num7 num8_Y num8_N num9',
+ self.expect('frame variable num1 num2 num3 num4 num5 num6 num7 num9',
substrs = ['(NSNumber *) num1 = ',' (int)5',
'(NSNumber *) num2 = ',' (float)3.1',
'(NSNumber *) num3 = ',' (double)3.14',
@@ -199,13 +195,8 @@ class ObjCDataFormatterTestCase(TestBase):
'(NSNumber *) num5 = ',' (char)65',
'(NSNumber *) num6 = ',' (long)255',
'(NSNumber *) num7 = ','2000000',
- '(NSNumber *) num8_Y = ',' @"1"',
- '(NSNumber *) num8_N = ',' @"0"',
'(NSNumber *) num9 = ',' (short)-31616'])
- self.expect('frame variable decimal_one',
- substrs = ['(NSDecimalNumber *) decimal_one = 0x','1'])
-
self.expect('frame variable num_at1 num_at2 num_at3 num_at4',
substrs = ['(NSNumber *) num_at1 = ',' (int)12',
'(NSNumber *) num_at2 = ',' (int)-12',
@@ -213,26 +204,19 @@ class ObjCDataFormatterTestCase(TestBase):
'(NSNumber *) num_at4 = ',' (double)-12.5'])
def nscontainers_data_formatter_commands(self):
- self.expect('frame variable newArray newDictionary newMutableDictionary cfdict_ref mutable_dict_ref cfarray_ref mutable_array_ref',
+ self.expect('frame variable newArray newDictionary newMutableDictionary cfarray_ref mutable_array_ref',
substrs = ['(NSArray *) newArray = ','@"50 elements"',
'(NSDictionary *) newDictionary = ',' 12 key/value pairs',
'(NSDictionary *) newMutableDictionary = ',' 21 key/value pairs',
- '(CFDictionaryRef) cfdict_ref = ','3 key/value pairs',
- '(CFMutableDictionaryRef) mutable_dict_ref = ','12 key/value pairs',
'(CFArrayRef) cfarray_ref = ','@"3 elements"',
'(CFMutableArrayRef) mutable_array_ref = ','@"11 elements"'])
- self.expect('frame variable nscounted_set',
- substrs = ['(NSCountedSet *) nscounted_set = ','5 elements'])
-
self.expect('frame variable iset1 iset2 imset',
substrs = ['4 indexes','512 indexes','10 indexes'])
- self.expect('frame variable mutable_bag_ref cfbag_ref binheap_ref',
- substrs = ['(CFMutableBagRef) mutable_bag_ref = ','@"17 values"',
- '(CFBagRef) cfbag_ref = ','@"15 values"',
- '(CFBinaryHeapRef) binheap_ref = ','@"21 items"'])
-
+ self.expect('frame variable binheap_ref',
+ substrs = ['(CFBinaryHeapRef) binheap_ref = ','@"21 items"'])
+
self.expect('expression -d run -- [NSArray new]', substrs=['@"0 elements"'])
def nsdata_data_formatter_commands(self):
@@ -258,6 +242,9 @@ class ObjCDataFormatterTestCase(TestBase):
self.expect('frame variable nserror',
substrs = ['domain: @"Foobar" - code: 12'])
+ self.expect('frame variable nserrorptr',
+ substrs = ['domain: @"Foobar" - code: 12'])
+
self.expect('frame variable nserror->_userInfo',
substrs = ['2 key/value pairs'])
@@ -272,24 +259,10 @@ class ObjCDataFormatterTestCase(TestBase):
def nsexception_data_formatter_commands(self):
self.expect('frame variable except0 except1 except2 except3',
- substrs = ['(NSException *) except0 = ','name:@"TheGuyWhoHasNoName" reason:@"cuz it\'s funny"',
- '(NSException *) except1 = ','name:@"TheGuyWhoHasNoName~1" reason:@"cuz it\'s funny"',
- '(NSException *) except2 = ','name:@"TheGuyWhoHasNoName`2" reason:@"cuz it\'s funny"',
- '(NSException *) except3 = ','name:@"TheGuyWhoHasNoName/3" reason:@"cuz it\'s funny"'])
-
- def nsmisc_data_formatter_commands(self):
- self.expect('frame variable localhost',
- substrs = ['<NSHost ','> localhost ((','"127.0.0.1"'])
-
- if self.getArchitecture() in ['i386', 'x86_64']:
- self.expect('frame variable my_task',
- substrs = ['<NS','Task: 0x'])
-
- self.expect('frame variable range_value',
- substrs = ['NSRange: {4, 4}'])
-
- self.expect('frame variable port',
- substrs = ['(NSMachPort *) port = ',' mach port: '])
+ substrs = ['(NSException *) except0 = ','name: @"TheGuyWhoHasNoName" - reason: @"cuz it\'s funny"',
+ '(NSException *) except1 = ','name: @"TheGuyWhoHasNoName~1" - reason: @"cuz it\'s funny"',
+ '(NSException *) except2 = ','name: @"TheGuyWhoHasNoName`2" - reason: @"cuz it\'s funny"',
+ '(NSException *) except3 = ','name: @"TheGuyWhoHasNoName/3" - reason: @"cuz it\'s funny"'])
def nsdate_data_formatter_commands(self):
self.expect('frame variable date1 date2',
@@ -298,16 +271,18 @@ class ObjCDataFormatterTestCase(TestBase):
# this test might fail if we hit the breakpoint late on December 31st of some given year
# and midnight comes between hitting the breakpoint and running this line of code
# hopefully the output will be revealing enough in that case :-)
- now_year = str(datetime.datetime.now().year)
+ now_year = '%s-' % str(datetime.datetime.now().year)
- self.expect('frame variable date3 date4',
- substrs = [now_year,'1970'])
+ self.expect('frame variable date3', substrs = [now_year])
+ self.expect('frame variable date4', substrs = ['1970'])
+ self.expect('frame variable date5', substrs = [now_year])
self.expect('frame variable date1_abs date2_abs',
substrs = ['1985-04','2011-01'])
- self.expect('frame variable date3_abs date4_abs',
- substrs = [now_year,'1970'])
+ self.expect('frame variable date3_abs', substrs = [now_year])
+ self.expect('frame variable date4_abs', substrs = ['1970'])
+ self.expect('frame variable date5_abs', substrs = [now_year])
self.expect('frame variable cupertino home europe',
substrs = ['@"America/Los_Angeles"',
@@ -385,7 +360,6 @@ class ObjCDataFormatterTestCase(TestBase):
self.runCmd('type format clear', check=False)
self.runCmd('type summary clear', check=False)
self.runCmd('type synth clear', check=False)
- self.runCmd('log timers disable', check=False)
# Execute the cleanup function during test case tear down.
@@ -406,7 +380,6 @@ class ObjCDataFormatterTestCase(TestBase):
'(Rect *) rect_ptr = (t=4, l=8, b=4, r=7)',
'(Point) point = (v=7, h=12)',
'(Point *) point_ptr = (v=7, h=12)',
- 'name:@"TheGuyWhoHasNoName" reason:@"cuz it\'s funny"',
'1985',
'foo_selector_impl'];
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/main.m b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/main.m
index 6eb7e021f70b..020e2fc6227a 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/main.m
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/main.m
@@ -415,41 +415,6 @@ int main (int argc, const char * argv[])
CFStringRef cfstring_ref = CFSTR("HELLO WORLD");
-
- CFSetRef set_ref = CFSetCreate(NULL, data_set, 3, NULL);
-
- CFMutableSetRef mutable_set_ref = CFSetCreateMutable(NULL, 5, NULL);
-
- CFSetAddValue(mutable_set_ref, str1);
- CFSetAddValue(mutable_set_ref, str2);
- CFSetAddValue(mutable_set_ref, str3);
- CFSetAddValue(mutable_set_ref, str4);
- CFSetAddValue(mutable_set_ref, str5);
- CFSetAddValue(mutable_set_ref, str6);
- CFSetAddValue(mutable_set_ref, str7);
- CFSetAddValue(mutable_set_ref, str8);
- CFSetAddValue(mutable_set_ref, str9);
- CFSetAddValue(mutable_set_ref, str10);
- CFSetAddValue(mutable_set_ref, str11);
- CFSetAddValue(mutable_set_ref, str12);
-
-
- CFDictionaryRef cfdict_ref = CFDictionaryCreate(NULL, data_set, data_set, 3, NULL, NULL);
- CFMutableDictionaryRef mutable_dict_ref = CFDictionaryCreateMutable(NULL, 16, NULL, NULL);
-
- CFDictionarySetValue(mutable_dict_ref, str1, str1);
- CFDictionarySetValue(mutable_dict_ref, str2, str2);
- CFDictionarySetValue(mutable_dict_ref, str3, str3);
- CFDictionarySetValue(mutable_dict_ref, str4, str1);
- CFDictionarySetValue(mutable_dict_ref, str5, str2);
- CFDictionarySetValue(mutable_dict_ref, str6, str3);
- CFDictionarySetValue(mutable_dict_ref, str7, str1);
- CFDictionarySetValue(mutable_dict_ref, str8, str2);
- CFDictionarySetValue(mutable_dict_ref, str9, str3);
- CFDictionarySetValue(mutable_dict_ref, str10, str1);
- CFDictionarySetValue(mutable_dict_ref, str11, str2);
- CFDictionarySetValue(mutable_dict_ref, str12, str3);
-
CFArrayRef cfarray_ref = CFArrayCreate(NULL, data_set, 3, NULL);
CFMutableArrayRef mutable_array_ref = CFArrayCreateMutable(NULL, 16, NULL);
@@ -466,31 +431,6 @@ int main (int argc, const char * argv[])
CFArraySetValueAtIndex(mutable_array_ref, 9, str11);
CFArraySetValueAtIndex(mutable_array_ref, 10, str12);
- CFMutableBagRef mutable_bag_ref = CFBagCreateMutable(NULL, 15, NULL);
-
- CFBagSetValue(mutable_bag_ref, strB10);
- CFBagSetValue(mutable_bag_ref, str1);
- CFBagSetValue(mutable_bag_ref, str2);
- CFBagSetValue(mutable_bag_ref, str3);
- CFBagSetValue(mutable_bag_ref, str4);
- CFBagSetValue(mutable_bag_ref, str5);
- CFBagSetValue(mutable_bag_ref, str6);
- CFBagSetValue(mutable_bag_ref, str7);
- CFBagSetValue(mutable_bag_ref, str8);
- CFBagSetValue(mutable_bag_ref, str9);
- CFBagSetValue(mutable_bag_ref, str10);
- CFBagSetValue(mutable_bag_ref, str11);
- CFBagSetValue(mutable_bag_ref, str12);
- CFBagSetValue(mutable_bag_ref, strA1);
- CFBagSetValue(mutable_bag_ref, strA2);
- CFBagSetValue(mutable_bag_ref, strA3);
-
- CFBagRef cfbag_ref = CFBagCreateCopy(NULL, mutable_bag_ref);
-
- CFBagSetValue(mutable_bag_ref, strB8);
- CFBagSetValue(mutable_bag_ref, strC4);
-
-
CFBinaryHeapRef binheap_ref = CFBinaryHeapCreate(NULL, 15, &kCFStringBinaryHeapCallBacks, NULL);
CFBinaryHeapAddValue(binheap_ref, str1);
CFBinaryHeapAddValue(binheap_ref, str2);
@@ -520,6 +460,7 @@ int main (int argc, const char * argv[])
NSDictionary *error_userInfo = @{@"a": @1, @"b" : @2};
NSError *nserror = [[NSError alloc] initWithDomain:@"Foobar" code:12 userInfo:error_userInfo];
+ NSError **nserrorptr = &nserror;
NSBundle* bundle_string = [[NSBundle alloc] initWithPath:@"/System/Library/Frameworks/Accelerate.framework"];
NSBundle* bundle_url = [[NSBundle alloc] initWithURL:[[NSURL alloc] initWithString:@"file://localhost/System/Library/Frameworks/Cocoa.framework"]];
@@ -540,8 +481,6 @@ int main (int argc, const char * argv[])
NSException* except2 = [[NSException alloc] initWithName:@"TheGuyWhoHasNoName`2" reason:@"cuz it's funny" userInfo:nil];
NSException* except3 = [[NSException alloc] initWithName:@"TheGuyWhoHasNoName/3" reason:@"cuz it's funny" userInfo:nil];
- NSMachPort *port = [NSMachPort port];
-
NSURL *nsurl = [[NSURL alloc] initWithString:@"http://www.foo.bar"];
NSURL *nsurl2 = [NSURL URLWithString:@"page.html" relativeToURL:nsurl];
NSURL *nsurl3 = [NSURL URLWithString:@"?whatever" relativeToURL:nsurl2];
@@ -550,22 +489,14 @@ int main (int argc, const char * argv[])
NSDate *date2 = [NSDate dateWithNaturalLanguageString:@"12am January 1, 2011"];
NSDate *date3 = [NSDate date];
NSDate *date4 = [NSDate dateWithTimeIntervalSince1970:24*60*60];
+ NSDate *date5 = [NSDate dateWithTimeIntervalSinceReferenceDate: floor([[NSDate date] timeIntervalSinceReferenceDate])];
CFAbsoluteTime date1_abs = CFDateGetAbsoluteTime(date1);
CFAbsoluteTime date2_abs = CFDateGetAbsoluteTime(date2);
CFAbsoluteTime date3_abs = CFDateGetAbsoluteTime(date3);
CFAbsoluteTime date4_abs = CFDateGetAbsoluteTime(date4);
+ CFAbsoluteTime date5_abs = CFDateGetAbsoluteTime(date5);
- NSCountedSet *nscounted_set = [[NSCountedSet alloc] initWithCapacity:5];
-
- [nscounted_set addObject:str0];
- [nscounted_set addObject:str1];
- [nscounted_set addObject:str0];
- [nscounted_set addObject:str0];
- [nscounted_set addObject:@"foo1"];
- [nscounted_set addObject:@"foo2"];
- [nscounted_set addObject:@"foo3"];
-
NSIndexSet *iset1 = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(1, 4)];
NSIndexSet *iset2 = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(1, 512)];
@@ -598,21 +529,12 @@ int main (int argc, const char * argv[])
NSTimeZone *home_ns = [NSTimeZone timeZoneWithName:@"Europe/Rome"];
NSTimeZone *europe_ns = [NSTimeZone timeZoneWithAbbreviation:@"CET"];
- NSHost *localhost = [NSHost hostWithAddress:@"127.0.0.1"];
-
-#ifndef IOS
- NSTask *my_task = [[NSTask alloc] init];
-#endif
-
-
CFGregorianUnits cf_greg_units = {1,3,5,12,5,7};
CFGregorianDate cf_greg_date = CFAbsoluteTimeGetGregorianDate(CFDateGetAbsoluteTime(date1), NULL);
CFRange cf_range = {4,4};
NSPoint ns_point = {4,4};
NSRange ns_range = {4,4};
-
- NSValue *range_value = [NSValue valueWithRange:ns_range];
-
+
NSRect ns_rect = {{1,1},{5,5}};
NSRect* ns_rect_ptr = &ns_rect;
NSRectArray ns_rect_arr = &ns_rect;
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py
index e11c45e9038e..f5c792593772 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-objc/nsstring/TestDataFormatterNSString.py
@@ -8,10 +8,11 @@ from __future__ import print_function
import os, time
+import datetime
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import datetime
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class NSStringDataFormatterTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/TestFormattersOneIsSingular.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/TestFormattersOneIsSingular.py
index 1281f17ab58a..3c9be04a2f6c 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/TestFormattersOneIsSingular.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/TestFormattersOneIsSingular.py
@@ -6,11 +6,12 @@ from __future__ import print_function
+import datetime
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import datetime
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class DataFormatterOneIsSingularTestCase(TestBase):
@@ -64,14 +65,6 @@ class DataFormatterOneIsSingularTestCase(TestBase):
substrs = ['1 key/value pair'])
self.expect('frame variable dict', matching=False,
substrs = ['1 key/value pairs'])
- self.expect('frame variable mutable_bag_ref',
- substrs = ['@"1 value"'])
- self.expect('frame variable mutable_bag_ref', matching=False,
- substrs = ['1 values'])
- self.expect('frame variable nscounted_set',
- substrs = ['1 element'])
- self.expect('frame variable nscounted_set', matching=False,
- substrs = ['1 elements'])
self.expect('frame variable imset',
substrs = ['1 index'])
self.expect('frame variable imset', matching=False,
@@ -80,10 +73,6 @@ class DataFormatterOneIsSingularTestCase(TestBase):
substrs = ['@"1 item"'])
self.expect('frame variable binheap_ref', matching=False,
substrs = ['1 items'])
- self.expect('frame variable nsset',
- substrs = ['1 element'])
- self.expect('frame variable nsset', matching=False,
- substrs = ['1 elements'])
self.expect('frame variable immutableData',
substrs = ['1 byte'])
self.expect('frame variable immutableData', matching=False,
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/main.m b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/main.m
index 7204d3c7b202..71ab8a746bb6 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/main.m
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-proper-plurals/main.m
@@ -11,32 +11,21 @@
int main (int argc, const char * argv[])
{
-
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSArray* key = [NSArray arrayWithObjects:@"foo",nil];
NSArray* value = [NSArray arrayWithObjects:@"key",nil];
NSDictionary *dict = [NSDictionary dictionaryWithObjects:value forKeys:key];
- CFMutableBagRef mutable_bag_ref = CFBagCreateMutable(NULL, 15, NULL);
- CFBagSetValue(mutable_bag_ref, CFSTR("Hello world"));
+ NSMutableIndexSet *imset = [[NSMutableIndexSet alloc] init];
+ [imset addIndex:4];
- NSCountedSet *nscounted_set = [[NSCountedSet alloc] initWithCapacity:5];
- [nscounted_set addObject:@"foo"];
+ CFBinaryHeapRef binheap_ref = CFBinaryHeapCreate(NULL, 15, &kCFStringBinaryHeapCallBacks, NULL);
+ CFBinaryHeapAddValue(binheap_ref, CFSTR("Hello world"));
- NSMutableIndexSet *imset = [[NSMutableIndexSet alloc] init];
- [imset addIndex:4];
+ NSData *immutableData = [[NSData alloc] initWithBytes:"HELLO" length:1];
- CFBinaryHeapRef binheap_ref = CFBinaryHeapCreate(NULL, 15, &kCFStringBinaryHeapCallBacks, NULL);
- CFBinaryHeapAddValue(binheap_ref, CFSTR("Hello world"));
-
- NSSet* nsset = [[NSSet alloc] initWithObjects:@"foo",nil];
-
- NSData *immutableData = [[NSData alloc] initWithBytes:"HELLO" length:1];
-
-
- [pool drain];// Set break point at this line.
- return 0;
+ [pool drain];// Set break point at this line.
+ return 0;
}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
index d202ff5d64e1..c7ff28874c5a 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class PythonSynthDataFormatterTestCase(TestBase):
@@ -43,6 +44,8 @@ class PythonSynthDataFormatterTestCase(TestBase):
self.runCmd("run", RUN_SUCCEEDED)
+ process = self.dbg.GetSelectedTarget().GetProcess()
+
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs = ['stopped',
@@ -61,39 +64,46 @@ class PythonSynthDataFormatterTestCase(TestBase):
# print the f00_1 variable without a synth
self.expect("frame variable f00_1",
- substrs = ['a = 0',
- 'b = 1',
- 'r = 33']);
+ substrs = ['a = 1',
+ 'b = 2',
+ 'r = 34']);
# now set up the synth
self.runCmd("script from fooSynthProvider import *")
self.runCmd("type synth add -l fooSynthProvider foo")
+ self.expect("type synthetic list foo", substrs=['fooSynthProvider'])
+
+ # note that the value of fake_a depends on target byte order
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ fake_a_val = 0x02000000
+ else:
+ fake_a_val = 0x00000100
# check that we get the two real vars and the fake_a variables
self.expect("frame variable f00_1",
- substrs = ['r = 33',
- 'fake_a = 16777216',
- 'a = 0']);
+ substrs = ['r = 34',
+ 'fake_a = %d' % fake_a_val,
+ 'a = 1']);
# check that we do not get the extra vars
self.expect("frame variable f00_1", matching=False,
- substrs = ['b = 1']);
+ substrs = ['b = 2']);
# check access to members by name
self.expect('frame variable f00_1.fake_a',
- substrs = ['16777216'])
+ substrs = ['%d' % fake_a_val])
# check access to members by index
self.expect('frame variable f00_1[1]',
- substrs = ['16777216'])
+ substrs = ['%d' % fake_a_val])
# put synthetic children in summary in several combinations
self.runCmd("type summary add --summary-string \"fake_a=${svar.fake_a}\" foo")
self.expect('frame variable f00_1',
- substrs = ['fake_a=16777216'])
+ substrs = ['fake_a=%d' % fake_a_val])
self.runCmd("type summary add --summary-string \"fake_a=${svar[1]}\" foo")
self.expect('frame variable f00_1',
- substrs = ['fake_a=16777216'])
+ substrs = ['fake_a=%d' % fake_a_val])
# clear the summary
self.runCmd("type summary delete foo")
@@ -101,23 +111,39 @@ class PythonSynthDataFormatterTestCase(TestBase):
# check that the caching does not span beyond the stopoint
self.runCmd("n")
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ fake_a_val = 0x02000000
+ else:
+ fake_a_val = 0x00000200
+
self.expect("frame variable f00_1",
- substrs = ['r = 33',
- 'fake_a = 16777216',
- 'a = 1']);
+ substrs = ['r = 34',
+ 'fake_a = %d' % fake_a_val,
+ 'a = 2']);
# check that altering the object also alters fake_a
self.runCmd("expr f00_1.a = 280")
+
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ fake_a_val = 0x02000001
+ else:
+ fake_a_val = 0x00011800
+
self.expect("frame variable f00_1",
- substrs = ['r = 33',
- 'fake_a = 16777217',
+ substrs = ['r = 34',
+ 'fake_a = %d' % fake_a_val,
'a = 280']);
# check that expanding a pointer does the right thing
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ fake_a_val = 0x0d000000
+ else:
+ fake_a_val = 0x00000c00
+
self.expect("frame variable --ptr-depth 1 f00_ptr",
- substrs = ['r = 45',
- 'fake_a = 218103808',
- 'a = 12'])
+ substrs = ['r = 45',
+ 'fake_a = %d' % fake_a_val,
+ 'a = 12'])
# now add a filter.. it should fail
self.expect("type filter add foo --child b --child j", error=True,
@@ -129,7 +155,7 @@ class PythonSynthDataFormatterTestCase(TestBase):
'j = 17'])
self.expect("frame variable --ptr-depth 1 f00_ptr",
substrs = ['r = 45',
- 'fake_a = 218103808',
+ 'fake_a = %d' % fake_a_val,
'a = 12'])
# now delete the synth and add the filter
@@ -137,11 +163,11 @@ class PythonSynthDataFormatterTestCase(TestBase):
self.runCmd("type filter add foo --child b --child j")
self.expect('frame variable f00_1',
- substrs = ['b = 1',
- 'j = 17'])
+ substrs = ['b = 2',
+ 'j = 18'])
self.expect("frame variable --ptr-depth 1 f00_ptr", matching=False,
substrs = ['r = 45',
- 'fake_a = 218103808',
+ 'fake_a = %d' % fake_a_val,
'a = 12'])
# now add the synth and it should fail
@@ -162,11 +188,11 @@ class PythonSynthDataFormatterTestCase(TestBase):
self.runCmd("type synth add -l fooSynthProvider foo")
self.expect('frame variable f00_1', matching=False,
- substrs = ['b = 1',
- 'j = 17'])
+ substrs = ['b = 2',
+ 'j = 18'])
self.expect("frame variable --ptr-depth 1 f00_ptr",
substrs = ['r = 45',
- 'fake_a = 218103808',
+ 'fake_a = %d' % fake_a_val,
'a = 12'])
# check the listing
@@ -183,8 +209,8 @@ class PythonSynthDataFormatterTestCase(TestBase):
self.expect("frame variable f00_1",
substrs = ['a = 280',
- 'b = 1',
- 'j = 17']);
+ 'b = 2',
+ 'j = 18']);
self.expect("frame variable f00_1", matching=False,
substrs = ['fake_a = '])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
index 48b29dcfd6e4..f45a2abfb9f1 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
@@ -48,7 +48,7 @@ struct wrapint
int main()
{
- foo f00_1(0);
+ foo f00_1(1);
foo *f00_ptr = new foo(12);
f00_1.a++; // Set break point at this line.
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
index 324b372cb11e..7ebc1c14ce13 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
@@ -52,6 +52,7 @@ class ScriptDataFormatterTestCase(TestBase):
script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'Hello from Python, \' + a_val + \' time\'; return str + (\'!\' if a_val == \'1\' else \'s!\');'
self.runCmd("type summary add i_am_cool --python-script \"%s\"" % script)
+ self.expect('type summary list i_am_cool', substrs=[script])
self.expect("frame variable one",
substrs = ['Hello from Python',
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile
index b438bbb970f6..a92cffcc319b 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile
@@ -1,6 +1,7 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
+USE_LIBSTDCPP := 1
# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
# targets. Other targets do not, which causes this test to fail.
@@ -12,8 +13,3 @@ endif
include $(LEVEL)/Makefile.rules
CXXFLAGS += -O0
-
-ifeq (,$(findstring gcc,$(CC)))
-CXXFLAGS += -stdlib=libstdc++
-LDFLAGS += -stdlib=libstdc++
-endif
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py
index 38e700812d05..c186f1465cf5 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py
@@ -8,15 +8,16 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SkipSummaryDataFormatterTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureFreeBSD("llvm.org/pr20548") # fails to build on lab.llvm.org buildbot
- @expectedFailureWindows("llvm.org/pr24462") # Data formatters have problems on Windows
+ @expectedFailureAll(oslist=['freebsd'], bugnumber="llvm.org/pr20548 fails to build on lab.llvm.org buildbot")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24462, Data formatters have problems on Windows")
def test_with_run_command(self):
"""Test data formatter commands."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py
index ca8858dbad9b..b3f8ba7d048e 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py
@@ -8,14 +8,15 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SmartArrayDataFormatterTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr24462") # Data formatters have problems on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24462, Data formatters have problems on Windows")
def test_with_run_command(self):
"""Test data formatter commands."""
self.build()
@@ -35,6 +36,8 @@ class SmartArrayDataFormatterTestCase(TestBase):
self.runCmd("run", RUN_SUCCEEDED)
+ process = self.dbg.GetSelectedTarget().GetProcess()
+
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs = ['stopped',
@@ -310,39 +313,81 @@ class SmartArrayDataFormatterTestCase(TestBase):
self.runCmd("type summary add --summary-string \"arr = ${var%y}\" \"float [7]\"")
self.runCmd("type summary add --summary-string \"arr = ${var%y}\" \"int [5]\"")
- self.expect("frame variable flarr",
- substrs = ['flarr = arr =',
- '00 00 9d 42,00 80 9a 42,00 00 9c 42,00 40 98 42,00 80 99 42,00 c0 99 42,00 00 9a 42'])
-
- self.expect("frame variable other.flarr",
- substrs = ['flarr = arr =',
- '00 00 cc 41,00 00 ca 41,00 00 c9 41,00 00 d6 41,00 00 db 41,00 00 dc 41,00 00 d1 41'])
-
- self.expect("frame variable intarr",
- substrs = ['intarr = arr =',
- '01 00 00 00,01 00 00 00,02 00 00 00,03 00 00 00,05 00 00 00'])
-
- self.expect("frame variable other.intarr",
- substrs = ['intarr = arr = ',
- '09 00 00 00,08 00 00 00,07 00 00 00,06 00 00 00,05 00 00 00'])
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ self.expect("frame variable flarr",
+ substrs = ['flarr = arr =',
+ '00 00 9d 42,00 80 9a 42,00 00 9c 42,00 40 98 42,00 80 99 42,00 c0 99 42,00 00 9a 42'])
+ else:
+ self.expect("frame variable flarr",
+ substrs = ['flarr = arr =',
+ '42 9d 00 00,42 9a 80 00,42 9c 00 00,42 98 40 00,42 99 80 00,42 99 c0 00,42 9a 00 00'])
+
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ self.expect("frame variable other.flarr",
+ substrs = ['flarr = arr =',
+ '00 00 cc 41,00 00 ca 41,00 00 c9 41,00 00 d6 41,00 00 db 41,00 00 dc 41,00 00 d1 41'])
+ else:
+ self.expect("frame variable other.flarr",
+ substrs = ['flarr = arr =',
+ '41 cc 00 00,41 ca 00 00,41 c9 00 00,41 d6 00 00,41 db 00 00,41 dc 00 00,41 d1 00 00'])
+
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ self.expect("frame variable intarr",
+ substrs = ['intarr = arr =',
+ '01 00 00 00,01 00 00 00,02 00 00 00,03 00 00 00,05 00 00 00'])
+ else:
+ self.expect("frame variable intarr",
+ substrs = ['intarr = arr =',
+ '00 00 00 01,00 00 00 01,00 00 00 02,00 00 00 03,00 00 00 05'])
+
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ self.expect("frame variable other.intarr",
+ substrs = ['intarr = arr = ',
+ '09 00 00 00,08 00 00 00,07 00 00 00,06 00 00 00,05 00 00 00'])
+ else:
+ self.expect("frame variable other.intarr",
+ substrs = ['intarr = arr = ',
+ '00 00 00 09,00 00 00 08,00 00 00 07,00 00 00 06,00 00 00 05'])
self.runCmd("type summary add --summary-string \"arr = ${var%Y}\" \"float [7]\"")
self.runCmd("type summary add --summary-string \"arr = ${var%Y}\" \"int [5]\"")
- self.expect("frame variable flarr",
- substrs = ['flarr = arr =',
- '00 00 9d 42 ...B,00 80 9a 42 ...B,00 00 9c 42 ...B,00 40 98 42 .@.B,00 80 99 42 ...B,00 c0 99 42 ...B,00 00 9a 42 ...B'])
-
- self.expect("frame variable other.flarr",
- substrs = ['flarr = arr =',
- '00 00 cc 41 ...A,00 00 ca 41 ...A,00 00 c9 41 ...A,00 00 d6 41 ...A,00 00 db 41 ...A,00 00 dc 41 ...A,00 00 d1 41 ...A'])
-
- self.expect("frame variable intarr",
- substrs = ['intarr = arr =',
- '....,01 00 00 00',
- '....,05 00 00 00'])
-
- self.expect("frame variable other.intarr",
- substrs = ['intarr = arr = ',
- '09 00 00 00',
- '....,07 00 00 00'])
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ self.expect("frame variable flarr",
+ substrs = ['flarr = arr =',
+ '00 00 9d 42 ...B,00 80 9a 42 ...B,00 00 9c 42 ...B,00 40 98 42 .@.B,00 80 99 42 ...B,00 c0 99 42 ...B,00 00 9a 42 ...B'])
+ else:
+ self.expect("frame variable flarr",
+ substrs = ['flarr = arr =',
+ '42 9d 00 00 B...,42 9a 80 00 B...,42 9c 00 00 B...,42 98 40 00 B.@.,42 99 80 00 B...,42 99 c0 00 B...,42 9a 00 00 B...'])
+
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ self.expect("frame variable other.flarr",
+ substrs = ['flarr = arr =',
+ '00 00 cc 41 ...A,00 00 ca 41 ...A,00 00 c9 41 ...A,00 00 d6 41 ...A,00 00 db 41 ...A,00 00 dc 41 ...A,00 00 d1 41 ...A'])
+ else:
+ self.expect("frame variable other.flarr",
+ substrs = ['flarr = arr =',
+ '41 cc 00 00 A...,41 ca 00 00 A...,41 c9 00 00 A...,41 d6 00 00 A...,41 db 00 00 A...,41 dc 00 00 A...,41 d1 00 00 A...'])
+
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ self.expect("frame variable intarr",
+ substrs = ['intarr = arr =',
+ '....,01 00 00 00',
+ '....,05 00 00 00'])
+ else:
+ self.expect("frame variable intarr",
+ substrs = ['intarr = arr =',
+ '....,00 00 00 01',
+ '....,00 00 00 05'])
+
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ self.expect("frame variable other.intarr",
+ substrs = ['intarr = arr = ',
+ '09 00 00 00',
+ '....,07 00 00 00'])
+ else:
+ self.expect("frame variable other.intarr",
+ substrs = ['intarr = arr = ',
+ '00 00 00 09',
+ '....,00 00 00 07'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/Makefile
new file mode 100644
index 000000000000..fdd717119d95
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../../../make
+CXX_SOURCES := main.cpp
+CXXFLAGS += -std=c++11
+USE_LIBCPP := 1
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/TestLibCxxAtomic.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/TestLibCxxAtomic.py
new file mode 100644
index 000000000000..083f713c259d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/TestLibCxxAtomic.py
@@ -0,0 +1,52 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class LibCxxAtomicTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def get_variable(self, name):
+ var = self.frame().FindVariable(name)
+ var.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
+ var.SetPreferSyntheticValue(True)
+ return var
+
+ @skipIf(compiler="gcc")
+ @skipIfWindows # libc++ not ported to Windows yet
+ def test(self):
+ """Test that std::atomic as defined by libc++ is correctly printed by LLDB"""
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line."))
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ lldbutil.skip_if_library_missing(self, self.target(), lldbutil.PrintableRegex("libc\+\+"))
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ s = self.get_variable('s')
+ i = self.get_variable('i')
+
+ if self.TraceOn(): print(s)
+ if self.TraceOn(): print(i)
+
+ self.assertTrue(i.GetValueAsUnsigned(0) == 5, "i == 5")
+ self.assertTrue(s.GetNumChildren() == 2, "s has two children")
+ self.assertTrue(s.GetChildAtIndex(0).GetValueAsUnsigned(0) == 1, "s.x == 1")
+ self.assertTrue(s.GetChildAtIndex(1).GetValueAsUnsigned(0) == 2, "s.y == 2")
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/main.cpp
new file mode 100644
index 000000000000..0eb2418c628a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/main.cpp
@@ -0,0 +1,26 @@
+//===-- main.cpp --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <atomic>
+
+struct S {
+ int x = 1;
+ int y = 2;
+};
+
+int main ()
+{
+ std::atomic<S> s;
+ s.store(S());
+ std::atomic<int> i;
+ i.store(5);
+
+ return 0; // Set break point at this line.
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py
index e01f1b6679fc..d452c1be69bf 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/initializerlist/TestInitializerList.py
@@ -8,16 +8,17 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class InitializerListTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfWindows # libc++ not ported to Windows yet
- @skipIfGcc
- @expectedFailureLinux # fails on clang 3.5 and tot
+ @skipIf(compiler="gcc")
+ @expectedFailureAll(oslist=["linux"], bugnumber="fails on clang 3.5 and tot")
def test(self):
"""Test that that file and class static variables display correctly."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py
index a87a2ed2d434..23f6956cf3f0 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class LibcxxIteratorDataFormatterTestCase(TestBase):
@@ -21,7 +22,7 @@ class LibcxxIteratorDataFormatterTestCase(TestBase):
# Find the line number to break at.
self.line = line_number('main.cpp', '// Set break point at this line.')
- @skipIfGcc
+ @skipIf(compiler="gcc")
@skipIfWindows # libc++ not ported to Windows yet
def test_with_run_command(self):
"""Test that libc++ iterators format properly."""
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py
index 18ee31a86106..6fcdc37465db 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time, re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class LibcxxListDataFormatterTestCase(TestBase):
@@ -24,8 +25,9 @@ class LibcxxListDataFormatterTestCase(TestBase):
self.line3 = line_number('main.cpp', '// Set third break point at this line.')
self.line4 = line_number('main.cpp', '// Set fourth break point at this line.')
- @skipIfGcc
+ @skipIf(compiler="gcc")
@skipIfWindows # libc++ not ported to Windows yet
+ @expectedFailureAll(oslist=["macosx"], bugnumber="rdar://25499635")
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/TestDataFormatterLibcxxListLoop.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/TestDataFormatterLibcxxListLoop.py
index 167cb2b887af..9e68e1dbc004 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/TestDataFormatterLibcxxListLoop.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/TestDataFormatterLibcxxListLoop.py
@@ -9,16 +9,18 @@ from __future__ import print_function
import os, time, re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class LibcxxListDataFormatterTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipIfGcc
+ @skipIf(compiler="gcc")
@skipIfWindows # libc++ not ported to Windows yet
@add_test_categories(["pyapi"])
+ @skipIfDarwin # rdar://25499635
def test_with_run_command(self):
self.build()
exe = os.path.join(os.getcwd(), "a.out")
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py
index 70a98f9c2cae..cecc3178b318 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py
@@ -8,14 +8,15 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class LibcxxMapDataFormatterTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipIfGcc
+ @skipIf(compiler="gcc")
@skipIfWindows # libc++ not ported to Windows yet
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/TestDataFormatterLibccMultiMap.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/TestDataFormatterLibccMultiMap.py
index d0ca73d3251d..eb74818c91f5 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/TestDataFormatterLibccMultiMap.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/TestDataFormatterLibccMultiMap.py
@@ -9,14 +9,16 @@ from __future__ import print_function
import os, time
import lldb
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class LibcxxMultiMapDataFormatterTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfWindows # libc++ not ported to Windows yet
- @skipIfGcc
+ @skipIf(compiler="gcc")
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py
index 384f6130d0c0..cfdfd07ddec1 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py
@@ -8,14 +8,15 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class LibcxxMultiSetDataFormatterTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipIfGcc
+ @skipIf(compiler="gcc")
@skipIfWindows # libc++ not ported to Windows yet
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py
index fcbfb0a8f0ed..00c1e548cf6b 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py
@@ -8,62 +8,63 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class LibcxxSetDataFormatterTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipIfGcc
+ @skipIf(compiler="gcc")
@skipIfWindows # libc++ not ported to Windows yet
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
self.build()
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
- bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line."))
+# bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line."))
self.runCmd("run", RUN_SUCCEEDED)
- lldbutil.skip_if_library_missing(self, self.target(), lldbutil.PrintableRegex("libc\+\+"))
-
- # The stop reason of the thread should be breakpoint.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
- substrs = ['stopped',
- 'stop reason = breakpoint'])
-
- # This is the function to remove the custom formats in order to have a
- # clean slate for the next test case.
- def cleanup():
- self.runCmd('type format clear', check=False)
- self.runCmd('type summary clear', check=False)
- self.runCmd('type filter clear', check=False)
- self.runCmd('type synth clear', check=False)
- self.runCmd("settings set target.max-children-count 256", check=False)
-
- # Execute the cleanup function during test case tear down.
- self.addTearDownHook(cleanup)
-
- self.expect('image list', substrs = self.getLibcPlusPlusLibs())
-
- self.expect("frame variable ii",substrs = ["size=0","{}"])
- lldbutil.continue_to_breakpoint(self.process(), bkpt)
- self.expect("frame variable ii",substrs = ["size=6","[0] = 0","[1] = 1", "[2] = 2", "[3] = 3", "[4] = 4", "[5] = 5"])
- lldbutil.continue_to_breakpoint(self.process(), bkpt)
- self.expect("frame variable ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"])
- self.expect("frame variable ii[2]",substrs = [" = 2"])
- self.expect("p ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"])
- lldbutil.continue_to_breakpoint(self.process(), bkpt)
- self.expect("frame variable ii",substrs = ["size=0","{}"])
- lldbutil.continue_to_breakpoint(self.process(), bkpt)
- self.expect("frame variable ii",substrs = ["size=0","{}"])
- self.expect("frame variable ss",substrs = ["size=0","{}"])
- lldbutil.continue_to_breakpoint(self.process(), bkpt)
- self.expect("frame variable ss",substrs = ["size=2",'[0] = "a"','[1] = "a very long string is right here"'])
- lldbutil.continue_to_breakpoint(self.process(), bkpt)
- self.expect("frame variable ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"'])
- self.expect("p ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"'])
- self.expect("frame variable ss[2]",substrs = [' = "b"'])
- lldbutil.continue_to_breakpoint(self.process(), bkpt)
- self.expect("frame variable ss",substrs = ["size=3",'[0] = "a"','[1] = "a very long string is right here"','[2] = "c"'])
+# lldbutil.skip_if_library_missing(self, self.target(), lldbutil.PrintableRegex("libc\+\+"))
+#
+# # The stop reason of the thread should be breakpoint.
+# self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+# substrs = ['stopped',
+# 'stop reason = breakpoint'])
+#
+# # This is the function to remove the custom formats in order to have a
+# # clean slate for the next test case.
+# def cleanup():
+# self.runCmd('type format clear', check=False)
+# self.runCmd('type summary clear', check=False)
+# self.runCmd('type filter clear', check=False)
+# self.runCmd('type synth clear', check=False)
+# self.runCmd("settings set target.max-children-count 256", check=False)
+#
+# # Execute the cleanup function during test case tear down.
+# self.addTearDownHook(cleanup)
+#
+# self.expect('image list', substrs = self.getLibcPlusPlusLibs())
+#
+# self.expect("frame variable ii",substrs = ["size=0","{}"])
+# lldbutil.continue_to_breakpoint(self.process(), bkpt)
+# self.expect("frame variable ii",substrs = ["size=6","[0] = 0","[1] = 1", "[2] = 2", "[3] = 3", "[4] = 4", "[5] = 5"])
+# lldbutil.continue_to_breakpoint(self.process(), bkpt)
+# self.expect("frame variable ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"])
+# self.expect("frame variable ii[2]",substrs = [" = 2"])
+# self.expect("p ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"])
+# lldbutil.continue_to_breakpoint(self.process(), bkpt)
+# self.expect("frame variable ii",substrs = ["size=0","{}"])
+# lldbutil.continue_to_breakpoint(self.process(), bkpt)
+# self.expect("frame variable ii",substrs = ["size=0","{}"])
+# self.expect("frame variable ss",substrs = ["size=0","{}"])
+# lldbutil.continue_to_breakpoint(self.process(), bkpt)
+# self.expect("frame variable ss",substrs = ["size=2",'[0] = "a"','[1] = "a very long string is right here"'])
+# lldbutil.continue_to_breakpoint(self.process(), bkpt)
+# self.expect("frame variable ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"'])
+# self.expect("p ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"'])
+# self.expect("frame variable ss[2]",substrs = [' = "b"'])
+# lldbutil.continue_to_breakpoint(self.process(), bkpt)
+# self.expect("frame variable ss",substrs = ["size=3",'[0] = "a"','[1] = "a very long string is right here"','[2] = "c"'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py
index 942124255f55..76eedb8c8919 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class LibcxxStringDataFormatterTestCase(TestBase):
@@ -22,7 +23,7 @@ class LibcxxStringDataFormatterTestCase(TestBase):
# Find the line number to break at.
self.line = line_number('main.cpp', '// Set break point at this line.')
- @skipIfGcc
+ @skipIf(compiler="gcc")
@skipIfWindows # libc++ not ported to Windows yet
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py
index 5e6ec2519323..4765cd70f67c 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py
@@ -8,15 +8,16 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class LibcxxUnorderedDataFormatterTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfWindows # libc++ not ported to Windows yet
- @skipIfGcc
+ @skipIf(compiler="gcc")
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
self.build()
@@ -72,4 +73,5 @@ class LibcxxUnorderedDataFormatterTestCase(TestBase):
def look_for_content_and_continue(self, var_name, patterns):
self.expect( ("frame variable %s" % var_name), patterns=patterns)
+ self.expect( ("frame variable %s" % var_name), patterns=patterns)
self.runCmd("continue")
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py
index 9771a819aa6b..fe3b6c115e31 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class LibcxxVBoolDataFormatterTestCase(TestBase):
@@ -21,7 +22,7 @@ class LibcxxVBoolDataFormatterTestCase(TestBase):
# Find the line number to break at.
self.line = line_number('main.cpp', '// Set break point at this line.')
- @skipIfGcc
+ @skipIf(compiler="gcc")
@skipIfWindows # libc++ not ported to Windows.
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py
index f8cd65be0931..9a145fba73e8 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py
@@ -8,14 +8,15 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class LibcxxVectorDataFormatterTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipIfGcc
+ @skipIf(compiler="gcc")
@skipIfWindows # libc++ not ported to Windows yet
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/TestDataFormatterStdIterator.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/TestDataFormatterStdIterator.py
index 6742c9e71701..dbaa37daa2d1 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/TestDataFormatterStdIterator.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/TestDataFormatterStdIterator.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class StdIteratorDataFormatterTestCase(TestBase):
@@ -22,7 +23,7 @@ class StdIteratorDataFormatterTestCase(TestBase):
self.line = line_number('main.cpp', '// Set break point at this line.')
@skipIfWindows # libstdcpp not ported to Windows
- @expectedFailureIcc # llvm.org/pr15301 LLDB prints incorrect sizes of STL containers
+ @expectedFailureAll(compiler="icc", bugnumber="llvm.org/pr15301 LLDB prints incorrect sizes of STL containers")
def test_with_run_command(self):
"""Test that libstdcpp iterators format properly."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py
index 5147d18da0fe..55658af1f2a3 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class StdListDataFormatterTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py
index e21c4e94c2c4..ff99255aec0c 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class StdMapDataFormatterTestCase(TestBase):
@@ -21,7 +22,7 @@ class StdMapDataFormatterTestCase(TestBase):
# Find the line number to break at.
self.line = line_number('main.cpp', '// Set break point at this line.')
- @expectedFailureIcc # llvm.org/pr15301: LLDB prints incorrect size of libstdc++ containers
+ @expectedFailureAll(compiler="icc", bugnumber="llvm.org/pr15301 LLDB prints incorrect sizes of STL containers")
@skipIfWindows # libstdcpp not ported to Windows
@skipIfFreeBSD
def test_with_run_command(self):
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/Makefile
new file mode 100644
index 000000000000..88cb026aba1c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/Makefile
@@ -0,0 +1,15 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+CXXFLAGS := -O0
+USE_LIBSTDCPP := 1
+
+# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
+# targets. Other targets do not, which causes this test to fail.
+# This flag enables FullDebugInfo for all targets.
+ifneq (,$(findstring clang,$(CC)))
+ CFLAGS_EXTRAS += -fno-limit-debug-info
+endif
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py
new file mode 100644
index 000000000000..20b1a3d21156
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py
@@ -0,0 +1,46 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class StdSmartPtrDataFormatterTestCase(TestBase):
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfFreeBSD
+ @skipIfWindows # libstdcpp not ported to Windows
+ @skipIfDarwin # doesn't compile on Darwin
+ def test_with_run_command(self):
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line.")
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ self.expect("frame variable nsp", substrs = ['nsp = nullptr'])
+ self.expect("frame variable isp", substrs = ['isp = 123'])
+ self.expect("frame variable ssp", substrs = ['ssp = "foobar"'])
+
+ self.expect("frame variable nwp", substrs = ['nwp = nullptr'])
+ self.expect("frame variable iwp", substrs = ['iwp = 123'])
+ self.expect("frame variable swp", substrs = ['swp = "foobar"'])
+
+ self.runCmd("continue")
+
+ self.expect("frame variable nsp", substrs = ['nsp = nullptr'])
+ self.expect("frame variable isp", substrs = ['isp = nullptr'])
+ self.expect("frame variable ssp", substrs = ['ssp = nullptr'])
+
+ self.expect("frame variable nwp", substrs = ['nwp = nullptr'])
+ self.expect("frame variable iwp", substrs = ['iwp = nullptr'])
+ self.expect("frame variable swp", substrs = ['swp = nullptr'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/main.cpp
new file mode 100644
index 000000000000..7ba50875a6db
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/main.cpp
@@ -0,0 +1,20 @@
+#include <memory>
+#include <string>
+
+int
+main()
+{
+ std::shared_ptr<char> nsp;
+ std::shared_ptr<int> isp(new int{123});
+ std::shared_ptr<std::string> ssp = std::make_shared<std::string>("foobar");
+
+ std::weak_ptr<char> nwp;
+ std::weak_ptr<int> iwp = isp;
+ std::weak_ptr<std::string> swp = ssp;
+
+ nsp.reset(); // Set break point at this line.
+ isp.reset();
+ ssp.reset();
+
+ return 0; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py
index 2d6af24c6afc..fde2f791183a 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class StdStringDataFormatterTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
index 9e73009aba83..f5cf7c04c3a7 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class StdVBoolDataFormatterTestCase(TestBase):
@@ -21,8 +22,8 @@ class StdVBoolDataFormatterTestCase(TestBase):
# Find the line number to break at.
self.line = line_number('main.cpp', '// Set break point at this line.')
- @expectedFailureFreeBSD("llvm.org/pr20548") # fails to build on lab.llvm.org buildbot
- @expectedFailureIcc # llvm.org/pr15301: lldb does not print the correct sizes of STL containers when building with ICC
+ @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr20548 fails to build on lab.llvm.org buildbot')
+ @expectedFailureAll(compiler="icc", bugnumber="llvm.org/pr15301 LLDB prints incorrect sizes of STL containers")
@skipIfWindows # libstdcpp not ported to Windows.
@skipIfDarwin
def test_with_run_command(self):
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
index ed4313657e93..4a352ef41c17 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class StdVectorDataFormatterTestCase(TestBase):
@@ -22,7 +23,7 @@ class StdVectorDataFormatterTestCase(TestBase):
self.line = line_number('main.cpp', '// Set break point at this line.')
@skipIfFreeBSD
- @expectedFailureIcc # llvm.org/pr15301 LLDB prints incorrect sizes of STL containers
+ @expectedFailureAll(compiler="icc", bugnumber="llvm.org/pr15301 LLDB prints incorrect sizes of STL containers")
@skipIfWindows # libstdcpp not ported to Windows
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/TestDataFormatterSynthType.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/TestDataFormatterSynthType.py
new file mode 100644
index 000000000000..6a03456e5c32
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/TestDataFormatterSynthType.py
@@ -0,0 +1,56 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class DataFormatterSynthTypeTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', 'break here')
+
+ @skipIfFreeBSD # llvm.org/pr20545 bogus output confuses buildbot parser
+ def test_with_run_command(self):
+ """Test using Python synthetic children provider to provide a typename."""
+ self.build()
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type filter clear', check=False)
+ self.runCmd('type synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("script from myIntSynthProvider import *")
+ self.runCmd("type synth add -l myIntSynthProvider myInt")
+
+ self.expect('frame variable x', substrs=['ThisTestPasses'])
+ self.expect('frame variable y', substrs=['ThisTestPasses'])
+ self.expect('frame variable z', substrs=['ThisTestPasses'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/main.cpp
new file mode 100644
index 000000000000..accbf0a5a578
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/main.cpp
@@ -0,0 +1,29 @@
+class myInt {
+ private: int theValue;
+ public: myInt() : theValue(0) {}
+ public: myInt(int _x) : theValue(_x) {}
+ int val() { return theValue; }
+};
+
+class myArray {
+public:
+ int array[16];
+};
+
+class hasAnInt {
+ public:
+ myInt theInt;
+ hasAnInt() : theInt(42) {}
+};
+
+myInt operator + (myInt x, myInt y) { return myInt(x.val() + y.val()); }
+
+int main() {
+ myInt x{3};
+ myInt y{4};
+ myInt z {x+y};
+ hasAnInt hi;
+ myArray ma;
+
+ return z.val(); // break here
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/myIntSynthProvider.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/myIntSynthProvider.py
new file mode 100644
index 000000000000..42737140b112
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthtype/myIntSynthProvider.py
@@ -0,0 +1,36 @@
+class myIntSynthProvider(object):
+ def __init__(self, valobj, dict):
+ self.valobj = valobj;
+ self.val = self.valobj.GetChildMemberWithName("theValue")
+ def num_children(self):
+ return 0;
+ def get_child_at_index(self, index):
+ return None
+ def get_child_index(self, name):
+ return None
+ def update(self):
+ return False
+ def has_children(self):
+ return False
+ def get_type_name(self):
+ return "ThisTestPasses"
+
+
+class myArraySynthProvider(object):
+ def __init__(self, valobj, dict):
+ self.valobj = valobj
+ self.array = self.valobj.GetChildMemberWithName("array")
+
+ def num_children(self, max_count):
+ if 16 < max_count:
+ return 16
+ return max_count
+
+ def get_child_at_index(self, index):
+ return None # Keep it simple when this is not tested here.
+
+ def get_child_index(self, name):
+ return None # Keep it simple when this is not tested here.
+
+ def has_children(self):
+ return True
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py
index 8d6e5df37a5c..e7a34647a6de 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class DataFormatterSynthValueTestCase(TestBase):
@@ -22,7 +23,7 @@ class DataFormatterSynthValueTestCase(TestBase):
self.line = line_number('main.cpp', 'break here')
@skipIfFreeBSD # llvm.org/pr20545 bogus output confuses buildbot parser
- @expectedFailureWindows("llvm.org/pr24462") # Data formatters have problems on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24462, Data formatters have problems on Windows")
def test_with_run_command(self):
"""Test using Python synthetic children provider to provide a value."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/TestDumpDynamic.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/TestDumpDynamic.py
index 8ae09d691940..886d09fda456 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/TestDumpDynamic.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/dump_dynamic/TestDumpDynamic.py
@@ -2,4 +2,4 @@ from __future__ import absolute_import
from lldbsuite.test import lldbinline
-lldbinline.MakeInlineTest(__file__, globals(), [lldbinline.expectedFailureWindows("llvm.org/pr24663")])
+lldbinline.MakeInlineTest(__file__, globals(), [lldbinline.expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24663")])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/TestNSArraySynthetic.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/TestNSArraySynthetic.py
index a12f9c841a7f..871cc19373a4 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/TestNSArraySynthetic.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsarraysynth/TestNSArraySynthetic.py
@@ -6,11 +6,12 @@ from __future__ import print_function
+import datetime
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import datetime
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class NSArraySyntheticTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py
index 13d493ecbdcc..5ee54c3a2952 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py
@@ -6,11 +6,12 @@ from __future__ import print_function
+import datetime
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import datetime
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class NSDictionarySyntheticTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py
index 6c558001bb04..d1680434d3b9 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py
@@ -6,11 +6,12 @@ from __future__ import print_function
+import datetime
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import datetime
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class NSSetSyntheticTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/TestFormattersOsType.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/TestFormattersOsType.py
index 4fb6176e9e4f..4158ec8a661c 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/TestFormattersOsType.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/ostypeformatting/TestFormattersOsType.py
@@ -6,11 +6,12 @@ from __future__ import print_function
+import datetime
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import datetime
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class DataFormatterOSTypeTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/TestPrintArray.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/TestPrintArray.py
new file mode 100644
index 000000000000..700b7418118a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/TestPrintArray.py
@@ -0,0 +1,70 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import datetime
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class PrintArrayTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_print_array(self):
+ """Test that expr -Z works"""
+ self.build()
+ self.printarray_data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', 'break here')
+
+ def printarray_data_formatter_commands(self):
+ """Test that expr -Z works"""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.expect('expr --element-count 3 -- data', substrs=['[0] = 1', '[1] = 3', '[2] = 5'])
+ self.expect('expr data', substrs=['int *', '$', '0x'])
+ self.expect('expr -f binary --element-count 0 -- data', substrs=['int *', '$', '0b'])
+ self.expect('expr -f hex --element-count 3 -- data', substrs=['[0] = 0x', '1', '[1] = 0x', '3', '[2] = 0x', '5'])
+ self.expect('expr -f binary --element-count 2 -- data', substrs=['int *', '$', '0x', '[0] = 0b', '1', '[1] = 0b', '11'])
+ self.expect('parray 3 data', substrs=['[0] = 1', '[1] = 3', '[2] = 5'])
+ self.expect('parray `1 + 1 + 1` data', substrs=['[0] = 1', '[1] = 3', '[2] = 5'])
+ self.expect('parray `data[1]` data', substrs=['[0] = 1', '[1] = 3', '[2] = 5'])
+ self.expect('parray/x 3 data', substrs=['[0] = 0x', '1', '[1] = 0x', '3', '[2] = 0x', '5'])
+ self.expect('parray/x `data[1]` data', substrs=['[0] = 0x', '1', '[1] = 0x', '3', '[2] = 0x', '5'])
+
+ # check error conditions
+ self.expect('expr --element-count 10 -- 123', error=True, substrs=['expression cannot be used with --element-count as it does not refer to a pointer'])
+ self.expect('expr --element-count 10 -- (void*)123', error=True, substrs=['expression cannot be used with --element-count as it refers to a pointer to void'])
+ self.expect('parray data', error=True, substrs=["invalid element count 'data'"])
+ self.expect('parray data data', error=True, substrs=["invalid element count 'data'"])
+ self.expect('parray', error=True, substrs=['Not enough arguments provided'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/main.cpp
new file mode 100644
index 000000000000..b2d6309947ad
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/main.cpp
@@ -0,0 +1,29 @@
+//===-- main.cpp -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <functional>
+#include <stdlib.h>
+
+template<typename ElemType>
+ElemType* alloc(size_t count, std::function<ElemType(size_t)> get)
+{
+ ElemType *elems = new ElemType[count];
+ for(size_t i = 0; i < count; i++)
+ elems[i] = get(i);
+ return elems;
+}
+
+int main (int argc, const char * argv[])
+{
+ int* data = alloc<int>(5, [] (size_t idx) -> int {
+ return 2 * idx + 1;
+ });
+ return 0; // break here
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/Makefile
new file mode 100644
index 000000000000..261658b10ae8
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+OBJCXX_SOURCES := main.mm
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/TestPrintObjectArray.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/TestPrintObjectArray.py
new file mode 100644
index 000000000000..7eb26a569867
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/TestPrintObjectArray.py
@@ -0,0 +1,60 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import datetime
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class PrintObjectArrayTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipUnlessDarwin
+ def test_print_array(self):
+ """Test that expr -O -Z works"""
+ self.build()
+ self.printarray_data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.mm', 'break here')
+
+ def printarray_data_formatter_commands(self):
+ """Test that expr -O -Z works"""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.mm", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.expect('expr --element-count 3 --object-description -- objects', substrs=['3735928559', '4276993775', '3203398366', 'Hello', 'World', 'Two =', '1 ='])
+ self.expect('poarray 3 objects', substrs=['3735928559', '4276993775', '3203398366', 'Hello', 'World', 'Two =', '1 ='])
+ self.expect('expr --element-count 3 --object-description --description-verbosity=full -- objects', substrs=['[0] =', '3735928559', '4276993775', '3203398366', '[1] =', 'Hello', 'World', '[2] =', 'Two =', '1 ='])
+ self.expect('parray 3 objects', substrs=['[0] = 0x', '[1] = 0x', '[2] = 0x'])
+ self.expect('expr --element-count 3 -d run -- objects', substrs=['3 elements', '2 elements', '2 key/value pairs'])
+ self.expect('expr --element-count 3 -d run --ptr-depth=1 -- objects', substrs=['3 elements', '2 elements', '2 key/value pairs', '3735928559', '4276993775', '3203398366', '"Hello"', '"World"'])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/main.mm b/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/main.mm
new file mode 100644
index 000000000000..9ef61e6a73f2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/main.mm
@@ -0,0 +1,30 @@
+//===-- main.cpp -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+struct ThreeObjects
+{
+ id one;
+ id two;
+ id three;
+};
+
+int main()
+{
+ NSArray *array1 = @[@0xDEADBEEF, @0xFEEDBEEF, @0xBEEFFADE];
+ NSArray *array2 = @[@"Hello", @"World"];
+ NSDictionary *dictionary = @{@1: array2, @"Two": array2};
+ ThreeObjects *tobjects = new ThreeObjects();
+ tobjects->one = array1;
+ tobjects->two = array2;
+ tobjects->three = dictionary;
+ id* objects = (id*)tobjects;
+ return 0; // break here
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/TestSetValueFromCString.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/TestSetValueFromCString.py
index 80305e303d03..791ce27dad00 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/TestSetValueFromCString.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/setvaluefromcstring/TestSetValueFromCString.py
@@ -1,4 +1,4 @@
-import lldbsuite.test.lldbinline as lldbinline
-import lldbsuite.test.lldbtest as lldbtest
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
-lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.skipIfFreeBSD,lldbtest.skipIfLinux,lldbtest.skipIfWindows])
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.skipIfFreeBSD,decorators.skipIfLinux,decorators.skipIfWindows])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/TestStringPrinter.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/TestStringPrinter.py
index 69f7d48c8b6c..e26344f2711a 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/TestStringPrinter.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/stringprinter/TestStringPrinter.py
@@ -1,4 +1,4 @@
-import lldbsuite.test.lldbinline as lldbinline
-import lldbsuite.test.lldbtest as lldbtest
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
-lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.expectedFailureWindows("llvm.org/pr24772")])
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24772")])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py
index 0550f57ae62a..e8b6c1ad95f5 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SyntheticCappingTestCase(TestBase):
@@ -30,6 +31,8 @@ class SyntheticCappingTestCase(TestBase):
self.runCmd("run", RUN_SUCCEEDED)
+ process = self.dbg.GetSelectedTarget().GetProcess()
+
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs = ['stopped',
@@ -51,25 +54,31 @@ class SyntheticCappingTestCase(TestBase):
self.runCmd("script from fooSynthProvider import *")
self.runCmd("type synth add -l fooSynthProvider foo")
+ # note that the value of fake_a depends on target byte order
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ fake_a_val = 0x02000000
+ else:
+ fake_a_val = 0x00000100
+
# check that the synthetic children work, so we know we are doing the right thing
self.expect("frame variable f00_1",
- substrs = ['r = 33',
- 'fake_a = 16777216',
- 'a = 0']);
+ substrs = ['r = 34',
+ 'fake_a = %d' % fake_a_val,
+ 'a = 1']);
# check that capping works
self.runCmd("settings set target.max-children-count 2", check=False)
self.expect("frame variable f00_1",
substrs = ['...',
- 'fake_a = 16777216',
- 'a = 0']);
+ 'fake_a = %d' % fake_a_val,
+ 'a = 1']);
self.expect("frame variable f00_1", matching=False,
- substrs = ['r = 33']);
+ substrs = ['r = 34']);
self.runCmd("settings set target.max-children-count 256", check=False)
self.expect("frame variable f00_1", matching=True,
- substrs = ['r = 33']);
+ substrs = ['r = 34']);
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/fooSynthProvider.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/fooSynthProvider.py
index fb95ac2b54d0..1a7e5679c0b8 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/fooSynthProvider.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/fooSynthProvider.py
@@ -1,21 +1,21 @@
import lldb
class fooSynthProvider:
- def __init__(self, valobj, dict):
- self.valobj = valobj;
- self.int_type = valobj.GetType().GetBasicType(lldb.eBasicTypeInt)
- def num_children(self):
- return 3;
- def get_child_at_index(self, index):
- if index == 0:
- child = self.valobj.GetChildMemberWithName('a');
- if index == 1:
- child = self.valobj.CreateChildAtOffset ('fake_a', 1, self.int_type);
- if index == 2:
- child = self.valobj.GetChildMemberWithName('r');
- return child;
- def get_child_index(self, name):
- if name == 'a':
- return 0;
- if name == 'fake_a':
- return 1;
- return 2;
+ def __init__(self, valobj, dict):
+ self.valobj = valobj;
+ self.int_type = valobj.GetType().GetBasicType(lldb.eBasicTypeInt)
+ def num_children(self):
+ return 3;
+ def get_child_at_index(self, index):
+ if index == 0:
+ child = self.valobj.GetChildMemberWithName('a');
+ if index == 1:
+ child = self.valobj.CreateChildAtOffset ('fake_a', 1, self.int_type);
+ if index == 2:
+ child = self.valobj.GetChildMemberWithName('r');
+ return child;
+ def get_child_index(self, name):
+ if name == 'a':
+ return 0;
+ if name == 'fake_a':
+ return 1;
+ return 2;
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp
index b921915b91c5..fec7907e0031 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp
@@ -48,7 +48,7 @@ struct wrapint
int main()
{
- foo f00_1(0);
+ foo f00_1(1);
foo *f00_ptr = new foo(12);
f00_1.a++; // Set break point at this line.
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/TestSyntheticFilterRecompute.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/TestSyntheticFilterRecompute.py
index 6b70a88b9f2c..23a31da685de 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/TestSyntheticFilterRecompute.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthupdate/TestSyntheticFilterRecompute.py
@@ -6,11 +6,12 @@ from __future__ import print_function
+import datetime
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import datetime
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SyntheticFilterRecomputingTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_arg/TestTypeSummaryListArg.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_arg/TestTypeSummaryListArg.py
new file mode 100644
index 000000000000..6568056f761b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_arg/TestTypeSummaryListArg.py
@@ -0,0 +1,31 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TypeSummaryListArgumentTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ @no_debug_info_test
+ def test_type_summary_list_with_arg(self):
+ """Test that the 'type summary list' command handles command line arguments properly"""
+ self.expect('type summary list Foo', substrs=['Category: default', 'Category: system'])
+ self.expect('type summary list char', substrs=['char *', 'unsigned char'])
+
+ self.expect('type summary list -w default', substrs=['system'], matching=False)
+ self.expect('type summary list -w system unsigned', substrs=['default', '0-9'], matching=False)
+ self.expect('type summary list -w system char', substrs=['unsigned char *'], matching=True)
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/TestTypeSummaryListScript.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/TestTypeSummaryListScript.py
new file mode 100644
index 000000000000..63a4a3a4ba8c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/TestTypeSummaryListScript.py
@@ -0,0 +1,61 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TypeSummaryListScriptTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_typesummarylist_script(self):
+ """Test data formatter commands."""
+ self.build()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', 'Break here')
+
+ def data_formatter_commands(self):
+ """Test printing out Python summary formatters."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type category delete TSLSFormatters', check=False)
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type filter clear', check=False)
+ self.runCmd('type synth clear', check=False)
+
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("command script import tslsformatters.py")
+
+ self.expect("frame variable myStruct", substrs=['A data formatter at work'])
+
+ self.expect('type summary list', substrs=['Struct_SummaryFormatter'])
+ self.expect('type summary list Struct', substrs=['Struct_SummaryFormatter'])
+
+
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/main.cpp
new file mode 100644
index 000000000000..2de37041f263
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/main.cpp
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+typedef struct Struct
+{
+ int one;
+ int two;
+} Struct;
+
+int
+main()
+{
+ Struct myStruct = {10, 20};
+ printf ("Break here: %d\n.", myStruct.one);
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/tslsformatters.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/tslsformatters.py
new file mode 100644
index 000000000000..d1ce8b7db17a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/type_summary_list_script/tslsformatters.py
@@ -0,0 +1,10 @@
+import lldb
+
+def Struct_SummaryFormatter(valobj, internal_dict):
+ return 'A data formatter at work'
+
+category = lldb.debugger.CreateCategory("TSLSFormatters")
+category.SetEnabled(True)
+summary = lldb.SBTypeSummary.CreateWithFunctionName("tslsformatters.Struct_SummaryFormatter", lldb.eTypeOptionCascade)
+spec = lldb.SBTypeNameSpecifier("Struct", False)
+category.AddTypeSummary(spec, summary)
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/TestTypedefArray.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/TestTypedefArray.py
index 30b66e062827..41b8c3499ccd 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/TestTypedefArray.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/TestTypedefArray.py
@@ -1,4 +1,4 @@
-import lldbsuite.test.lldbinline as lldbinline
-import lldbsuite.test.lldbtest as lldbtest
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
-lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.expectedFailureGcc])
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.expectedFailureAll(compiler="gcc")])
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py
index 4d060c332f93..f3eced625898 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py
@@ -7,10 +7,11 @@ from __future__ import print_function
import os, time
+import os.path
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
-import os.path
+from lldbsuite.test import lldbutil
class PythonSynthDataFormatterTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py
index 05899a24ad22..365ddff3c7e8 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class VectorTypesFormattingTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/dead-strip/TestDeadStrip.py b/packages/Python/lldbsuite/test/functionalities/dead-strip/TestDeadStrip.py
index f10736bd75c0..efbaa69eef57 100644
--- a/packages/Python/lldbsuite/test/functionalities/dead-strip/TestDeadStrip.py
+++ b/packages/Python/lldbsuite/test/functionalities/dead-strip/TestDeadStrip.py
@@ -8,15 +8,17 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class DeadStripTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr24778")
- @expectedFailureDwo("llvm.org/pr25087")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
+ @expectedFailureAll(debug_info="dwo", bugnumber="llvm.org/pr25087")
+ @expectedFailureAll(oslist=["linux"], debug_info="gmodules", bugnumber="llvm.org/pr27865")
@skipIfFreeBSD # The -dead_strip linker option isn't supported on FreeBSD versions of ld.
def test(self):
"""Test breakpoint works correctly with dead-code stripping."""
diff --git a/packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py b/packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py
index df2308de7605..be0ea1441333 100644
--- a/packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py
+++ b/packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py
@@ -8,14 +8,15 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class DisassemblyTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows # Function name prints fully demangled instead of name-only
+ @expectedFailureAll(oslist=["windows"], bugnumber="function names print fully demangled instead of name-only")
def test(self):
self.build()
exe = os.path.join (os.getcwd(), "a.out")
@@ -41,7 +42,10 @@ class DisassemblyTestCase(TestBase):
instructions = [' add ', ' ldr ', ' str ']
elif re.match("mips" , arch):
breakpoint_opcodes = ["break"]
- instructions = ['lw', 'sw', 'jr']
+ instructions = ['lw', 'sw']
+ elif arch in ["s390x"]:
+ breakpoint_opcodes = [".long"]
+ instructions = [' l ', ' a ', ' st ']
else:
# TODO please add your arch here
self.fail('unimplemented for arch = "{arch}"'.format(arch=self.getArchitecture()))
diff --git a/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py b/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py
index ac039990b5bf..37593768f4a8 100644
--- a/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py
+++ b/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class DynamicValueChildCountTestCase(TestBase):
@@ -31,11 +32,8 @@ class DynamicValueChildCountTestCase(TestBase):
self.main_sixth_call_line = line_number('pass-to-base.cpp',
'// Break here and check b has 0 children again')
- @expectedFailureLinux("llvm.org/pr23039")
- @expectedFailureFreeBSD("llvm.org/pr19311") # continue at a breakpoint does not work
- @expectedFailureWindows("llvm.org/pr24663")
- @expectedFailurei386("to be figured out")
@add_test_categories(['pyapi'])
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24663")
def test_get_dynamic_vals(self):
"""Test fetching C++ dynamic values from pointers & references."""
"""Get argument vals for the call stack when stopped on a breakpoint."""
diff --git a/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py b/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py
index eddaa3cc9840..4b1880dee96f 100644
--- a/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py
+++ b/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py
@@ -6,7 +6,9 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ConvenienceVariablesCase(TestBase):
@@ -20,7 +22,7 @@ class ConvenienceVariablesCase(TestBase):
@skipIfFreeBSD # llvm.org/pr17228
@skipIfRemote
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_with_run_commands(self):
"""Test convenience variables lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py b/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py
index 9321a308a83c..912d51fb6b02 100644
--- a/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py
+++ b/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py
@@ -8,9 +8,10 @@ from __future__ import print_function
import lldb
import os
import time
+from lldbsuite.support import seven
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
-import lldbsuite.support.seven as seven
+from lldbsuite.test import lldbutil
def execute_command (command):
#print('%% %s' % (command))
@@ -55,15 +56,18 @@ class ExecTestCase(TestBase):
self.assertTrue(process.GetState() == lldb.eStateStopped,
STOPPED_DUE_TO_BREAKPOINT)
- thread = process.GetThreadAtIndex (0)
+ threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint)
+ self.assertTrue(len(threads) == 1)
- self.assertTrue (thread.IsValid(),
- "Process stopped at 'main' should have a valid thread");
+ # We had a deadlock tearing down the TypeSystemMap on exec, but only if some
+ # expression had been evaluated. So make sure we do that here so the teardown
+ # is not trivial.
- stop_reason = thread.GetStopReason()
-
- self.assertTrue (stop_reason == lldb.eStopReasonBreakpoint,
- "Thread in process stopped in 'main' should have a stop reason of eStopReasonBreakpoint");
+ thread = threads[0]
+ value = thread.frames[0].EvaluateExpression("1 + 2")
+ self.assertTrue(value.IsValid(), "Expression evaluated successfully")
+ int_value = value.GetValueAsSigned()
+ self.assertTrue(int_value == 3, "Expression got the right result.")
# Run and we should stop due to exec
process.Continue()
@@ -71,15 +75,11 @@ class ExecTestCase(TestBase):
self.assertTrue(process.GetState() == lldb.eStateStopped,
"Process should be stopped at __dyld_start")
- thread = process.GetThreadAtIndex (0)
-
- self.assertTrue (thread.IsValid(),
- "Process stopped at exec should have a valid thread");
-
- stop_reason = thread.GetStopReason()
-
- self.assertTrue (stop_reason == lldb.eStopReasonExec,
- "Thread in process stopped on exec should have a stop reason of eStopReasonExec");
-
+ threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonExec)
+ self.assertTrue(len(threads) == 1, "We got a thread stopped for exec.")
+
# Run and we should stop at breakpoint in main after exec
process.Continue()
+
+ threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint)
+ self.assertTrue(len(threads) == 1, "Stopped at breakpoint in exec'ed process.")
diff --git a/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py b/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py
index a54b45822a6a..1492fe069220 100644
--- a/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py
+++ b/packages/Python/lldbsuite/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ExprDoesntDeadlockTestCase(TestBase):
@@ -19,9 +20,8 @@ class ExprDoesntDeadlockTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureFreeBSD('llvm.org/pr17946')
- @expectedFlakeyLinux # failed 1/365 test runs, line 61, thread.IsValid()
- @expectedFailureWindows # Windows doesn't have pthreads, need to port this test.
+ @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr17946')
+ @expectedFailureAll(oslist=["windows"], bugnumber="Windows doesn't have pthreads, test needs to be ported")
def test_with_run_command(self):
"""Test that expr will time out and allow other threads to run if it blocks."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/fat_archives/TestFatArchives.py b/packages/Python/lldbsuite/test/functionalities/fat_archives/TestFatArchives.py
index 19a2dba2109a..6d2763c1ead1 100644
--- a/packages/Python/lldbsuite/test/functionalities/fat_archives/TestFatArchives.py
+++ b/packages/Python/lldbsuite/test/functionalities/fat_archives/TestFatArchives.py
@@ -8,9 +8,10 @@ from __future__ import print_function
import lldb
import os
import time
-from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
import lldbsuite.support.seven as seven
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
def execute_command (command):
# print('%% %s' % (command))
diff --git a/packages/Python/lldbsuite/test/functionalities/format/TestFormats.py b/packages/Python/lldbsuite/test/functionalities/format/TestFormats.py
index cc962150bc8c..0ba036124b03 100644
--- a/packages/Python/lldbsuite/test/functionalities/format/TestFormats.py
+++ b/packages/Python/lldbsuite/test/functionalities/format/TestFormats.py
@@ -8,13 +8,15 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestFormats(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureHostWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_formats(self):
"""Test format string functionality."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-assert/TestInferiorAssert.py b/packages/Python/lldbsuite/test/functionalities/inferior-assert/TestInferiorAssert.py
index 950b021b69ce..ceeb2eadaf4f 100644
--- a/packages/Python/lldbsuite/test/functionalities/inferior-assert/TestInferiorAssert.py
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-assert/TestInferiorAssert.py
@@ -6,55 +6,56 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
-import lldbsuite.test.lldbplatformutil as lldbplatformutil
+from lldbsuite.test import lldbutil
+from lldbsuite.test import lldbplatformutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
class AssertingInferiorTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
- @expectedFailurei386("llvm.org/pr25338")
- @expectedFailureLinux("llvm.org/pr25338", archs=['arm', 'i386'])
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
+ @expectedFailureAll(oslist=["linux"], archs=["arm"], bugnumber="llvm.org/pr25338")
+ @expectedFailureAll(bugnumber="llvm.org/pr26592", triple = '^mips')
def test_inferior_asserting(self):
"""Test that lldb reliably catches the inferior asserting (command)."""
self.build()
self.inferior_asserting()
- @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
@expectedFailureAndroid(api_levels=list(range(16 + 1))) # b.android.com/179836
def test_inferior_asserting_register(self):
"""Test that lldb reliably reads registers from the inferior after asserting (command)."""
self.build()
self.inferior_asserting_registers()
- @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
- @expectedFailurei386("llvm.org/pr25338")
- @expectedFailureLinux("llvm.org/pr25338", archs=['arm', 'i386'])
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
+ @expectedFailureAll(oslist=["linux"], archs=["aarch64", "arm"], bugnumber="llvm.org/pr25338")
+ @expectedFailureAll(bugnumber="llvm.org/pr26592", triple = '^mips')
def test_inferior_asserting_disassemble(self):
"""Test that lldb reliably disassembles frames after asserting (command)."""
self.build()
self.inferior_asserting_disassemble()
@add_test_categories(['pyapi'])
- @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
def test_inferior_asserting_python(self):
"""Test that lldb reliably catches the inferior asserting (Python API)."""
self.build()
self.inferior_asserting_python()
- @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
- @expectedFailurei386("llvm.org/pr25338")
- @expectedFailureLinux("llvm.org/pr25338", archs=['arm', 'i386'])
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
+ @expectedFailureAll(oslist=["linux"], archs=["aarch64", "arm"], bugnumber="llvm.org/pr25338")
+ @expectedFailureAll(bugnumber="llvm.org/pr26592", triple = '^mips')
def test_inferior_asserting_expr(self):
"""Test that the lldb expression interpreter can read from the inferior after asserting (command)."""
self.build()
self.inferior_asserting_expr()
- @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
- @expectedFailurei386("llvm.org/pr25338")
- @expectedFailureLinux("llvm.org/pr25338", archs=['arm', 'i386'])
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
+ @expectedFailureAll(oslist=["linux"], archs=["aarch64", "arm"], bugnumber="llvm.org/pr25338")
+ @expectedFailureAll(bugnumber="llvm.org/pr26592", triple = '^mips')
def test_inferior_asserting_step(self):
"""Test that lldb functions correctly after stepping through a call to assert()."""
self.build()
@@ -64,7 +65,8 @@ class AssertingInferiorTestCase(TestBase):
lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
def check_stop_reason(self):
- if matchAndroid(api_levels=list(range(1, 16+1)))(self):
+ matched = lldbplatformutil.match_android_device(self.getArchitecture(), valid_api_levels=list(range(1, 16+1)))
+ if matched:
# On android until API-16 the abort() call ended in a sigsegv instead of in a sigabrt
stop_reason = 'stop reason = signal SIGSEGV'
else:
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-changed/TestInferiorChanged.py b/packages/Python/lldbsuite/test/functionalities/inferior-changed/TestInferiorChanged.py
index 830c7f69355f..359846c314f6 100644
--- a/packages/Python/lldbsuite/test/functionalities/inferior-changed/TestInferiorChanged.py
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-changed/TestInferiorChanged.py
@@ -6,15 +6,17 @@ from __future__ import print_function
import os, time
import lldb
-from lldbsuite.test import configuration
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import configuration
+from lldbsuite.test import lldbutil
class ChangedInferiorTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipIfHostWindows
+ @skipIf(hostoslist=["windows"])
+ @no_debug_info_test
def test_inferior_crashing(self):
"""Test lldb reloads the inferior after it was changed during the session."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py
index c547df116c16..fd6a9abce36e 100644
--- a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py
@@ -6,55 +6,56 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
-import lldbsuite.test.lldbplatformutil as lldbplatformutil
+from lldbsuite.test import lldbutil
+from lldbsuite.test import lldbplatformutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
class CrashingInferiorTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureFreeBSD("llvm.org/pr23699 SIGSEGV is reported as exception, not signal")
- @expectedFailureWindows("llvm.org/pr24778") # This actually works, but the test relies on the output format instead of the API
+ @expectedFailureAll(oslist=['freebsd'], bugnumber="llvm.org/pr23699 SIGSEGV is reported as exception, not signal")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API")
def test_inferior_crashing(self):
"""Test that lldb reliably catches the inferior crashing (command)."""
self.build()
self.inferior_crashing()
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API")
def test_inferior_crashing_register(self):
"""Test that lldb reliably reads registers from the inferior after crashing (command)."""
self.build()
self.inferior_crashing_registers()
@add_test_categories(['pyapi'])
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API")
def test_inferior_crashing_python(self):
"""Test that lldb reliably catches the inferior crashing (Python API)."""
self.build()
self.inferior_crashing_python()
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API")
def test_inferior_crashing_expr(self):
"""Test that the lldb expression interpreter can read from the inferior after crashing (command)."""
self.build()
self.inferior_crashing_expr()
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API")
def test_inferior_crashing_step(self):
"""Test that stepping after a crash behaves correctly."""
self.build()
self.inferior_crashing_step()
- @expectedFailureFreeBSD('llvm.org/pr24939')
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr24939')
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API")
@expectedFailureAndroid(archs=['aarch64'], api_levels=list(range(21 + 1))) # No eh_frame for sa_restorer
def test_inferior_crashing_step_after_break(self):
"""Test that lldb functions correctly after stepping through a crash."""
self.build()
self.inferior_crashing_step_after_break()
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API")
@skipIfLinux # Inferior exits after stepping after a segfault. This is working as intended IMHO.
def test_inferior_crashing_expr_step_and_expr(self):
"""Test that lldb expressions work before and after stepping after a crash."""
diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py
index 8afc81f6892a..0d1992d7b4b1 100644
--- a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py
+++ b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py
@@ -6,57 +6,57 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
-import lldbsuite.test.lldbplatformutil as lldbplatformutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbplatformutil
+from lldbsuite.test import lldbutil
class CrashingRecursiveInferiorTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureFreeBSD("llvm.org/pr23699 SIGSEGV is reported as exception, not signal")
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=['freebsd'], bugnumber="llvm.org/pr23699 SIGSEGV is reported as exception, not signal")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_recursive_inferior_crashing(self):
"""Test that lldb reliably catches the inferior crashing (command)."""
self.build()
self.recursive_inferior_crashing()
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_recursive_inferior_crashing_register(self):
"""Test that lldb reliably reads registers from the inferior after crashing (command)."""
self.build()
self.recursive_inferior_crashing_registers()
@add_test_categories(['pyapi'])
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_recursive_inferior_crashing_python(self):
"""Test that lldb reliably catches the inferior crashing (Python API)."""
self.build()
self.recursive_inferior_crashing_python()
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_recursive_inferior_crashing_expr(self):
"""Test that the lldb expression interpreter can read from the inferior after crashing (command)."""
self.build()
self.recursive_inferior_crashing_expr()
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_recursive_inferior_crashing_step(self):
"""Test that stepping after a crash behaves correctly."""
self.build()
self.recursive_inferior_crashing_step()
- @expectedFailureFreeBSD('llvm.org/pr24939')
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr24939')
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
@expectedFailureAndroid(archs=['aarch64'], api_levels=list(range(21 + 1))) # No eh_frame for sa_restorer
def test_recursive_inferior_crashing_step_after_break(self):
"""Test that lldb functions correctly after stepping through a crash."""
self.build()
self.recursive_inferior_crashing_step_after_break()
- @expectedFailureFreeBSD('llvm.org/pr15989') # Couldn't allocate space for the stack frame
@skipIfLinux # Inferior exits after stepping after a segfault. This is working as intended IMHO.
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_recursive_inferior_crashing_expr_step_and_expr(self):
"""Test that lldb expressions work before and after stepping after a crash."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/inline-stepping/TestInlineStepping.py b/packages/Python/lldbsuite/test/functionalities/inline-stepping/TestInlineStepping.py
index 023f6f31e395..8257106888d6 100644
--- a/packages/Python/lldbsuite/test/functionalities/inline-stepping/TestInlineStepping.py
+++ b/packages/Python/lldbsuite/test/functionalities/inline-stepping/TestInlineStepping.py
@@ -6,18 +6,16 @@ from __future__ import print_function
import os, time, sys
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestInlineStepping(TestBase):
mydir = TestBase.compute_mydir(__file__)
@add_test_categories(['pyapi'])
- @expectedFailureFreeBSD('llvm.org/pr17214')
- @expectedFailureIcc # Not really a bug. ICC combines two inlined functions.
- # failed 1/365 dosep runs, (i386-clang), TestInlineStepping.py:237 failed to stop at first breakpoint in main
- @expectedFailureAll(oslist=["linux"], archs=["i386"])
+ @expectedFailureAll(compiler="icc", bugnumber="# Not really a bug. ICC combines two inlined functions.")
def test_with_python_api(self):
"""Test stepping over and into inlined functions."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py b/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py
index c7abf3464412..336260a8e4a3 100644
--- a/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py
+++ b/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py
@@ -2,13 +2,12 @@
from __future__ import print_function
-
-
import unittest2
import os
import lldb
+from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
import re
@@ -16,7 +15,7 @@ class JITLoaderGDBTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipTestIfFn(lambda x: True, "llvm.org/pr24702", "Skipped because the test crashes the test runner")
+ @skipTestIfFn(lambda : "Skipped because the test crashes the test runner", bugnumber="llvm.org/pr24702")
@unittest2.expectedFailure("llvm.org/pr24702")
def test_bogus_values(self):
"""Test that we handle inferior misusing the GDB JIT interface"""
diff --git a/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py
index 8f712dc21110..28d8cccacfcf 100644
--- a/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py
+++ b/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py
@@ -8,16 +8,15 @@ from __future__ import print_function
import lldb
import os
import time
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class LaunchWithShellExpandTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureFreeBSD("llvm.org/pr22627 process launch w/ shell expansion not working")
- @expectedFailureLinux("llvm.org/pr22627 process launch w/ shell expansion not working")
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows", "linux", "freebsd"], bugnumber="llvm.org/pr24778 llvm.org/pr22627")
def test(self):
self.build()
exe = os.path.join (os.getcwd(), "a.out")
@@ -31,7 +30,7 @@ class LaunchWithShellExpandTestCase(TestBase):
breakpoint = target.BreakpointCreateBySourceRegex ('break here', lldb.SBFileSpec ("main.cpp", False))
self.assertTrue(breakpoint, VALID_BREAKPOINT)
- self.runCmd("process launch -X true -w %s -- fi*.tx?" % (os.getcwd()))
+ self.runCmd("process launch -X true -w %s -- fi*.tx? () > <" % (os.getcwd()))
process = self.process()
@@ -52,7 +51,11 @@ class LaunchWithShellExpandTestCase(TestBase):
self.expect("frame variable argv[2]", substrs=['file2.txt'])
self.expect("frame variable argv[3]", substrs=['file3.txt'])
self.expect("frame variable argv[4]", substrs=['file4.txy'])
+ self.expect("frame variable argv[5]", substrs=['()'])
+ self.expect("frame variable argv[6]", substrs=['>'])
+ self.expect("frame variable argv[7]", substrs=['<'])
self.expect("frame variable argv[5]", substrs=['file5.tyx'], matching=False)
+ self.expect("frame variable argv[8]", substrs=['file5.tyx'], matching=False)
self.runCmd("process kill")
diff --git a/packages/Python/lldbsuite/test/functionalities/llvm/TestLLVM.py b/packages/Python/lldbsuite/test/functionalities/llvm/TestLLVM.py
new file mode 100644
index 000000000000..a2a43bf2fabd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/llvm/TestLLVM.py
@@ -0,0 +1,60 @@
+"""
+Test lldb 'commands regex' command which allows the user to create a regular expression command.
+"""
+
+from __future__ import print_function
+
+
+
+import os
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestHomeDirectory(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
+ @no_debug_info_test
+ def test_tilde_home_directory(self):
+ """Test that we can resolve "~/" in paths correctly.
+ When a path starts with "~/", we use llvm::sys::path::home_directory() to
+ resolve the home directory. This currently relies on "HOME" being set in the
+ environment. While this is usually set, we can't rely upon that. We might
+ eventually get a fix into llvm::sys::path::home_directory() so it doesn't rely
+ on having to have an environment variable set, but until then we have work around
+ code in FileSpec::ResolveUsername (llvm::SmallVectorImpl<char> &path) to ensure
+ this always works. This test tests that we get the correct answer for with and
+ without "HOME" being set in the environment."""
+ import pexpect
+ prompt = "(lldb) "
+
+ child = pexpect.spawn('%s --no-use-colors %s' % (lldbtest_config.lldbExec, self.lldbOption))
+ # Turn on logging for what the child sends back.
+ if self.TraceOn():
+ child.logfile_read = sys.stdout
+ # So that the spawned lldb session gets shutdown durng teardown.
+ self.child = child
+
+ # Resolve "~/." to the full path of our home directory + "/."
+ if 'HOME' in os.environ:
+ home_dir = os.environ['HOME']
+ if self.TraceOn():
+ print("home directory is: '%s'" % (home_dir))
+ if os.path.exists(home_dir):
+ home_dir_slash_dot = home_dir + '/.'
+ child.expect_exact(prompt)
+ child.sendline('''script str(lldb.SBFileSpec("~/.", True))''')
+ child.expect_exact(home_dir)
+ child.expect_exact(prompt)
+ child.sendline('''script import os; os.unsetenv('HOME'); str(lldb.SBFileSpec("~/", True))''');
+ child.expect_exact(home_dir)
+ child.expect_exact(prompt)
+ elif self.TraceOn():
+ print('''home directory "%s" doesn't exist, skipping home directory test''' % (home_dir))
+ elif self.TraceOn():
+ print('"HOME" not in environment, skipping home directory test')
+
+ child.sendline('quit')
diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py b/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
index 481e7c887bd0..3a703b2ee04e 100644
--- a/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
+++ b/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
@skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently
class LoadUnloadTestCase(TestBase):
@@ -125,7 +126,6 @@ class LoadUnloadTestCase(TestBase):
substrs = [new_dylib])
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
- @skipUnlessListedRemote(['android'])
@expectedFailureAndroid # wrong source file shows up for hidden library
@skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently
def test_dyld_library_path(self):
@@ -182,7 +182,6 @@ class LoadUnloadTestCase(TestBase):
@expectedFailureAll(bugnumber="llvm.org/pr25805", hostoslist=["windows"], compiler="gcc", archs=["i386"], triple='.*-android')
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
- @skipUnlessListedRemote(['android'])
@skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently
def test_lldb_process_load_and_unload_commands(self):
"""Test that lldb process load/unload command work correctly."""
@@ -241,7 +240,6 @@ class LoadUnloadTestCase(TestBase):
self.runCmd("process continue")
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
- @skipUnlessListedRemote(['android'])
def test_load_unload(self):
"""Test breakpoint by name works correctly with dlopen'ing."""
@@ -283,7 +281,6 @@ class LoadUnloadTestCase(TestBase):
substrs = [' resolved, hit count = 2'])
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
- @skipUnlessListedRemote(['android'])
@skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently
def test_step_over_load (self):
"""Test stepping over code that loads a shared library works correctly."""
@@ -313,7 +310,6 @@ class LoadUnloadTestCase(TestBase):
'stop reason = step over'])
@skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
- @skipUnlessListedRemote(['android'])
@skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently
@unittest2.expectedFailure("llvm.org/pr25806")
def test_static_init_during_load (self):
diff --git a/packages/Python/lldbsuite/test/functionalities/longjmp/TestLongjmp.py b/packages/Python/lldbsuite/test/functionalities/longjmp/TestLongjmp.py
index 1316a01c924c..d9f2b2231895 100644
--- a/packages/Python/lldbsuite/test/functionalities/longjmp/TestLongjmp.py
+++ b/packages/Python/lldbsuite/test/functionalities/longjmp/TestLongjmp.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class LongjmpTestCase(TestBase):
@@ -20,8 +21,8 @@ class LongjmpTestCase(TestBase):
@skipIfDarwin # llvm.org/pr16769: LLDB on Mac OS X dies in function ReadRegisterBytes in GDBRemoteRegisterContext.cpp
@skipIfFreeBSD # llvm.org/pr17214
- @expectedFailureLinux("llvm.org/pr20231")
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr20231")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_step_out(self):
"""Test stepping when the inferior calls setjmp/longjmp, in particular, thread step-out."""
self.build()
@@ -29,8 +30,8 @@ class LongjmpTestCase(TestBase):
@skipIfDarwin # llvm.org/pr16769: LLDB on Mac OS X dies in function ReadRegisterBytes in GDBRemoteRegisterContext.cpp
@skipIfFreeBSD # llvm.org/pr17214
- @expectedFailureLinux("llvm.org/pr20231")
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr20231")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_step_over(self):
"""Test stepping when the inferior calls setjmp/longjmp, in particular, thread step-over a longjmp."""
self.build()
@@ -38,8 +39,8 @@ class LongjmpTestCase(TestBase):
@skipIfDarwin # llvm.org/pr16769: LLDB on Mac OS X dies in function ReadRegisterBytes in GDBRemoteRegisterContext.cpp
@skipIfFreeBSD # llvm.org/pr17214
- @expectedFailureLinux("llvm.org/pr20231")
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr20231")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_step_back_out(self):
"""Test stepping when the inferior calls setjmp/longjmp, in particular, thread step-out after thread step-in."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/memory/cache/Makefile b/packages/Python/lldbsuite/test/functionalities/memory/cache/Makefile
new file mode 100644
index 000000000000..314f1cb2f077
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/memory/cache/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/memory/cache/TestMemoryCache.py b/packages/Python/lldbsuite/test/functionalities/memory/cache/TestMemoryCache.py
new file mode 100644
index 000000000000..a65882d3fa43
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/memory/cache/TestMemoryCache.py
@@ -0,0 +1,64 @@
+"""
+Test the MemoryCache L1 flush.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class MemoryCacheTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ @expectedFlakeyOS(oslist=["windows"])
+ def test_memory_cache(self):
+ """Test the MemoryCache class with a sequence of 'memory read' and 'memory write' operations."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break in main() after the variables are assigned values.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
+
+ # Read a chunk of memory containing &my_ints[0]. The number of bytes read
+ # must be greater than m_L2_cache_line_byte_size to make sure the L1
+ # cache is used.
+ self.runCmd('memory read -f d -c 201 `&my_ints - 100`')
+
+ # Check the value of my_ints[0] is the same as set in main.cpp.
+ line = self.res.GetOutput().splitlines()[100]
+ self.assertTrue(0x00000042 == int(line.split(':')[1], 0))
+
+ # Change the value of my_ints[0] in memory.
+ self.runCmd("memory write -s 4 `&my_ints` AA")
+
+ # Re-read the chunk of memory. The cache line should have been
+ # flushed because of the 'memory write'.
+ self.runCmd('memory read -f d -c 201 `&my_ints - 100`')
+
+ # Check the value of my_ints[0] have been updated correctly.
+ line = self.res.GetOutput().splitlines()[100]
+ self.assertTrue(0x000000AA == int(line.split(':')[1], 0))
diff --git a/packages/Python/lldbsuite/test/functionalities/memory/cache/main.cpp b/packages/Python/lldbsuite/test/functionalities/memory/cache/main.cpp
new file mode 100644
index 000000000000..7f25e2f4bf68
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/memory/cache/main.cpp
@@ -0,0 +1,14 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int main ()
+{
+ int my_ints[] = {0x42};
+ return 0; // Set break point at this line.
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/multidebugger_commands/TestMultipleDebuggersCommands.py b/packages/Python/lldbsuite/test/functionalities/multidebugger_commands/TestMultipleDebuggersCommands.py
new file mode 100644
index 000000000000..7d959ec504c8
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/multidebugger_commands/TestMultipleDebuggersCommands.py
@@ -0,0 +1,48 @@
+"""
+Test that commands do not try and hold on to stale CommandInterpreters in a multiple debuggers scenario
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class MultipleDebuggersCommandsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @no_debug_info_test
+ def test_multipledebuggers_commands(self):
+ """Test that commands do not try and hold on to stale CommandInterpreters in a multiple debuggers scenario"""
+ source_init_files = False
+ magic_text = "The following commands may relate to 'env'"
+
+ debugger_1 = lldb.SBDebugger.Create(source_init_files)
+ interpreter_1 = debugger_1.GetCommandInterpreter()
+
+ retobj = lldb.SBCommandReturnObject()
+ interpreter_1.HandleCommand("apropos env", retobj)
+ self.assertTrue(magic_text in str(retobj), "[interpreter_1]: the output does not contain the correct words")
+
+ if self.TraceOn(): print(str(retobj))
+
+ lldb.SBDebugger.Destroy(debugger_1)
+
+ # now do this again with a different debugger - we shouldn't crash
+
+ debugger_2 = lldb.SBDebugger.Create(source_init_files)
+ interpreter_2 = debugger_2.GetCommandInterpreter()
+
+ retobj = lldb.SBCommandReturnObject()
+ interpreter_2.HandleCommand("apropos env", retobj)
+ self.assertTrue(magic_text in str(retobj), "[interpreter_2]: the output does not contain the correct words")
+
+ if self.TraceOn(): print(str(retobj))
+
+ lldb.SBDebugger.Destroy(debugger_2)
+
diff --git a/packages/Python/lldbsuite/test/functionalities/nested_alias/Makefile b/packages/Python/lldbsuite/test/functionalities/nested_alias/Makefile
new file mode 100644
index 000000000000..8a7102e347af
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/nested_alias/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/nested_alias/TestNestedAlias.py b/packages/Python/lldbsuite/test/functionalities/nested_alias/TestNestedAlias.py
new file mode 100644
index 000000000000..6a74ddb727df
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/nested_alias/TestNestedAlias.py
@@ -0,0 +1,68 @@
+"""
+Test that an alias can reference other aliases without crashing.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import re
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class NestedAliasTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.cpp', '// break here')
+
+ def test_nested_alias(self):
+ """Test that an alias can reference other aliases without crashing."""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break in main() aftre the variables are assigned values.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
+
+ # This is the function to remove the custom aliases in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('command unalias read', check=False)
+ self.runCmd('command unalias rd', check=False)
+ self.runCmd('command unalias fo', check=False)
+ self.runCmd('command unalias foself', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd('command alias read memory read -f A')
+ self.runCmd('command alias rd read -c 3')
+
+ self.expect('memory read -f A -c 3 `&my_ptr[0]`', substrs=['deadbeef', 'main.cpp:', 'feedbeef'])
+ self.expect('rd `&my_ptr[0]`', substrs=['deadbeef', 'main.cpp:', 'feedbeef'])
+
+ self.expect('memory read -f A -c 3 `&my_ptr[0]`', substrs=['deadfeed'], matching=False)
+ self.expect('rd `&my_ptr[0]`', substrs=['deadfeed'], matching=False)
+
+ self.runCmd('command alias fo frame variable -O --')
+ self.runCmd('command alias foself fo self')
+
+ self.expect('help foself', substrs=['--show-all-children', '--raw-output'], matching=False)
+ self.expect('help foself', substrs=['Show variables for the current', 'stack frame.'], matching=True)
diff --git a/packages/Python/lldbsuite/test/functionalities/nested_alias/main.cpp b/packages/Python/lldbsuite/test/functionalities/nested_alias/main.cpp
new file mode 100644
index 000000000000..4424cf30c3a4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/nested_alias/main.cpp
@@ -0,0 +1,22 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+int main (int argc, char const *argv[])
+{
+ void* my_ptr[] = {
+ reinterpret_cast<void*>(0xDEADBEEF),
+ reinterpret_cast<void*>(main),
+ reinterpret_cast<void*>(0xFEEDBEEF),
+ reinterpret_cast<void*>(0xFEEDDEAD),
+ reinterpret_cast<void*>(0xDEADFEED)
+ };
+ return 0; // break here
+}
+
diff --git a/packages/Python/lldbsuite/test/functionalities/object-file/TestImageListMultiArchitecture.py b/packages/Python/lldbsuite/test/functionalities/object-file/TestImageListMultiArchitecture.py
index 4f4a22ed6067..0fdc43bb9feb 100644
--- a/packages/Python/lldbsuite/test/functionalities/object-file/TestImageListMultiArchitecture.py
+++ b/packages/Python/lldbsuite/test/functionalities/object-file/TestImageListMultiArchitecture.py
@@ -9,16 +9,19 @@ from __future__ import print_function
import os.path
+import re
+
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
-import re
+from lldbsuite.test import lldbutil
class TestImageListMultiArchitecture(TestBase):
mydir = TestBase.compute_mydir(__file__)
@no_debug_info_test
+ @skipIfRemote
def test_image_list_shows_multiple_architectures(self):
"""Test that image list properly shows the correct architecture for a set of different architecture object files."""
images = {
diff --git a/packages/Python/lldbsuite/test/functionalities/paths/TestPaths.py b/packages/Python/lldbsuite/test/functionalities/paths/TestPaths.py
index f718b62f95ea..db577dc5bacd 100644
--- a/packages/Python/lldbsuite/test/functionalities/paths/TestPaths.py
+++ b/packages/Python/lldbsuite/test/functionalities/paths/TestPaths.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import lldb
import os
import time
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestPaths(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/platform/TestPlatformCommand.py b/packages/Python/lldbsuite/test/functionalities/platform/TestPlatformCommand.py
index 6b3eedaf603a..9599f83d6a53 100644
--- a/packages/Python/lldbsuite/test/functionalities/platform/TestPlatformCommand.py
+++ b/packages/Python/lldbsuite/test/functionalities/platform/TestPlatformCommand.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class PlatformCommandTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/plugins/commands/TestPluginCommands.py b/packages/Python/lldbsuite/test/functionalities/plugins/commands/TestPluginCommands.py
index b62c30bcf4e7..619ed7afe328 100644
--- a/packages/Python/lldbsuite/test/functionalities/plugins/commands/TestPluginCommands.py
+++ b/packages/Python/lldbsuite/test/functionalities/plugins/commands/TestPluginCommands.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class PluginCommandTestCase(TestBase):
@@ -18,7 +19,7 @@ class PluginCommandTestCase(TestBase):
@skipIfNoSBHeaders
@skipIfHostIncompatibleWithRemote # Requires a compatible arch and platform to link against the host's built lldb lib.
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
@no_debug_info_test
def test_load_plugin(self):
"""Test that plugins that load commands work correctly."""
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
new file mode 100644
index 000000000000..fd5bb00d0565
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
@@ -0,0 +1,164 @@
+"""
+Test basics of linux core file debugging.
+"""
+
+from __future__ import print_function
+
+import shutil
+import struct
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class LinuxCoreTestCase(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ _i386_pid = 32306
+ _x86_64_pid = 32259
+ _s390x_pid = 1045
+
+ _i386_regions = 4
+ _x86_64_regions = 5
+ _s390x_regions = 2
+
+ @skipIf(bugnumber="llvm.org/pr26947")
+ def test_i386(self):
+ """Test that lldb can read the process information from an i386 linux core file."""
+ self.do_test("i386", self._i386_pid, self._i386_regions)
+
+ def test_x86_64(self):
+ """Test that lldb can read the process information from an x86_64 linux core file."""
+ self.do_test("x86_64", self._x86_64_pid, self._x86_64_regions)
+
+ # This seems to hang on non-s390x platforms for some reason. Disabling for now.
+ @skipIf(archs=no_match(['s390x']))
+ def test_s390x(self):
+ """Test that lldb can read the process information from an s390x linux core file."""
+ self.do_test("s390x", self._s390x_pid, self._s390x_regions)
+
+ def test_same_pid_running(self):
+ """Test that we read the information from the core correctly even if we have a running
+ process with the same PID around"""
+ try:
+ shutil.copyfile("x86_64.out", "x86_64-pid.out")
+ shutil.copyfile("x86_64.core", "x86_64-pid.core")
+ with open("x86_64-pid.core", "r+b") as f:
+ # These are offsets into the NT_PRSTATUS and NT_PRPSINFO structures in the note
+ # segment of the core file. If you update the file, these offsets may need updating
+ # as well. (Notes can be viewed with readelf --notes.)
+ for pid_offset in [0x1c4, 0x320]:
+ f.seek(pid_offset)
+ self.assertEqual(struct.unpack("<I", f.read(4))[0], self._x86_64_pid)
+
+ # We insert our own pid, and make sure the test still works.
+ f.seek(pid_offset)
+ f.write(struct.pack("<I", os.getpid()))
+ self.do_test("x86_64-pid", os.getpid(), self._x86_64_regions)
+ finally:
+ self.RemoveTempFile("x86_64-pid.out")
+ self.RemoveTempFile("x86_64-pid.core")
+
+ def test_two_cores_same_pid(self):
+ """Test that we handle the situation if we have two core files with the same PID
+ around"""
+ alttarget = self.dbg.CreateTarget("altmain.out")
+ altprocess = alttarget.LoadCore("altmain.core")
+ self.assertTrue(altprocess, PROCESS_IS_VALID)
+ self.assertEqual(altprocess.GetNumThreads(), 1)
+ self.assertEqual(altprocess.GetProcessID(), self._x86_64_pid)
+
+ altframe = altprocess.GetSelectedThread().GetFrameAtIndex(0)
+ self.assertEqual(altframe.GetFunctionName(), "_start")
+ self.assertEqual(altframe.GetLineEntry().GetLine(), line_number("altmain.c", "Frame _start"))
+
+ error = lldb.SBError()
+ F = altprocess.ReadCStringFromMemory(altframe.FindVariable("F").GetValueAsUnsigned(), 256, error)
+ self.assertTrue(error.Success())
+ self.assertEqual(F, "_start")
+
+ # without destroying this process, run the test which opens another core file with the
+ # same pid
+ self.do_test("x86_64", self._x86_64_pid, self._x86_64_regions)
+
+ def check_memory_regions(self, process, region_count):
+ region_list = process.GetMemoryRegions()
+ self.assertEqual(region_list.GetSize(), region_count)
+
+ region = lldb.SBMemoryRegionInfo()
+
+ # Check we have the right number of regions.
+ self.assertEqual(region_list.GetSize(), region_count);
+
+ # Check that getting a region beyond the last in the list fails.
+ self.assertFalse(region_list.GetMemoryRegionAtIndex(region_count, region));
+
+ # Check each region is valid.
+ for i in range(region_list.GetSize()):
+ # Check we can actually get this region.
+ self.assertTrue(region_list.GetMemoryRegionAtIndex(i, region))
+
+ #Every region in the list should be mapped.
+ self.assertTrue(region.IsMapped())
+
+ # Test the address at the start of a region returns it's enclosing region.
+ begin_address = region.GetRegionBase()
+ region_at_begin = lldb.SBMemoryRegionInfo()
+ error = process.GetMemoryRegionInfo(begin_address, region_at_begin)
+ self.assertEqual(region, region_at_begin)
+
+ # Test an address in the middle of a region returns it's enclosing region.
+ middle_address = (region.GetRegionBase() + region.GetRegionEnd()) / 2l
+ region_at_middle = lldb.SBMemoryRegionInfo()
+ error = process.GetMemoryRegionInfo(middle_address, region_at_middle)
+ self.assertEqual(region, region_at_middle)
+
+ # Test the address at the end of a region returns it's enclosing region.
+ end_address = region.GetRegionEnd() - 1l
+ region_at_end = lldb.SBMemoryRegionInfo()
+ error = process.GetMemoryRegionInfo(end_address, region_at_end)
+ self.assertEqual(region, region_at_end)
+
+ # Check that quering the end address does not return this region but
+ # the next one.
+ next_region = lldb.SBMemoryRegionInfo()
+ error = process.GetMemoryRegionInfo(region.GetRegionEnd(), next_region)
+ self.assertNotEqual(region, next_region)
+ self.assertEqual(region.GetRegionEnd(), next_region.GetRegionBase())
+
+ # Check that query beyond the last region returns an unmapped region
+ # that ends at LLDB_INVALID_ADDRESS
+ last_region = lldb.SBMemoryRegionInfo()
+ region_list.GetMemoryRegionAtIndex(region_count - 1, last_region)
+ end_region = lldb.SBMemoryRegionInfo()
+ error = process.GetMemoryRegionInfo(last_region.GetRegionEnd(), end_region)
+ self.assertFalse(end_region.IsMapped())
+ self.assertEqual(last_region.GetRegionEnd(), end_region.GetRegionBase())
+ self.assertEqual(end_region.GetRegionEnd(), lldb.LLDB_INVALID_ADDRESS)
+
+ def do_test(self, filename, pid, region_count):
+ target = self.dbg.CreateTarget(filename + ".out")
+ process = target.LoadCore(filename + ".core")
+ self.assertTrue(process, PROCESS_IS_VALID)
+ self.assertEqual(process.GetNumThreads(), 1)
+ self.assertEqual(process.GetProcessID(), pid)
+
+ thread = process.GetSelectedThread()
+ self.assertTrue(thread)
+ self.assertEqual(thread.GetThreadID(), pid)
+ backtrace = ["bar", "foo", "_start"]
+ self.assertEqual(thread.GetNumFrames(), len(backtrace))
+ for i in range(len(backtrace)):
+ frame = thread.GetFrameAtIndex(i)
+ self.assertTrue(frame)
+ self.assertEqual(frame.GetFunctionName(), backtrace[i])
+ self.assertEqual(frame.GetLineEntry().GetLine(),
+ line_number("main.c", "Frame " + backtrace[i]))
+ self.assertEqual(frame.FindVariable("F").GetValueAsUnsigned(), ord(backtrace[i][0]))
+
+ self.check_memory_regions(process, region_count)
+
+ self.dbg.DeleteTarget(target)
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.c b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.c
new file mode 100644
index 000000000000..da49a00996e1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.c
@@ -0,0 +1,6 @@
+void _start(void)
+{
+ const char *F = "_start";
+ char *boom = (char *)0;
+ *boom = 47; // Frame _start
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.core b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.core
new file mode 100644
index 000000000000..423413070c7a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.core
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.out b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.out
new file mode 100755
index 000000000000..2fddf3e8f803
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.out
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/i386.core b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/i386.core
new file mode 100644
index 000000000000..f8deff474d1f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/i386.core
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/i386.out b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/i386.out
new file mode 100755
index 000000000000..3cdd4eeca103
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/i386.out
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/main.c b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/main.c
new file mode 100644
index 000000000000..f5bde4171ca5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/main.c
@@ -0,0 +1,17 @@
+static void bar(char *boom)
+{
+ char F = 'b';
+ *boom = 47; // Frame bar
+}
+
+static void foo(char *boom, void (*boomer)(char *))
+{
+ char F = 'f';
+ boomer(boom); // Frame foo
+}
+
+void _start(void)
+{
+ char F = '_';
+ foo(0, bar); // Frame _start
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/make-core.sh b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/make-core.sh
new file mode 100755
index 000000000000..efe1b801df34
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/make-core.sh
@@ -0,0 +1,40 @@
+#! /bin/bash
+
+set -e -x
+
+file=$1
+if [ -z "$file" ]; then
+ cat <<EOF
+Please supply the main source file as the first argument.
+EOF
+ exit 1
+fi
+
+if grep -q '^|' </proc/sys/kernel/core_pattern; then
+ cat <<EOF
+Your system uses a crash report tool ($(cat /proc/sys/kernel/core_pattern)). Core files
+will not be generated. Please reset /proc/sys/kernel/core_pattern (requires root
+privileges) to enable core generation.
+EOF
+ exit 1
+fi
+
+ulimit -c 1000
+real_limit=$(ulimit -c)
+if [ $real_limit -lt 100 ]; then
+ cat <<EOF
+Unable to increase the core file limit. Core file may be truncated!
+To fix this, increase HARD core file limit (ulimit -H -c 1000). This may require root
+privileges.
+EOF
+fi
+
+${CC:-cc} -nostdlib -static -g $CFLAGS "$file" -o a.out
+
+cat <<EOF
+Executable file is in a.out.
+Core file will be saved according to pattern $(cat /proc/sys/kernel/core_pattern).
+EOF
+
+ulimit -s 8 # Decrease stack size to 8k => smaller core files.
+exec ./a.out
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/s390x.core b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/s390x.core
new file mode 100644
index 000000000000..b97fc43e967d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/s390x.core
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/s390x.out b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/s390x.out
new file mode 100755
index 000000000000..640fbdc257d9
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/s390x.out
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/x86_64.core b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/x86_64.core
new file mode 100644
index 000000000000..e2fa69e4558e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/x86_64.core
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/x86_64.out b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/x86_64.out
new file mode 100755
index 000000000000..842402fd519d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/x86_64.out
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py
index 1dda59ac374b..89d1974b6703 100644
--- a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py
@@ -7,8 +7,9 @@ from six import iteritems
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class MiniDumpTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/TestWow64MiniDump.py b/packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/TestWow64MiniDump.py
new file mode 100644
index 000000000000..08debab538f5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/TestWow64MiniDump.py
@@ -0,0 +1,76 @@
+"""
+Test basics of a mini dump taken of a 32-bit process running in WoW64
+
+WoW64 is the subsystem that lets 32-bit processes run in 64-bit Windows. If you
+capture a mini dump of a process running under WoW64 with a 64-bit debugger, you
+end up with a dump of the WoW64 layer. In that case, LLDB must do extra work to
+get the 32-bit register contexts.
+"""
+
+from __future__ import print_function
+from six import iteritems
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class Wow64MiniDumpTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipUnlessWindows # for now mini-dump debugging is limited to Windows hosts
+ @no_debug_info_test
+ def test_wow64_mini_dump(self):
+ """Test that lldb can read the process information from the minidump."""
+ # target create -c fizzbuzz_wow64.dmp
+ target = self.dbg.CreateTarget("")
+ process = target.LoadCore("fizzbuzz_wow64.dmp")
+ self.assertTrue(process, PROCESS_IS_VALID)
+ self.assertEqual(process.GetNumThreads(), 1)
+ self.assertEqual(process.GetProcessID(), 0x1E9C)
+
+ @skipUnlessWindows # for now mini-dump debugging is limited to Windows hosts
+ @no_debug_info_test
+ def test_thread_info_in_wow64_mini_dump(self):
+ """Test that lldb can read the thread information from the minidump."""
+ # target create -c fizzbuzz_wow64.dmp
+ target = self.dbg.CreateTarget("")
+ process = target.LoadCore("fizzbuzz_wow64.dmp")
+ # This process crashed due to an access violation (0xc0000005), but the
+ # minidump doesn't have an exception record--perhaps the crash handler
+ # ate it.
+ # TODO: See if we can recover the exception information from the TEB,
+ # which, according to Windbg, has a pointer to an exception list.
+
+ # In the dump, none of the threads are stopped, so we cannot use
+ # lldbutil.get_stopped_thread.
+ thread = process.GetThreadAtIndex(0)
+ self.assertEqual(thread.GetStopReason(), lldb.eStopReasonNone)
+
+ @skipUnlessWindows # for now mini-dump debugging is limited to Windows hosts
+ @no_debug_info_test
+ def test_stack_info_in_wow64_mini_dump(self):
+ """Test that we can see a trivial stack in a VS-generate mini dump."""
+ # target create -c fizzbuzz_no_heap.dmp
+ target = self.dbg.CreateTarget("")
+ process = target.LoadCore("fizzbuzz_wow64.dmp")
+ self.assertGreaterEqual(process.GetNumThreads(), 1)
+ # This process crashed due to an access violation (0xc0000005), but the
+ # minidump doesn't have an exception record--perhaps the crash handler
+ # ate it.
+ # TODO: See if we can recover the exception information from the TEB,
+ # which, according to Windbg, has a pointer to an exception list.
+
+ # In the dump, none of the threads are stopped, so we cannot use
+ # lldbutil.get_stopped_thread.
+ thread = process.GetThreadAtIndex(0)
+ # The crash is in main, so there should be at least one frame on the stack.
+ self.assertGreaterEqual(thread.GetNumFrames(), 1)
+ frame = thread.GetFrameAtIndex(0)
+ self.assertTrue(frame.IsValid())
+ pc = frame.GetPC()
+ eip = frame.FindRegister("pc")
+ self.assertTrue(eip.IsValid())
+ self.assertEqual(pc, eip.GetValueAsUnsigned())
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/fizzbuzz.cpp b/packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/fizzbuzz.cpp
new file mode 100644
index 000000000000..295d4a1f24db
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/fizzbuzz.cpp
@@ -0,0 +1,31 @@
+// A sample program for getting minidumps on Windows.
+
+#include <iostream>
+
+bool
+fizz(int x)
+{
+ return x % 3 == 0;
+}
+
+bool
+buzz(int x)
+{
+ return x % 5 == 0;
+}
+
+int
+main()
+{
+ int *buggy = 0;
+
+ for (int i = 1; i <= 100; ++i)
+ {
+ if (fizz(i)) std::cout << "fizz";
+ if (buzz(i)) std::cout << "buzz";
+ if (!fizz(i) && !buzz(i)) std::cout << i;
+ std::cout << '\n';
+ }
+
+ return *buggy;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/fizzbuzz_wow64.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/fizzbuzz_wow64.dmp
new file mode 100644
index 000000000000..3d97186f2cd2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/fizzbuzz_wow64.dmp
Binary files differ
diff --git a/packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py b/packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py
index 83906b546300..e4eb302d83d1 100644
--- a/packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py
+++ b/packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
exe_name = "ProcessAttach" # Must match Makefile
diff --git a/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/TestAttachDenied.py b/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/TestAttachDenied.py
index ed9d58f90888..3d1d7fdc7907 100644
--- a/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/TestAttachDenied.py
+++ b/packages/Python/lldbsuite/test/functionalities/process_attach/attach_denied/TestAttachDenied.py
@@ -9,7 +9,9 @@ from __future__ import print_function
import os
import time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
exe_name = 'AttachDenied' # Must match Makefile
@@ -17,12 +19,6 @@ class AttachDeniedTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- def run_platform_command(self, cmd):
- platform = self.dbg.GetSelectedPlatform()
- shell_command = lldb.SBPlatformShellCommand(cmd)
- err = platform.Run(shell_command)
- return (err, shell_command.GetStatus(), shell_command.GetOutput())
-
@skipIfWindows
@skipIfiOSSimulator
def test_attach_to_process_by_id_denied(self):
@@ -39,21 +35,7 @@ class AttachDeniedTestCase(TestBase):
popen = self.spawnSubprocess(exe, [pid_file_path])
self.addTearDownHook(self.cleanupSubprocesses)
- max_attempts = 5
- for i in range(max_attempts):
- err, retcode, msg = self.run_platform_command("ls %s" % pid_file_path)
- if err.Success() and retcode == 0:
- break
- else:
- print(msg)
- if i < max_attempts:
- # Exponential backoff!
- time.sleep(pow(2, i) * 0.25)
- else:
- self.fail("Child PID file %s not found even after %d attempts." % (pid_file_path, max_attempts))
- err, retcode, pid = self.run_platform_command("cat %s" % (pid_file_path))
- self.assertTrue(err.Success() and retcode == 0,
- "Failed to read file %s: %s, retcode: %d" % (pid_file_path, err.GetCString(), retcode))
+ pid = lldbutil.wait_for_file_on_target(self, pid_file_path)
self.expect('process attach -p ' + pid,
startstr = 'error: attach failed:',
diff --git a/packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py b/packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py
index 25be37b2b12d..c20d66aa3ab0 100644
--- a/packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py
+++ b/packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ChangeProcessGroupTestCase(TestBase):
@@ -35,23 +36,7 @@ class ChangeProcessGroupTestCase(TestBase):
popen = self.spawnSubprocess(exe, [pid_file_path])
self.addTearDownHook(self.cleanupSubprocesses)
- max_attempts = 5
- for i in range(max_attempts):
- err, retcode, msg = self.run_platform_command("ls %s" % pid_file_path)
- if err.Success() and retcode == 0:
- break
- else:
- print(msg)
- if i < max_attempts:
- # Exponential backoff!
- time.sleep(pow(2, i) * 0.25)
- else:
- self.fail("Child PID file %s not found even after %d attempts." % (pid_file_path, max_attempts))
-
- err, retcode, pid = self.run_platform_command("cat %s" % (pid_file_path))
-
- self.assertTrue(err.Success() and retcode == 0,
- "Failed to read file %s: %s, retcode: %d" % (pid_file_path, err.GetCString(), retcode))
+ pid = lldbutil.wait_for_file_on_target(self, pid_file_path)
# make sure we cleanup the forked child also
def cleanupChild():
@@ -99,9 +84,3 @@ class ChangeProcessGroupTestCase(TestBase):
# run to completion
process.Continue()
self.assertEqual(process.GetState(), lldb.eStateExited)
-
- def run_platform_command(self, cmd):
- platform = self.dbg.GetSelectedPlatform()
- shell_command = lldb.SBPlatformShellCommand(cmd)
- err = platform.Run(shell_command)
- return (err, shell_command.GetStatus(), shell_command.GetOutput())
diff --git a/packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py b/packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py
index 3131000be428..5998edb3c7e0 100644
--- a/packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py
+++ b/packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py
@@ -4,11 +4,16 @@ Test lldb process launch flags.
from __future__ import print_function
+import copy
+import os
+import time
-
-import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+import six
class ProcessLaunchTestCase(TestBase):
@@ -17,9 +22,11 @@ class ProcessLaunchTestCase(TestBase):
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
- # disable "There is a running process, kill it and restart?" prompt
self.runCmd("settings set auto-confirm true")
- self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
+ def tearDown(self):
+ self.runCmd("settings clear auto-confirm")
+ TestBase.tearDown(self)
@not_remote_testsuite_ready
def test_io (self):
@@ -109,7 +116,7 @@ class ProcessLaunchTestCase(TestBase):
# rdar://problem/9056462
# The process launch flag '-w' for setting the current working directory not working?
@not_remote_testsuite_ready
- @expectedFailureLinux("llvm.org/pr20265")
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr20265")
def test_set_working_dir (self):
"""Test that '-w dir' sets the working dir when running the inferior."""
d = {'CXX_SOURCES' : 'print_cwd.cpp'}
@@ -180,8 +187,9 @@ class ProcessLaunchTestCase(TestBase):
self.fail(err_msg)
def test_environment_with_special_char (self):
- """Test that environment variables containing '*' and '}' are communicated correctly to the lldb-server."""
- d = {'CXX_SOURCES' : 'print_env.cpp'}
+ """Test that environment variables containing '*' and '}' are handled correctly by the inferior."""
+ source = 'print_env.cpp'
+ d = {'CXX_SOURCES' : source}
self.build(dictionary=d)
self.setTearDownCleanup(d)
exe = os.path.join (os.getcwd(), "a.out")
@@ -189,19 +197,19 @@ class ProcessLaunchTestCase(TestBase):
evil_var = 'INIT*MIDDLE}TAIL'
target = self.dbg.CreateTarget(exe)
- process = target.LaunchSimple(None, ['EVIL=' + evil_var], self.get_process_working_directory())
- self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
-
- out = process.GetSTDOUT(len(evil_var))
- self.assertIsNotNone(out, "Encountered an error reading the process's output")
+ main_source_spec = lldb.SBFileSpec(source)
+ breakpoint = target.BreakpointCreateBySourceRegex('// Set breakpoint here.', main_source_spec)
- out = out[:len(evil_var)]
- if out != evil_var:
- self.fail('The environment variable was mis-coded: %s\n' % repr(out))
+ process = target.LaunchSimple(None, ['EVIL=' + evil_var], self.get_process_working_directory())
+ self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
- newline = process.GetSTDOUT(1)
- self.assertIsNotNone(newline, "Encountered an error reading the process's output")
+ threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint)
+ self.assertEqual(len(threads), 1)
+ frame = threads[0].GetFrameAtIndex(0)
+ sbvalue = frame.EvaluateExpression("evil")
+ value = sbvalue.GetSummary().strip('"')
- newline = newline[0]
- if newline != '\r' and newline != '\n':
- self.fail('Garbage at end of environment variable')
+ self.assertEqual(value, evil_var)
+ process.Continue()
+ self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
+ pass
diff --git a/packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp b/packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp
index cbb9b2175916..8c6df8ea01a4 100644
--- a/packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp
@@ -5,7 +5,6 @@
int main (int argc, char **argv)
{
char *evil = getenv("EVIL");
- puts(evil);
- return 0;
+ return 0; // Set breakpoint here.
}
diff --git a/packages/Python/lldbsuite/test/functionalities/process_save_core/TestProcessSaveCore.py b/packages/Python/lldbsuite/test/functionalities/process_save_core/TestProcessSaveCore.py
index 0578bcf44b4c..1c01e2138c2e 100644
--- a/packages/Python/lldbsuite/test/functionalities/process_save_core/TestProcessSaveCore.py
+++ b/packages/Python/lldbsuite/test/functionalities/process_save_core/TestProcessSaveCore.py
@@ -6,7 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ProcessSaveCoreTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/ptr_refs/Makefile b/packages/Python/lldbsuite/test/functionalities/ptr_refs/Makefile
new file mode 100644
index 000000000000..0d70f2595019
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/ptr_refs/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/ptr_refs/TestPtrRefs.py b/packages/Python/lldbsuite/test/functionalities/ptr_refs/TestPtrRefs.py
new file mode 100644
index 000000000000..81db42d8e3c6
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/ptr_refs/TestPtrRefs.py
@@ -0,0 +1,43 @@
+"""
+Test the ptr_refs tool on Darwin
+"""
+
+from __future__ import print_function
+
+import os
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestPtrRefs(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipUnlessDarwin
+ def test_ptr_refs(self):
+ """Test format string functionality."""
+ self.build()
+ exe_name = 'a.out'
+ exe = os.path.join(os.getcwd(), exe_name)
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ main_file_spec = lldb.SBFileSpec ('main.c')
+ breakpoint = target.BreakpointCreateBySourceRegex('break', main_file_spec)
+ self.assertTrue(breakpoint and
+ breakpoint.GetNumLocations() == 1,
+ VALID_BREAKPOINT)
+
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Frame #0 should be on self.line1 and the break condition should hold.
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
+
+ frame = thread.GetFrameAtIndex(0)
+
+ self.dbg.HandleCommand("script import lldb.macosx.heap")
+ self.expect("ptr_refs my_ptr", substrs=["malloc", "stack"]);
diff --git a/packages/Python/lldbsuite/test/functionalities/ptr_refs/main.c b/packages/Python/lldbsuite/test/functionalities/ptr_refs/main.c
new file mode 100644
index 000000000000..4053f9997276
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/ptr_refs/main.c
@@ -0,0 +1,27 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct referent {
+ const char *p;
+};
+
+int main (int argc, char const *argv[])
+{
+ const char *my_ptr = strdup("hello");
+ struct referent *r = malloc(sizeof(struct referent));
+ r->p = my_ptr;
+
+ printf("%p\n", r); // break here
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/register/TestRegisters.py b/packages/Python/lldbsuite/test/functionalities/register/TestRegisters.py
index c5d4650aa371..21de3ab7cc37 100644
--- a/packages/Python/lldbsuite/test/functionalities/register/TestRegisters.py
+++ b/packages/Python/lldbsuite/test/functionalities/register/TestRegisters.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, sys, time
import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class RegisterCommandsTestCase(TestBase):
@@ -25,7 +26,7 @@ class RegisterCommandsTestCase(TestBase):
TestBase.tearDown(self)
@skipIfiOSSimulator
- @skipUnlessArch(['amd64', 'arm', 'i386', 'x86_64'])
+ @skipIf(archs=no_match(['amd64', 'arm', 'i386', 'x86_64']))
def test_register_commands(self):
"""Test commands related to registers, in particular vector registers."""
self.build()
@@ -48,7 +49,7 @@ class RegisterCommandsTestCase(TestBase):
@skipIfiOSSimulator
@skipIfTargetAndroid(archs=["i386"]) # Writing of mxcsr register fails, presumably due to a kernel/hardware problem
- @skipUnlessArch(['amd64', 'arm', 'i386', 'x86_64'])
+ @skipIf(archs=no_match(['amd64', 'arm', 'i386', 'x86_64']))
def test_fp_register_write(self):
"""Test commands that write to registers, in particular floating-point registers."""
self.build()
@@ -57,14 +58,14 @@ class RegisterCommandsTestCase(TestBase):
@skipIfiOSSimulator
@expectedFailureAndroid(archs=["i386"]) # "register read fstat" always return 0xffff
@skipIfFreeBSD #llvm.org/pr25057
- @skipUnlessArch(['amd64', 'i386', 'x86_64'])
+ @skipIf(archs=no_match(['amd64', 'i386', 'x86_64']))
def test_fp_special_purpose_register_read(self):
"""Test commands that read fpu special purpose registers."""
self.build()
self.fp_special_purpose_register_read()
@skipIfiOSSimulator
- @skipUnlessArch(['amd64', 'arm', 'i386', 'x86_64'])
+ @skipIf(archs=no_match(['amd64', 'arm', 'i386', 'x86_64']))
def test_register_expressions(self):
"""Test expression evaluation with commands related to registers."""
self.build()
@@ -85,21 +86,21 @@ class RegisterCommandsTestCase(TestBase):
self.expect("expr -- ($rax & 0xffffffff) == $eax", substrs = ['true'])
@skipIfiOSSimulator
- @skipUnlessArch(['amd64', 'x86_64'])
+ @skipIf(archs=no_match(['amd64', 'x86_64']))
def test_convenience_registers(self):
"""Test convenience registers."""
self.build()
self.convenience_registers()
@skipIfiOSSimulator
- @skipUnlessArch(['amd64', 'x86_64'])
+ @skipIf(archs=no_match(['amd64', 'x86_64']))
def test_convenience_registers_with_process_attach(self):
"""Test convenience registers after a 'process attach'."""
self.build()
self.convenience_registers_with_process_attach(test_16bit_regs=False)
@skipIfiOSSimulator
- @skipUnlessArch(['amd64', 'x86_64'])
+ @skipIf(archs=no_match(['amd64', 'x86_64']))
def test_convenience_registers_16bit_with_process_attach(self):
"""Test convenience registers after a 'process attach'."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/rerun/TestRerun.py b/packages/Python/lldbsuite/test/functionalities/rerun/TestRerun.py
index 0ed56de35699..8636abadd104 100644
--- a/packages/Python/lldbsuite/test/functionalities/rerun/TestRerun.py
+++ b/packages/Python/lldbsuite/test/functionalities/rerun/TestRerun.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import lldb
import os
import time
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestRerun(TestBase):
@@ -31,19 +32,9 @@ class TestRerun(TestBase):
self.runCmd("process launch 1 2 3")
process = self.process()
-
- self.assertTrue(process.GetState() == lldb.eStateStopped,
- STOPPED_DUE_TO_BREAKPOINT)
-
- thread = process.GetThreadAtIndex (0)
-
- self.assertTrue (thread.IsValid(),
- "Process stopped at 'main' should have a valid thread");
-
- stop_reason = thread.GetStopReason()
-
- self.assertTrue (stop_reason == lldb.eStopReasonBreakpoint,
- "Thread in process stopped in 'main' should have a stop reason of eStopReasonBreakpoint");
+ thread = lldbutil.get_one_thread_stopped_at_breakpoint(process, breakpoint)
+ self.assertIsNotNone(thread, "Process should be stopped at a breakpoint in main")
+ self.assertTrue(thread.IsValid(), "Stopped thread is not valid")
self.expect("frame variable argv[1]", substrs=['1'])
self.expect("frame variable argv[2]", substrs=['2'])
@@ -57,19 +48,10 @@ class TestRerun(TestBase):
self.runCmd("process launch")
process = self.process()
-
- self.assertTrue(process.GetState() == lldb.eStateStopped,
- STOPPED_DUE_TO_BREAKPOINT)
-
- thread = process.GetThreadAtIndex (0)
+ thread = lldbutil.get_one_thread_stopped_at_breakpoint(process, breakpoint)
- self.assertTrue (thread.IsValid(),
- "Process stopped at 'main' should have a valid thread");
-
- stop_reason = thread.GetStopReason()
-
- self.assertTrue (stop_reason == lldb.eStopReasonBreakpoint,
- "Thread in process stopped in 'main' should have a stop reason of eStopReasonBreakpoint");
+ self.assertIsNotNone(thread, "Process should be stopped at a breakpoint in main");
+ self.assertTrue(thread.IsValid(), "Stopped thread is not valid")
self.expect("frame variable argv[1]", substrs=['1'])
self.expect("frame variable argv[2]", substrs=['2'])
diff --git a/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py b/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py
index 246eb5c3fdbd..81d93294b5a5 100644
--- a/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py
+++ b/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ReturnValueTestCase(TestBase):
@@ -19,7 +20,7 @@ class ReturnValueTestCase(TestBase):
@expectedFailureAll(oslist=["macosx","freebsd"], archs=["i386"])
@expectedFailureAll(oslist=["linux"], compiler="clang", compiler_version=["<=", "3.6"], archs=["i386"])
@expectedFailureAll(bugnumber="llvm.org/pr25785", hostoslist=["windows"], compiler="gcc", archs=["i386"], triple='.*-android')
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
@add_test_categories(['pyapi'])
def test_with_python(self):
"""Test getting return values from stepping out."""
diff --git a/packages/Python/lldbsuite/test/functionalities/set-data/TestSetData.py b/packages/Python/lldbsuite/test/functionalities/set-data/TestSetData.py
index 3acad5f87be0..294aa6725155 100644
--- a/packages/Python/lldbsuite/test/functionalities/set-data/TestSetData.py
+++ b/packages/Python/lldbsuite/test/functionalities/set-data/TestSetData.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SetDataTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/signal/TestSendSignal.py b/packages/Python/lldbsuite/test/functionalities/signal/TestSendSignal.py
index 971b82a7c75d..1da4d701a590 100644
--- a/packages/Python/lldbsuite/test/functionalities/signal/TestSendSignal.py
+++ b/packages/Python/lldbsuite/test/functionalities/signal/TestSendSignal.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time, signal
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SendSignalTestCase(TestBase):
@@ -20,7 +21,7 @@ class SendSignalTestCase(TestBase):
# Find the line number to break inside main().
self.line = line_number('main.c', 'Put breakpoint here')
- @expectedFailureFreeBSD("llvm.org/pr23318: does not report running state")
+ @expectedFailureAll(oslist=['freebsd'], bugnumber="llvm.org/pr23318: does not report running state")
@skipIfWindows # Windows does not support signals
def test_with_run_command(self):
"""Test that lldb command 'process signal SIGUSR1' sends a signal to the inferior process."""
diff --git a/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/TestHandleSegv.py b/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/TestHandleSegv.py
index feed5bfb3c76..d8dbb7f68936 100644
--- a/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/TestHandleSegv.py
+++ b/packages/Python/lldbsuite/test/functionalities/signal/handle-segv/TestHandleSegv.py
@@ -5,10 +5,12 @@ from __future__ import print_function
import os
+import re
+
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
-import re
+from lldbsuite.test import lldbutil
class HandleSegvTestCase(TestBase):
@@ -17,7 +19,7 @@ class HandleSegvTestCase(TestBase):
@skipIfWindows # signals do not exist on Windows
@skipIfDarwin
- @expectedFailureFreeBSD("llvm.org/pr23699 SIGSEGV is reported as exception, not signal")
+ @expectedFailureAll(oslist=['freebsd'], bugnumber="llvm.org/pr23699 SIGSEGV is reported as exception, not signal")
def test_inferior_handle_sigsegv(self):
self.build()
exe = os.path.join(os.getcwd(), "a.out")
diff --git a/packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py b/packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py
index 39e7753397d1..2c30f69d7b20 100644
--- a/packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py
+++ b/packages/Python/lldbsuite/test/functionalities/signal/raise/TestRaise.py
@@ -6,9 +6,11 @@ from __future__ import print_function
import os
import lldb
-from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
import re
+from lldbsuite.test.lldbplatformutil import getDarwinOSTriples
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
@skipIfWindows # signals do not exist on Windows
@@ -148,8 +150,7 @@ class RaiseTestCase(TestBase):
# reset signal handling to default
self.set_handle(signal, default_pass, default_stop, default_notify)
- @expectedFailureLinux("llvm.org/pr24530") # the signal the inferior generates gets lost
- @expectedFailureDarwin("llvm.org/pr24530") # the signal the inferior generates gets lost
+ @expectedFailureAll(oslist=["linux"]+getDarwinOSTriples(), bugnumber="llvm.org/pr20231")
def test_restart_bug(self):
"""Test that we catch a signal in the edge case where the process receives it while we are
about to interrupt it"""
diff --git a/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py b/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py
index 6a2dd74d3956..6f5882636cb6 100644
--- a/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py
+++ b/packages/Python/lldbsuite/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class SingleQuoteInCommandLineTestCase(TestBase):
@@ -25,7 +27,7 @@ class SingleQuoteInCommandLineTestCase(TestBase):
except:
pass
- @expectedFailureHostWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@no_debug_info_test
def test_lldb_invocation_with_single_quote_in_filename(self):
"""Test that 'lldb my_file_name' works where my_file_name is a string with a single quote char in it."""
diff --git a/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py b/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py
index 6c1f2c3da41b..8b9c91217de4 100644
--- a/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py
+++ b/packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py
@@ -8,10 +8,12 @@ from __future__ import print_function
import os
import re
-import lldb
-import lldbsuite.test.lldbutil as lldbutil
import sys
+
+import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ReturnValueTestCase(TestBase):
@@ -25,7 +27,8 @@ class ReturnValueTestCase(TestBase):
self.do_step_out_past_nodebug()
@add_test_categories(['pyapi'])
- @expectedFailureGcc("llvm.org/pr19247")
+ @decorators.expectedFailureAll(compiler="gcc", bugnumber="llvm.org/pr28549")
+ @decorators.expectedFailureAll(compiler="clang", compiler_version=[">=", "3.9"], archs=["i386"], bugnumber="llvm.org/pr28549")
def test_step_over_with_python(self):
"""Test stepping over using avoid-no-debug with dwarf."""
self.build()
@@ -33,7 +36,8 @@ class ReturnValueTestCase(TestBase):
self.do_step_over_past_nodebug()
@add_test_categories(['pyapi'])
- @expectedFailureGcc("llvm.org/pr19247")
+ @decorators.expectedFailureAll(compiler="gcc", bugnumber="llvm.org/pr28549")
+ @decorators.expectedFailureAll(compiler="clang", compiler_version=[">=", "3.9"], archs=["i386"], bugnumber="llvm.org/pr28549")
def test_step_in_with_python(self):
"""Test stepping in using avoid-no-debug with dwarf."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py b/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py
index 753491339c4c..93f846a06870 100644
--- a/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py
+++ b/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class StopHookCmdTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py b/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py
index 7785d85772e2..c42c1e563881 100644
--- a/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py
+++ b/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py
@@ -8,8 +8,10 @@ from __future__ import print_function
import os
import lldb
-from lldbsuite.test import configuration
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import configuration
+from lldbsuite.test import lldbutil
class StopHookMechanismTestCase(TestBase):
@@ -26,7 +28,7 @@ class StopHookMechanismTestCase(TestBase):
@skipIfFreeBSD # llvm.org/pr15037
@expectedFlakeyLinux('llvm.org/pr15037') # stop-hooks sometimes fail to fire on Linux
- @expectedFailureHostWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test(self):
"""Test the stop-hook mechanism."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py b/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py
index c7fb53d495e6..57395832dc21 100644
--- a/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py
+++ b/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py
@@ -8,8 +8,10 @@ from __future__ import print_function
import os, time
import lldb
-from lldbsuite.test import configuration
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import configuration
+from lldbsuite.test import lldbutil
class StopHookForMultipleThreadsTestCase(TestBase):
@@ -29,7 +31,7 @@ class StopHookForMultipleThreadsTestCase(TestBase):
@expectedFlakeyFreeBSD("llvm.org/pr15037")
@expectedFlakeyLinux("llvm.org/pr15037") # stop hooks sometimes fail to fire on Linux
- @expectedFailureHostWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
def test_stop_hook_multiple_threads(self):
"""Test that lldb stop-hook works for multiple threads."""
self.build(dictionary=self.d)
diff --git a/packages/Python/lldbsuite/test/functionalities/target_command/TestTargetCommand.py b/packages/Python/lldbsuite/test/functionalities/target_command/TestTargetCommand.py
index 0ab965d2aa16..126f6e4dab80 100644
--- a/packages/Python/lldbsuite/test/functionalities/target_command/TestTargetCommand.py
+++ b/packages/Python/lldbsuite/test/functionalities/target_command/TestTargetCommand.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import lldb
import sys
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class targetCommandTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py
index 91bc68577a43..902adacb2abd 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py
@@ -5,8 +5,9 @@ Test regression for Bug 25251.
import os, time
import unittest2
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class BreakpointAfterJoinTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/TestBreakAfterJoin.py b/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/TestBreakAfterJoin.py
index 43397a122391..8ef0fb0a000d 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/TestBreakAfterJoin.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/TestBreakAfterJoin.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class BreakpointAfterJoinTestCase(TestBase):
@@ -21,9 +22,9 @@ class BreakpointAfterJoinTestCase(TestBase):
# Find the line number for our breakpoint.
self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
- @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
- @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=lldbplatformutil.getDarwinOSTriples(), bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr18190 thread states not properly maintained")
def test(self):
"""Test breakpoint handling after a thread join."""
self.build(dictionary=self.getBuildFlags())
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/main.cpp
index a63079524ee2..f9f33fda82bb 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/main.cpp
@@ -19,24 +19,12 @@
volatile int g_test = 0;
-// Note that although hogging the CPU while waiting for a variable to change
-// would be terrible in production code, it's great for testing since it
-// avoids a lot of messy context switching to get multiple threads synchronized.
-#define do_nothing()
-
-#define pseudo_barrier_wait(bar) \
- --bar; \
- while (bar > 0) \
- do_nothing();
-
-#define pseudo_barrier_init(bar, count) (bar = count)
-
// A barrier to synchronize all the threads.
-std::atomic_int g_barrier1;
+pseudo_barrier_t g_barrier1;
// A barrier to keep the threads from exiting until after the breakpoint has
// been passed.
-std::atomic_int g_barrier2;
+pseudo_barrier_t g_barrier2;
void *
break_thread_func ()
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py b/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py
index 9eb25b68765a..30adcccd203f 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py
@@ -17,11 +17,11 @@ from __future__ import print_function
import unittest2
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
@skipIfWindows
-@expectedFailureAll(archs=['mips64', 'mips64el']) # Atomic sequences are not supported yet for MIPS in LLDB.
class ConcurrentEventsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@@ -30,24 +30,28 @@ class ConcurrentEventsTestCase(TestBase):
## Tests for multiple threads that generate a single event.
#
@unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_many_breakpoints(self):
"""Test 100 breakpoints from 100 threads."""
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_breakpoint_threads=100)
@unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_many_watchpoints(self):
"""Test 100 watchpoints from 100 threads."""
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_watchpoint_threads=100)
@unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_many_signals(self):
"""Test 100 signals from 100 threads."""
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_signal_threads=100)
@unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_many_crash(self):
"""Test 100 threads that cause a segfault."""
self.build(dictionary=self.getBuildFlags())
@@ -58,18 +62,21 @@ class ConcurrentEventsTestCase(TestBase):
## Tests for concurrent signal and breakpoint
#
@skipIfFreeBSD # timing out on buildbot
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_signal_break(self):
"""Test signal and a breakpoint in multiple threads."""
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_breakpoint_threads=1, num_signal_threads=1)
@skipIfFreeBSD # timing out on buildbot
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_delay_signal_break(self):
"""Test (1-second delay) signal and a breakpoint in multiple threads."""
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_breakpoint_threads=1, num_delay_signal_threads=1)
@skipIfFreeBSD # timing out on buildbot
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_signal_delay_break(self):
"""Test signal and a (1 second delay) breakpoint in multiple threads."""
self.build(dictionary=self.getBuildFlags())
@@ -81,6 +88,7 @@ class ConcurrentEventsTestCase(TestBase):
#
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_watch_break(self):
"""Test watchpoint and a breakpoint in multiple threads."""
self.build(dictionary=self.getBuildFlags())
@@ -88,6 +96,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_delay_watch_break(self):
"""Test (1-second delay) watchpoint and a breakpoint in multiple threads."""
self.build(dictionary=self.getBuildFlags())
@@ -95,6 +104,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_watch_break_delay(self):
"""Test watchpoint and a (1 second delay) breakpoint in multiple threads."""
self.build(dictionary=self.getBuildFlags())
@@ -105,6 +115,7 @@ class ConcurrentEventsTestCase(TestBase):
#
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_signal_watch(self):
"""Test a watchpoint and a signal in multiple threads."""
self.build(dictionary=self.getBuildFlags())
@@ -112,6 +123,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_delay_signal_watch(self):
"""Test a watchpoint and a (1 second delay) signal in multiple threads."""
self.build(dictionary=self.getBuildFlags())
@@ -119,7 +131,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
- @expectedFailureAll("llvm.org/pr16714", oslist=["linux"], archs=["i386"])
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_signal_delay_watch(self):
"""Test a (1 second delay) watchpoint and a signal in multiple threads."""
self.build(dictionary=self.getBuildFlags())
@@ -130,12 +142,14 @@ class ConcurrentEventsTestCase(TestBase):
## Tests for multiple breakpoint threads
#
@skipIfFreeBSD # timing out on buildbot
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_two_breakpoint_threads(self):
"""Test two threads that trigger a breakpoint. """
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_breakpoint_threads=2)
@skipIfFreeBSD # timing out on buildbot
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_breakpoint_one_delay_breakpoint_threads(self):
"""Test threads that trigger a breakpoint where one thread has a 1 second delay. """
self.build(dictionary=self.getBuildFlags())
@@ -143,12 +157,14 @@ class ConcurrentEventsTestCase(TestBase):
num_delay_breakpoint_threads=1)
@skipIfFreeBSD # timing out on buildbot
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_two_breakpoints_one_signal(self):
"""Test two threads that trigger a breakpoint and one signal thread. """
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_breakpoint_threads=2, num_signal_threads=1)
@skipIfFreeBSD # timing out on buildbot
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_breakpoint_delay_breakpoint_one_signal(self):
"""Test two threads that trigger a breakpoint (one with a 1 second delay) and one signal thread. """
self.build(dictionary=self.getBuildFlags())
@@ -157,6 +173,7 @@ class ConcurrentEventsTestCase(TestBase):
num_signal_threads=1)
@skipIfFreeBSD # timing out on buildbot
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_two_breakpoints_one_delay_signal(self):
"""Test two threads that trigger a breakpoint and one (1 second delay) signal thread. """
self.build(dictionary=self.getBuildFlags())
@@ -164,6 +181,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_two_breakpoints_one_watchpoint(self):
"""Test two threads that trigger a breakpoint and one watchpoint thread. """
self.build(dictionary=self.getBuildFlags())
@@ -171,6 +189,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_breakpoints_delayed_breakpoint_one_watchpoint(self):
"""Test a breakpoint, a delayed breakpoint, and one watchpoint thread. """
self.build(dictionary=self.getBuildFlags())
@@ -183,6 +202,7 @@ class ConcurrentEventsTestCase(TestBase):
#
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_two_watchpoint_threads(self):
"""Test two threads that trigger a watchpoint. """
self.build(dictionary=self.getBuildFlags())
@@ -190,6 +210,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_watchpoint_with_delay_watchpoint_threads(self):
"""Test two threads that trigger a watchpoint where one thread has a 1 second delay. """
self.build(dictionary=self.getBuildFlags())
@@ -198,6 +219,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_two_watchpoints_one_breakpoint(self):
"""Test two threads that trigger a watchpoint and one breakpoint thread. """
self.build(dictionary=self.getBuildFlags())
@@ -205,6 +227,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_two_watchpoints_one_delay_breakpoint(self):
"""Test two threads that trigger a watchpoint and one (1 second delay) breakpoint thread. """
self.build(dictionary=self.getBuildFlags())
@@ -212,6 +235,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_watchpoint_delay_watchpoint_one_breakpoint(self):
"""Test two threads that trigger a watchpoint (one with a 1 second delay) and one breakpoint thread. """
self.build(dictionary=self.getBuildFlags())
@@ -221,6 +245,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_two_watchpoints_one_signal(self):
"""Test two threads that trigger a watchpoint and one signal thread. """
self.build(dictionary=self.getBuildFlags())
@@ -231,6 +256,7 @@ class ConcurrentEventsTestCase(TestBase):
#
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_signal_watch_break(self):
"""Test a signal/watchpoint/breakpoint in multiple threads."""
self.build(dictionary=self.getBuildFlags())
@@ -240,6 +266,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_signal_watch_break(self):
"""Test one signal thread with 5 watchpoint and breakpoint threads."""
self.build(dictionary=self.getBuildFlags())
@@ -249,6 +276,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_signal_watch_break(self):
"""Test with 5 watchpoint and breakpoint threads."""
self.build(dictionary=self.getBuildFlags())
@@ -260,6 +288,7 @@ class ConcurrentEventsTestCase(TestBase):
## Test for crashing threads happening concurrently with other events
#
@skipIfFreeBSD # timing out on buildbot
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_crash_with_break(self):
""" Test a thread that crashes while another thread hits a breakpoint."""
self.build(dictionary=self.getBuildFlags())
@@ -267,12 +296,14 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_crash_with_watchpoint(self):
""" Test a thread that crashes while another thread hits a watchpoint."""
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_crash_threads=1, num_watchpoint_threads=1)
@skipIfFreeBSD # timing out on buildbot
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_crash_with_signal(self):
""" Test a thread that crashes while another thread generates a signal."""
self.build(dictionary=self.getBuildFlags())
@@ -280,6 +311,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_crash_with_watchpoint_breakpoint_signal(self):
""" Test a thread that crashes while other threads generate a signal and hit a watchpoint and breakpoint. """
self.build(dictionary=self.getBuildFlags())
@@ -290,6 +322,7 @@ class ConcurrentEventsTestCase(TestBase):
@skipIfFreeBSD # timing out on buildbot
@skipIfRemoteDueToDeadlock
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_delayed_crash_with_breakpoint_watchpoint(self):
""" Test a thread with a delayed crash while other threads hit a watchpoint and a breakpoint. """
self.build(dictionary=self.getBuildFlags())
@@ -298,6 +331,7 @@ class ConcurrentEventsTestCase(TestBase):
num_watchpoint_threads=1)
@skipIfFreeBSD # timing out on buildbot
+ @expectedFailureAll(triple = '^mips') # Atomic sequences are not supported yet for MIPS in LLDB.
def test_delayed_crash_with_breakpoint_signal(self):
""" Test a thread with a delayed crash while other threads generate a signal and hit a breakpoint. """
self.build(dictionary=self.getBuildFlags())
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/main.cpp
index ac2535cd2bff..10b55bff3ba4 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/main.cpp
@@ -23,22 +23,10 @@ using namespace std;
#include <sys/types.h>
#include <unistd.h>
-// Note that although hogging the CPU while waiting for a variable to change
-// would be terrible in production code, it's great for testing since it
-// avoids a lot of messy context switching to get multiple threads synchronized.
-#define do_nothing()
-
-#define pseudo_barrier_wait(bar) \
- --bar; \
- while (bar > 0) \
- do_nothing();
-
-#define pseudo_barrier_init(bar, count) (bar = count)
-
typedef std::vector<std::pair<unsigned, void*(*)(void*)> > action_counts;
typedef std::vector<pthread_t> thread_vector;
-std::atomic_int g_barrier;
+pseudo_barrier_t g_barrier;
int g_breakpoint = 0;
int g_sigusr1_count = 0;
std::atomic_int g_watchme;
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py b/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py
index 24b5bf0dad36..edd1e885ca9e 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CreateDuringStepTestCase(TestBase):
@@ -19,9 +20,10 @@ class CreateDuringStepTestCase(TestBase):
TestBase.setUp(self)
self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
@expectedFailureAndroid("llvm.org/pr24497", archs=['arm', 'aarch64'])
- @expectedFailureAll(archs=['mips', 'mipsel', 'mips64', 'mips64el']) # IO error due to breakpoint at invalid address
+ @expectedFailureAll(oslist=["linux"], archs=["arm"], bugnumber="llvm.org/pr24497")
+ @expectedFailureAll(triple = re.compile('^mips')) # IO error due to breakpoint at invalid address
def test_step_inst_with(self):
"""Test thread creation during step-inst handling."""
self.build(dictionary=self.getBuildFlags())
@@ -38,11 +40,8 @@ class CreateDuringStepTestCase(TestBase):
# The stop reason should be breakpoint.
self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
- self.assertEqual(lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint).IsValid(), 1,
- STOPPED_DUE_TO_BREAKPOINT)
-
- thread = process.GetThreadAtIndex(0)
- self.assertTrue(thread and thread.IsValid(), "Thread is valid")
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid(), STOPPED_DUE_TO_BREAKPOINT)
# Keep stepping until the inferior crashes
while process.GetState() == lldb.eStateStopped and not lldbutil.is_thread_crashed(self, thread):
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py b/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py
index 977254343aa0..1cb97355395f 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CreateAfterAttachTestCase(TestBase):
@@ -29,7 +30,6 @@ class CreateAfterAttachTestCase(TestBase):
# for FreeBSD.
@skipIfRemote
@skipIfWindows # Windows doesn't have fork.
- @expectedFlakeyLinux("llvm.org/pr16229") # 1/100 dosep, build 3546, clang-3.5 x84_64
@skipIfiOSSimulator
def test_create_after_attach_with_fork(self):
"""Test thread creation after process attach."""
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py b/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py
index 046a86509c0f..9401826e304e 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py
@@ -8,35 +8,36 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CreateDuringStepTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
- @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=lldbplatformutil.getDarwinOSTriples(), bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr18190 thread states not properly maintained")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly")
def test_step_inst(self):
"""Test thread creation during step-inst handling."""
self.build(dictionary=self.getBuildFlags())
self.create_during_step_base("thread step-inst -m all-threads", 'stop reason = instruction step')
- @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
- @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=lldbplatformutil.getDarwinOSTriples(), bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr18190 thread states not properly maintained")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly")
def test_step_over(self):
"""Test thread creation during step-over handling."""
self.build(dictionary=self.getBuildFlags())
self.create_during_step_base("thread step-over -m all-threads", 'stop reason = step over')
- @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
- @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=lldbplatformutil.getDarwinOSTriples(), bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr18190 thread states not properly maintained")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly")
def test_step_in(self):
"""Test thread creation during step-in handling."""
self.build(dictionary=self.getBuildFlags())
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/main.cpp
index 3a00248c022a..70681fd11603 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/main.cpp
@@ -13,19 +13,9 @@
#include <atomic>
#include <thread>
-// Note that although hogging the CPU while waiting for a variable to change
-// would be terrible in production code, it's great for testing since it
-// avoids a lot of messy context switching to get multiple threads synchronized.
#define do_nothing()
-#define pseudo_barrier_wait(bar) \
- --bar; \
- while (bar > 0) \
- do_nothing();
-
-#define pseudo_barrier_init(bar, count) (bar = count)
-
-std::atomic_int g_barrier;
+pseudo_barrier_t g_barrier;
volatile int g_thread_created = 0;
volatile int g_test = 0;
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py
index f999ffe108f3..2c394263d36e 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ExitDuringBreakpointTestCase(TestBase):
@@ -21,10 +22,10 @@ class ExitDuringBreakpointTestCase(TestBase):
# Find the line number for our breakpoint.
self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
- @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
- @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=lldbplatformutil.getDarwinOSTriples(), bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr18190 thread states not properly maintained")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly")
def test(self):
"""Test thread exit during breakpoint handling."""
self.build(dictionary=self.getBuildFlags())
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/main.cpp
index 3570637207d2..a032da835ea6 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/main.cpp
@@ -19,27 +19,15 @@
volatile int g_test = 0;
-// Note that although hogging the CPU while waiting for a variable to change
-// would be terrible in production code, it's great for testing since it
-// avoids a lot of messy context switching to get multiple threads synchronized.
-#define do_nothing()
-
-#define pseudo_barrier_wait(bar) \
- --bar; \
- while (bar > 0) \
- do_nothing();
-
-#define pseudo_barrier_init(bar, count) (bar = count)
-
// A barrier to synchronize all the threads except the one that will exit.
-std::atomic_int g_barrier1;
+pseudo_barrier_t g_barrier1;
// A barrier to synchronize all the threads including the one that will exit.
-std::atomic_int g_barrier2;
+pseudo_barrier_t g_barrier2;
// A barrier to keep the first group of threads from exiting until after the
// breakpoint has been passed.
-std::atomic_int g_barrier3;
+pseudo_barrier_t g_barrier3;
void *
break_thread_func ()
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py
index 67d1c96fd342..af4a022ed0c1 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py
@@ -8,42 +8,31 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ExitDuringStepTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
- @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureWindows("llvm.org/pr24681")
- def test_thread_state_is_stopped(self):
- """Test thread exit during step handling."""
- self.build(dictionary=self.getBuildFlags())
- self.exit_during_step_base("thread step-in -m all-threads", 'stop reason = step in', True)
-
@skipIfFreeBSD # llvm.org/pr21411: test is hanging
- @expectedFailureWindows("llvm.org/pr24681")
def test(self):
"""Test thread exit during step handling."""
self.build(dictionary=self.getBuildFlags())
- self.exit_during_step_base("thread step-inst -m all-threads", 'stop reason = instruction step', False)
+ self.exit_during_step_base("thread step-inst -m all-threads", 'stop reason = instruction step')
@skipIfFreeBSD # llvm.org/pr21411: test is hanging
- @expectedFailureWindows("llvm.org/pr24681")
def test_step_over(self):
"""Test thread exit during step-over handling."""
self.build(dictionary=self.getBuildFlags())
- self.exit_during_step_base("thread step-over -m all-threads", 'stop reason = step over', False)
+ self.exit_during_step_base("thread step-over -m all-threads", 'stop reason = step over')
@skipIfFreeBSD # llvm.org/pr21411: test is hanging
- @expectedFailureWindows("llvm.org/pr24681")
def test_step_in(self):
"""Test thread exit during step-in handling."""
self.build(dictionary=self.getBuildFlags())
- self.exit_during_step_base("thread step-in -m all-threads", 'stop reason = step in', False)
+ self.exit_during_step_base("thread step-in -m all-threads", 'stop reason = step in')
def setUp(self):
# Call super's setUp().
@@ -52,7 +41,7 @@ class ExitDuringStepTestCase(TestBase):
self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
self.continuepoint = line_number('main.cpp', '// Continue from here')
- def exit_during_step_base(self, step_cmd, step_stop_reason, test_thread_state):
+ def exit_during_step_base(self, step_cmd, step_stop_reason):
"""Test thread exit during step handling."""
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
@@ -76,37 +65,16 @@ class ExitDuringStepTestCase(TestBase):
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
- # Get the number of threads
num_threads = process.GetNumThreads()
-
# Make sure we see all three threads
- self.assertTrue(num_threads == 3, 'Number of expected threads and actual threads do not match.')
-
- # Get the thread objects
- thread1 = process.GetThreadAtIndex(0)
- thread2 = process.GetThreadAtIndex(1)
- thread3 = process.GetThreadAtIndex(2)
-
- # Make sure all threads are stopped
- if test_thread_state:
- self.assertTrue(thread1.IsStopped(), "Thread 1 didn't stop during breakpoint")
- self.assertTrue(thread2.IsStopped(), "Thread 2 didn't stop during breakpoint")
- self.assertTrue(thread3.IsStopped(), "Thread 3 didn't stop during breakpoint")
- return
-
- # Find the thread that is stopped at the breakpoint
- stepping_thread = None
- for thread in process:
- expected_bp_desc = "breakpoint %s." % self.bp_num
- stop_desc = thread.GetStopDescription(100)
- if stop_desc and (expected_bp_desc in stop_desc):
- stepping_thread = thread
- break
- self.assertTrue(stepping_thread != None, "unable to find thread stopped at %s" % expected_bp_desc)
+ self.assertGreaterEqual(num_threads, 3, 'Number of expected threads and actual threads do not match.')
+
+ stepping_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id(process, self.bp_num)
+ self.assertIsNotNone(stepping_thread, "Could not find a thread stopped at the breakpoint")
current_line = self.breakpoint
stepping_frame = stepping_thread.GetFrameAtIndex(0)
- self.assertTrue(current_line == stepping_frame.GetLineEntry().GetLine(), "Starting line for stepping doesn't match breakpoint line.")
+ self.assertEqual(current_line, stepping_frame.GetLineEntry().GetLine(), "Starting line for stepping doesn't match breakpoint line.")
# Keep stepping until we've reached our designated continue point
while current_line != self.continuepoint:
@@ -122,16 +90,16 @@ class ExitDuringStepTestCase(TestBase):
current_line = frame.GetLineEntry().GetLine()
- self.assertTrue(current_line >= self.breakpoint, "Stepped to unexpected line, " + str(current_line))
- self.assertTrue(current_line <= self.continuepoint, "Stepped to unexpected line, " + str(current_line))
+ self.assertGreaterEqual(current_line, self.breakpoint, "Stepped to unexpected line, " + str(current_line))
+ self.assertLessEqual(current_line, self.continuepoint, "Stepped to unexpected line, " + str(current_line))
self.runCmd("thread list")
# Update the number of threads
- num_threads = process.GetNumThreads()
+ new_num_threads = process.GetNumThreads()
# Check to see that we reduced the number of threads as expected
- self.assertTrue(num_threads == 2, 'Number of expected threads and actual threads do not match after thread exit.')
+ self.assertEqual(new_num_threads, num_threads-1, 'Number of threads did not reduce by 1 after thread exit.')
self.expect("thread list", 'Process state is stopped due to step',
substrs = ['stopped',
@@ -141,4 +109,4 @@ class ExitDuringStepTestCase(TestBase):
self.runCmd("continue")
# At this point, the inferior process should have exited.
- self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
+ self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/main.cpp
index d1b364b8baa2..45adf28ce813 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/main.cpp
@@ -12,20 +12,10 @@
#include <thread>
-// Note that although hogging the CPU while waiting for a variable to change
-// would be terrible in production code, it's great for testing since it
-// avoids a lot of messy context switching to get multiple threads synchronized.
#define do_nothing()
-#define pseudo_barrier_wait(bar) \
- --bar; \
- while (bar > 0) \
- do_nothing();
-
-#define pseudo_barrier_init(bar, count) (bar = count)
-
// A barrier to synchronize thread start.
-volatile int g_barrier;
+pseudo_barrier_t g_barrier;
volatile int g_thread_exited = 0;
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py b/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py
index 768e2fe4f87a..4c55bcd982a7 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ThreadJumpTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py
index 9dd212412216..d4b1eb32a9ae 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class MultipleBreakpointTestCase(TestBase):
@@ -21,10 +22,10 @@ class MultipleBreakpointTestCase(TestBase):
# Find the line number for our breakpoint.
self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
- @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not properly maintained
- @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=lldbplatformutil.getDarwinOSTriples(), bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr18190 thread states not properly maintained")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly")
def test(self):
"""Test simultaneous breakpoints in multiple threads."""
self.build(dictionary=self.getBuildFlags())
@@ -55,7 +56,7 @@ class MultipleBreakpointTestCase(TestBase):
num_threads = process.GetNumThreads()
# Make sure we see all three threads
- self.assertTrue(num_threads == 3, 'Number of expected threads and actual threads do not match.')
+ self.assertTrue(num_threads >= 3, 'Number of expected threads and actual threads do not match.')
# Get the thread objects
thread1 = process.GetThreadAtIndex(0)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/multi_break/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/multi_break/main.cpp
index 01f4b8f98ea7..c3d695dbc745 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/multi_break/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/thread/multi_break/main.cpp
@@ -15,19 +15,7 @@
#include <atomic>
#include <thread>
-// Note that although hogging the CPU while waiting for a variable to change
-// would be terrible in production code, it's great for testing since it
-// avoids a lot of messy context switching to get multiple threads synchronized.
-#define do_nothing()
-
-#define pseudo_barrier_wait(bar) \
- --bar; \
- while (bar > 0) \
- do_nothing();
-
-#define pseudo_barrier_init(bar, count) (bar = count)
-
-std::atomic_int g_barrier;
+pseudo_barrier_t g_barrier;
volatile int g_test = 0;
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py b/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py
index 4938ec50453e..5afb57bf4ba8 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py
@@ -9,25 +9,26 @@ from __future__ import print_function
import unittest2
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ThreadStateTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureDarwin("rdar://15367566")
- @expectedFailureFreeBSD('llvm.org/pr15824')
- @expectedFailureLinux("llvm.org/pr15824") # thread states not properly maintained
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=lldbplatformutil.getDarwinOSTriples(), bugnumber="llvm.org/pr15824 thread states not properly maintained")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr18190 thread states not properly maintained")
def test_state_after_breakpoint(self):
"""Test thread state after breakpoint."""
self.build(dictionary=self.getBuildFlags(use_cpp11=False))
self.thread_state_after_breakpoint_test()
@skipIfDarwin # 'llvm.org/pr23669', cause Python crash randomly
- @expectedFailureDarwin('llvm.org/pr23669')
- @expectedFailureFreeBSD('llvm.org/pr15824')
- @expectedFailureWindows("llvm.org/pr24660")
+ @expectedFailureAll(oslist=lldbplatformutil.getDarwinOSTriples(), bugnumber="llvm.org/pr23669")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr15824")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24660")
def test_state_after_continue(self):
"""Test thread state after continue."""
self.build(dictionary=self.getBuildFlags(use_cpp11=False))
@@ -35,7 +36,7 @@ class ThreadStateTestCase(TestBase):
@skipIfDarwin # 'llvm.org/pr23669', cause Python crash randomly
@expectedFailureDarwin('llvm.org/pr23669')
- @expectedFailureWindows("llvm.org/pr24660")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24660")
@unittest2.expectedFailure("llvm.org/pr16712") # thread states not properly maintained
def test_state_after_expression(self):
"""Test thread state after expression."""
@@ -43,14 +44,14 @@ class ThreadStateTestCase(TestBase):
self.thread_state_after_expression_test()
@unittest2.expectedFailure("llvm.org/pr16712") # thread states not properly maintained
- @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly")
def test_process_interrupt(self):
"""Test process interrupt."""
self.build(dictionary=self.getBuildFlags(use_cpp11=False))
self.process_interrupt_test()
@unittest2.expectedFailure("llvm.org/pr15824") # thread states not properly maintained
- @expectedFailureWindows("llvm.org/pr24668") # Breakpoints not resolved correctly
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly")
def test_process_state(self):
"""Test thread states (comprehensive)."""
self.build(dictionary=self.getBuildFlags(use_cpp11=False))
@@ -69,28 +70,17 @@ class ThreadStateTestCase(TestBase):
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# This should create a breakpoint in the main thread.
- lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1)
+ bp = lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1)
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
- # The stop reason of the thread should be breakpoint.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
- substrs = ['stopped',
- '* thread #1',
- 'stop reason = breakpoint'])
-
# Get the target process
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
- # Get the number of threads
- num_threads = process.GetNumThreads()
-
- self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
-
- # Get the thread object
- thread = process.GetThreadAtIndex(0)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
# Make sure the thread is in the stopped state.
self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 1.")
@@ -99,11 +89,11 @@ class ThreadStateTestCase(TestBase):
# Kill the process
self.runCmd("process kill")
- def wait_for_running_event(self):
+ def wait_for_running_event(self, process):
listener = self.dbg.GetListener()
if lldb.remote_platform:
- lldbutil.expect_state_changes(self, listener, [lldb.eStateConnected])
- lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning])
+ lldbutil.expect_state_changes(self, listener, process, [lldb.eStateConnected])
+ lldbutil.expect_state_changes(self, listener, process, [lldb.eStateRunning])
def thread_state_after_continue_test(self):
"""Test thread state after continue."""
@@ -117,28 +107,17 @@ class ThreadStateTestCase(TestBase):
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
- # The stop reason of the thread should be breakpoint.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
- substrs = ['stopped',
- '* thread #1',
- 'stop reason = breakpoint'])
-
# Get the target process
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
- # Get the number of threads
- num_threads = process.GetNumThreads()
-
- self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
-
- # Get the thread object
- thread = process.GetThreadAtIndex(0)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
# Continue, the inferior will go into an infinite loop waiting for 'g_test' to change.
self.dbg.SetAsync(True)
self.runCmd("continue")
- self.wait_for_running_event()
+ self.wait_for_running_event(process)
# Check the thread state. It should be running.
self.assertFalse(thread.IsStopped(), "Thread state is \'stopped\' when it should be running.")
@@ -162,23 +141,12 @@ class ThreadStateTestCase(TestBase):
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
- # The stop reason of the thread should be breakpoint.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
- substrs = ['stopped',
- '* thread #1',
- 'stop reason = breakpoint'])
-
# Get the target process
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
- # Get the number of threads
- num_threads = process.GetNumThreads()
-
- self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
-
- # Get the thread object
- thread = process.GetThreadAtIndex(0)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
# Get the inferior out of its loop
self.runCmd("expression g_test = 1")
@@ -202,25 +170,17 @@ class ThreadStateTestCase(TestBase):
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
- # The stop reason of the thread should be breakpoint.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
- substrs = ['stopped',
- '* thread #1',
- 'stop reason = breakpoint'])
-
# Get the target process
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
- # Get the number of threads
- num_threads = process.GetNumThreads()
-
- self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
# Continue, the inferior will go into an infinite loop waiting for 'g_test' to change.
self.dbg.SetAsync(True)
self.runCmd("continue")
- self.wait_for_running_event()
+ self.wait_for_running_event(process)
# Go back to synchronous interactions
self.dbg.SetAsync(False)
@@ -228,11 +188,7 @@ class ThreadStateTestCase(TestBase):
# Stop the process
self.runCmd("process interrupt")
- # The stop reason of the thread should be signal.
- self.expect("process status", STOPPED_DUE_TO_SIGNAL,
- substrs = ['stopped',
- '* thread #1',
- 'stop reason = signal'])
+ self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal)
# Get the inferior out of its loop
self.runCmd("expression g_test = 1")
@@ -252,23 +208,11 @@ class ThreadStateTestCase(TestBase):
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
- # The stop reason of the thread should be breakpoint.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
- substrs = ['stopped',
- '* thread #1',
- 'stop reason = breakpoint'])
-
# Get the target process
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
-
- # Get the number of threads
- num_threads = process.GetNumThreads()
-
- self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.')
-
- # Get the thread object
- thread = process.GetThreadAtIndex(0)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
# Make sure the thread is in the stopped state.
self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 1.")
@@ -277,7 +221,7 @@ class ThreadStateTestCase(TestBase):
# Continue, the inferior will go into an infinite loop waiting for 'g_test' to change.
self.dbg.SetAsync(True)
self.runCmd("continue")
- self.wait_for_running_event()
+ self.wait_for_running_event(process)
# Check the thread state. It should be running.
self.assertFalse(thread.IsStopped(), "Thread state is \'stopped\' when it should be running.")
@@ -289,11 +233,7 @@ class ThreadStateTestCase(TestBase):
# Stop the process
self.runCmd("process interrupt")
- # The stop reason of the thread should be signal.
- self.expect("process status", STOPPED_DUE_TO_SIGNAL,
- substrs = ['stopped',
- '* thread #1',
- 'stop reason = signal'])
+ self.assertEqual(thread.GetState(), lldb.eStopReasonSignal)
# Check the thread state
self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after process stop.")
@@ -306,20 +246,12 @@ class ThreadStateTestCase(TestBase):
self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after expression evaluation.")
self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after expression evaluation.")
- # The stop reason of the thread should be signal.
- self.expect("process status", STOPPED_DUE_TO_SIGNAL,
- substrs = ['stopped',
- '* thread #1',
- 'stop reason = signal'])
+ self.assertEqual(thread.GetState(), lldb.eStopReasonSignal)
# Run to breakpoint 2
self.runCmd("continue")
- # The stop reason of the thread should be breakpoint.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
- substrs = ['stopped',
- '* thread #1',
- 'stop reason = breakpoint'])
+ self.assertEqual(thread.GetState(), lldb.eStopReasonBreakpoint)
# Make sure both threads are stopped
self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 2.")
@@ -329,4 +261,4 @@ class ThreadStateTestCase(TestBase):
self.runCmd("continue")
# At this point, the inferior process should have exited.
- self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
+ self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py b/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py
index b2d966c4c0f3..735ee80d624e 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py
@@ -8,35 +8,36 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ThreadStepOutTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfLinux # Test occasionally times out on the Linux build bot
- @expectedFailureLinux("llvm.org/pr23477") # Test occasionally times out on the Linux build bot
- @expectedFailureFreeBSD("llvm.org/pr18066") # inferior does not exit
- @expectedFailureWindows # Test crashes
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr23477 Test occasionally times out on the Linux build bot")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr18066 inferior does not exit")
+ @expectedFailureAll(oslist=["windows"])
def test_step_single_thread(self):
"""Test thread step out on one thread via command interpreter. """
self.build(dictionary=self.getBuildFlags())
self.step_out_test(self.step_out_single_thread_with_cmd)
@skipIfLinux # Test occasionally times out on the Linux build bot
- @expectedFailureLinux("llvm.org/pr23477") # Test occasionally times out on the Linux build bot
- @expectedFailureFreeBSD("llvm.org/pr19347") # 2nd thread stops at breakpoint
- @expectedFailureWindows # Test crashes
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr23477 Test occasionally times out on the Linux build bot")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr19347 2nd thread stops at breakpoint")
+ @expectedFailureAll(oslist=["windows"])
def test_step_all_threads(self):
"""Test thread step out on all threads via command interpreter. """
self.build(dictionary=self.getBuildFlags())
self.step_out_test(self.step_out_all_threads_with_cmd)
@skipIfLinux # Test occasionally times out on the Linux build bot
- @expectedFailureLinux("llvm.org/pr23477") # Test occasionally times out on the Linux build bot
- @expectedFailureFreeBSD("llvm.org/pr19347")
- @expectedFailureWindows("llvm.org/pr24681")
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr23477 Test occasionally times out on the Linux build bot")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr19347 2nd thread stops at breakpoint")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24681")
def test_python(self):
"""Test thread step out on one thread via Python API (dwarf)."""
self.build(dictionary=self.getBuildFlags())
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/step_out/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/step_out/main.cpp
index b4c6216d6bfe..31f9a1576b92 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/step_out/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/thread/step_out/main.cpp
@@ -13,19 +13,7 @@
#include <atomic>
#include <thread>
-// Note that although hogging the CPU while waiting for a variable to change
-// would be terrible in production code, it's great for testing since it
-// avoids a lot of messy context switching to get multiple threads synchronized.
-#define do_nothing()
-
-#define pseudo_barrier_wait(bar) \
- --bar; \
- while (bar > 0) \
- do_nothing();
-
-#define pseudo_barrier_init(bar, count) (bar = count)
-
-std::atomic_int g_barrier;
+pseudo_barrier_t g_barrier;
volatile int g_test = 0;
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py
index f785401277a4..2ba6f2e57f2b 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py
@@ -24,7 +24,6 @@ class ThreadExitTestCase(TestBase):
self.break_3 = line_number('main.cpp', '// Set third breakpoint here')
self.break_4 = line_number('main.cpp', '// Set fourth breakpoint here')
- @expectedFailureWindows("llvm.org/pr24681")
def test(self):
"""Test thread exit handling."""
self.build(dictionary=self.getBuildFlags())
@@ -32,10 +31,10 @@ class ThreadExitTestCase(TestBase):
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# This should create a breakpoint with 1 location.
- lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1)
- lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1)
- lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_3, num_expected_locations=1)
- lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_4, num_expected_locations=1)
+ bp1_id = lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1)
+ bp2_id = lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1)
+ bp3_id = lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_3, num_expected_locations=1)
+ bp4_id = lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_4, num_expected_locations=1)
# The breakpoint list should show 1 locations.
self.expect("breakpoint list -f", "Breakpoint location shown correctly",
@@ -46,71 +45,46 @@ class ThreadExitTestCase(TestBase):
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
-
- # The stop reason of the thread should be breakpoint 1.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 1",
- substrs = ['stopped',
- '* thread #1',
- 'stop reason = breakpoint 1',
- 'thread #2'])
-
# Get the target process
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
+ stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id(process, bp1_id)
+ self.assertIsNotNone(stopped_thread, "Process is not stopped at breakpoint 1")
+
# Get the number of threads
num_threads = process.GetNumThreads()
-
- self.assertTrue(num_threads == 2, 'Number of expected threads and actual threads do not match at breakpoint 1.')
+ self.assertGreaterEqual(num_threads, 2, 'Number of expected threads and actual threads do not match at breakpoint 1.')
# Run to the second breakpoint
self.runCmd("continue")
-
- # The stop reason of the thread should be breakpoint 1.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 2",
- substrs = ['stopped',
- 'thread #1',
- 'thread #2',
- 'stop reason = breakpoint 2',
- 'thread #3'])
+ stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id(process, bp2_id)
+ self.assertIsNotNone(stopped_thread, "Process is not stopped at breakpoint 2")
# Update the number of threads
- num_threads = process.GetNumThreads()
-
- self.assertTrue(num_threads == 3, 'Number of expected threads and actual threads do not match at breakpoint 2.')
+ new_num_threads = process.GetNumThreads()
+ self.assertEqual(new_num_threads, num_threads+1, 'Number of expected threads did not increase by 1 at bp 2.')
# Run to the third breakpoint
self.runCmd("continue")
-
- # The stop reason of the thread should be breakpoint 3.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 3",
- substrs = ['stopped',
- 'thread #1',
- 'stop reason = breakpoint 3',
- 'thread #3',
- ])
+ stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id(process, bp3_id)
+ self.assertIsNotNone(stopped_thread, "Process is not stopped at breakpoint 3")
# Update the number of threads
- num_threads = process.GetNumThreads()
-
- self.assertTrue(num_threads == 2, 'Number of expected threads and actual threads do not match at breakpoint 3.')
+ new_num_threads = process.GetNumThreads()
+ self.assertEqual(new_num_threads, num_threads, 'Number of expected threads is not equal to original number of threads at bp 3.')
# Run to the fourth breakpoint
self.runCmd("continue")
-
- # The stop reason of the thread should be breakpoint 4.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 4",
- substrs = ['stopped',
- 'thread #1',
- 'stop reason = breakpoint 4'])
+ stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id(process, bp4_id)
+ self.assertIsNotNone(stopped_thread, "Process is not stopped at breakpoint 4")
# Update the number of threads
- num_threads = process.GetNumThreads()
-
- self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match at breakpoint 4.')
+ new_num_threads = process.GetNumThreads()
+ self.assertEqual(new_num_threads, num_threads-1, 'Number of expected threads did not decrease by 1 at bp 4.')
# Run to completion
self.runCmd("continue")
# At this point, the inferior process should have exited.
- self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
+ self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp
index e498db7895d2..c57db9f48527 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp
@@ -12,21 +12,9 @@
#include <atomic>
#include <thread>
-// Note that although hogging the CPU while waiting for a variable to change
-// would be terrible in production code, it's great for testing since it
-// avoids a lot of messy context switching to get multiple threads synchronized.
-#define do_nothing()
-
-#define pseudo_barrier_wait(bar) \
- --bar; \
- while (bar > 0) \
- do_nothing();
-
-#define pseudo_barrier_init(bar, count) (bar = count)
-
-std::atomic_int g_barrier1;
-std::atomic_int g_barrier2;
-std::atomic_int g_barrier3;
+pseudo_barrier_t g_barrier1;
+pseudo_barrier_t g_barrier2;
+pseudo_barrier_t g_barrier3;
void *
thread1 ()
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/TestThreadSpecificBreakpoint.py b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/TestThreadSpecificBreakpoint.py
index 3c69b6667f7d..12bacabd0d78 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/TestThreadSpecificBreakpoint.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/TestThreadSpecificBreakpoint.py
@@ -9,15 +9,16 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ThreadSpecificBreakTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@add_test_categories(['pyapi'])
- @expectedFailureWindows # Thread specific breakpoints cause the inferior to crash
+ @expectedFailureAll(oslist=["windows"])
def test_python(self):
"""Test that we obey thread conditioned breakpoints."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py
index 68c96a0fba75..ccb58c965b3f 100644
--- a/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py
+++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py
@@ -10,17 +10,17 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ThreadSpecificBreakPlusConditionTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfFreeBSD # test frequently times out or hangs
- @expectedFailureFreeBSD('llvm.org/pr18522') # hits break in another thread in testrun
+ @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr18522') # hits break in another thread in testrun
@add_test_categories(['pyapi'])
- @expectedFlakeyLinux # this test fails 6/100 dosep runs
def test_python(self):
"""Test that we obey thread conditioned breakpoints."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/basic/Makefile b/packages/Python/lldbsuite/test/functionalities/tsan/basic/Makefile
new file mode 100644
index 000000000000..c930ae563fc1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/basic/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -fsanitize=thread -g
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py b/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py
new file mode 100644
index 000000000000..44fa9cedc86c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py
@@ -0,0 +1,118 @@
+"""
+Tests basic ThreadSanitizer support (detecting a data race).
+"""
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+import json
+
+class TsanBasicTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)")
+ @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
+ @skipIfRemote
+ @skipUnlessCompilerRt
+ @skipUnlessThreadSanitizer
+ def test (self):
+ self.build ()
+ self.tsan_tests ()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ self.line_malloc = line_number('main.c', '// malloc line')
+ self.line_thread1 = line_number('main.c', '// thread1 line')
+ self.line_thread2 = line_number('main.c', '// thread2 line')
+
+ def tsan_tests (self):
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ])
+
+ self.runCmd("run")
+
+ stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()
+ if stop_reason == lldb.eStopReasonExec:
+ # On OS X 10.10 and older, we need to re-exec to enable interceptors.
+ self.runCmd("continue")
+
+ # the stop reason of the thread should be breakpoint.
+ self.expect("thread list", "A data race should be detected",
+ substrs = ['stopped', 'stop reason = Data race detected'])
+
+ self.assertEqual(self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), lldb.eStopReasonInstrumentation)
+
+ # test that the TSan dylib is present
+ self.expect("image lookup -n __tsan_get_current_report", "__tsan_get_current_report should be present",
+ substrs = ['1 match found'])
+
+ # We should be stopped in __tsan_on_report
+ process = self.dbg.GetSelectedTarget().process
+ thread = process.GetSelectedThread()
+ frame = thread.GetSelectedFrame()
+ self.assertTrue("__tsan_on_report" in frame.GetFunctionName())
+
+ # The stopped thread backtrace should contain either line1 or line2 from main.c.
+ found = False
+ for i in range(0, thread.GetNumFrames()):
+ frame = thread.GetFrameAtIndex(i)
+ if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
+ if frame.GetLineEntry().GetLine() == self.line_thread1:
+ found = True
+ if frame.GetLineEntry().GetLine() == self.line_thread2:
+ found = True
+ self.assertTrue(found)
+
+ self.expect("thread info -s", "The extended stop info should contain the TSan provided fields",
+ substrs = ["instrumentation_class", "description", "mops"])
+
+ output_lines = self.res.GetOutput().split('\n')
+ json_line = '\n'.join(output_lines[2:])
+ data = json.loads(json_line)
+ self.assertEqual(data["instrumentation_class"], "ThreadSanitizer")
+ self.assertEqual(data["issue_type"], "data-race")
+ self.assertEqual(len(data["mops"]), 2)
+
+ backtraces = thread.GetStopReasonExtendedBacktraces(lldb.eInstrumentationRuntimeTypeAddressSanitizer)
+ self.assertEqual(backtraces.GetSize(), 0)
+
+ backtraces = thread.GetStopReasonExtendedBacktraces(lldb.eInstrumentationRuntimeTypeThreadSanitizer)
+ self.assertTrue(backtraces.GetSize() >= 2)
+
+ # First backtrace is a memory operation
+ thread = backtraces.GetThreadAtIndex(0)
+ found = False
+ for i in range(0, thread.GetNumFrames()):
+ frame = thread.GetFrameAtIndex(i)
+ if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
+ if frame.GetLineEntry().GetLine() == self.line_thread1:
+ found = True
+ if frame.GetLineEntry().GetLine() == self.line_thread2:
+ found = True
+ self.assertTrue(found)
+
+ # Second backtrace is a memory operation
+ thread = backtraces.GetThreadAtIndex(1)
+ found = False
+ for i in range(0, thread.GetNumFrames()):
+ frame = thread.GetFrameAtIndex(i)
+ if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
+ if frame.GetLineEntry().GetLine() == self.line_thread1:
+ found = True
+ if frame.GetLineEntry().GetLine() == self.line_thread2:
+ found = True
+ self.assertTrue(found)
+
+ self.runCmd("continue")
+
+ # the stop reason of the thread should be a SIGABRT.
+ self.expect("thread list", "We should be stopped due a SIGABRT",
+ substrs = ['stopped', 'stop reason = signal SIGABRT'])
+
+ # test that we're in pthread_kill now (TSan abort the process)
+ self.expect("thread list", "We should be stopped in pthread_kill",
+ substrs = ['pthread_kill'])
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/basic/main.c b/packages/Python/lldbsuite/test/functionalities/tsan/basic/main.c
new file mode 100644
index 000000000000..c082b01a57c7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/basic/main.c
@@ -0,0 +1,37 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+char *pointer;
+
+void *f1(void *p) {
+ pointer[0] = 'x'; // thread1 line
+ return NULL;
+}
+
+void *f2(void *p) {
+ pointer[0] = 'y'; // thread2 line
+ return NULL;
+}
+
+int main (int argc, char const *argv[])
+{
+ pointer = (char *)malloc(10); // malloc line
+
+ pthread_t t1, t2;
+ pthread_create(&t1, NULL, f1, NULL);
+ pthread_create(&t2, NULL, f2, NULL);
+
+ pthread_join(t1, NULL);
+ pthread_join(t2, NULL);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/Makefile b/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/Makefile
new file mode 100644
index 000000000000..a58194779074
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+CFLAGS_EXTRAS := -fsanitize=thread -g
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/TestTsanCPPGlobalLocation.py b/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/TestTsanCPPGlobalLocation.py
new file mode 100644
index 000000000000..230ff982da0d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/TestTsanCPPGlobalLocation.py
@@ -0,0 +1,54 @@
+"""
+Tests that TSan correctly reports the filename and line number of a racy global C++ variable.
+"""
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+import json
+
+class TsanCPPGlobalLocationTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)")
+ @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
+ @skipIfRemote
+ @skipUnlessCompilerRt
+ @skipUnlessThreadSanitizer
+ def test (self):
+ self.build ()
+ self.tsan_tests ()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def tsan_tests (self):
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ])
+
+ self.runCmd("run")
+
+ stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()
+ if stop_reason == lldb.eStopReasonExec:
+ # On OS X 10.10 and older, we need to re-exec to enable interceptors.
+ self.runCmd("continue")
+
+ # the stop reason of the thread should be breakpoint.
+ self.expect("thread list", "A data race should be detected",
+ substrs = ['stopped', 'stop reason = Data race detected'])
+
+ self.expect("thread info -s", "The extended stop info should contain the TSan provided fields",
+ substrs = ["instrumentation_class", "description", "mops"])
+
+ output_lines = self.res.GetOutput().split('\n')
+ json_line = '\n'.join(output_lines[2:])
+ data = json.loads(json_line)
+ self.assertEqual(data["instrumentation_class"], "ThreadSanitizer")
+ self.assertEqual(data["issue_type"], "data-race")
+
+ self.assertTrue(data["location_filename"].endswith("/main.cpp"))
+ self.assertEqual(data["location_line"], line_number('main.cpp', '// global variable'))
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/main.cpp b/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/main.cpp
new file mode 100644
index 000000000000..80f72ae83cf7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/main.cpp
@@ -0,0 +1,38 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+long my_global_variable; // global variable
+
+void *f1(void *p) {
+ my_global_variable = 42;
+ return NULL;
+}
+
+void *f2(void *p) {
+ my_global_variable = 43;
+ return NULL;
+}
+
+int main (int argc, char const *argv[])
+{
+ pthread_t t1;
+ pthread_create(&t1, NULL, f1, NULL);
+
+ pthread_t t2;
+ pthread_create(&t2, NULL, f2, NULL);
+
+ pthread_join(t1, NULL);
+ pthread_join(t2, NULL);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/global_location/Makefile b/packages/Python/lldbsuite/test/functionalities/tsan/global_location/Makefile
new file mode 100644
index 000000000000..c930ae563fc1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/global_location/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -fsanitize=thread -g
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py b/packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py
new file mode 100644
index 000000000000..b268c46fead3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py
@@ -0,0 +1,54 @@
+"""
+Tests that TSan correctly reports the filename and line number of a racy global variable.
+"""
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+import json
+
+class TsanGlobalLocationTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)")
+ @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
+ @skipIfRemote
+ @skipUnlessCompilerRt
+ @skipUnlessThreadSanitizer
+ def test (self):
+ self.build ()
+ self.tsan_tests ()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def tsan_tests (self):
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ])
+
+ self.runCmd("run")
+
+ stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()
+ if stop_reason == lldb.eStopReasonExec:
+ # On OS X 10.10 and older, we need to re-exec to enable interceptors.
+ self.runCmd("continue")
+
+ # the stop reason of the thread should be breakpoint.
+ self.expect("thread list", "A data race should be detected",
+ substrs = ['stopped', 'stop reason = Data race detected'])
+
+ self.expect("thread info -s", "The extended stop info should contain the TSan provided fields",
+ substrs = ["instrumentation_class", "description", "mops"])
+
+ output_lines = self.res.GetOutput().split('\n')
+ json_line = '\n'.join(output_lines[2:])
+ data = json.loads(json_line)
+ self.assertEqual(data["instrumentation_class"], "ThreadSanitizer")
+ self.assertEqual(data["issue_type"], "data-race")
+
+ self.assertTrue(data["location_filename"].endswith("/main.c"))
+ self.assertEqual(data["location_line"], line_number('main.c', '// global variable'))
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/global_location/main.c b/packages/Python/lldbsuite/test/functionalities/tsan/global_location/main.c
new file mode 100644
index 000000000000..caa2c3cb43cd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/global_location/main.c
@@ -0,0 +1,38 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+long my_global_variable; // global variable
+
+void *f1(void *p) {
+ my_global_variable = 42;
+ return NULL;
+}
+
+void *f2(void *p) {
+ my_global_variable = 43;
+ return NULL;
+}
+
+int main (int argc, char const *argv[])
+{
+ pthread_t t1;
+ pthread_create(&t1, NULL, f1, NULL);
+
+ pthread_t t2;
+ pthread_create(&t2, NULL, f2, NULL);
+
+ pthread_join(t1, NULL);
+ pthread_join(t2, NULL);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/multiple/Makefile b/packages/Python/lldbsuite/test/functionalities/tsan/multiple/Makefile
new file mode 100644
index 000000000000..c930ae563fc1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/multiple/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -fsanitize=thread -g
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py b/packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py
new file mode 100644
index 000000000000..c22501141cca
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py
@@ -0,0 +1,69 @@
+"""
+Test ThreadSanitizer when multiple different issues are found.
+"""
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+import json
+
+class TsanMultipleTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)")
+ @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
+ @skipIfRemote
+ @skipUnlessCompilerRt
+ @skipUnlessThreadSanitizer
+ def test (self):
+ self.build ()
+ self.tsan_tests ()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def tsan_tests (self):
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ])
+
+ self.runCmd("env TSAN_OPTIONS=abort_on_error=0")
+
+ self.runCmd("run")
+
+ stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()
+ if stop_reason == lldb.eStopReasonExec:
+ # On OS X 10.10 and older, we need to re-exec to enable interceptors.
+ self.runCmd("continue")
+
+ report_count = 0
+ while self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason() == lldb.eStopReasonInstrumentation:
+ report_count += 1
+
+ stop_description = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopDescription(100)
+
+ self.assertTrue(
+ (stop_description == "Data race detected") or
+ (stop_description == "Use of deallocated memory detected") or
+ (stop_description == "Thread leak detected") or
+ (stop_description == "Use of an uninitialized or destroyed mutex detected") or
+ (stop_description == "Unlock of an unlocked mutex (or by a wrong thread) detected")
+ )
+
+ self.expect("thread info -s", "The extended stop info should contain the TSan provided fields",
+ substrs = ["instrumentation_class", "description", "mops"])
+
+ output_lines = self.res.GetOutput().split('\n')
+ json_line = '\n'.join(output_lines[2:])
+ data = json.loads(json_line)
+ self.assertEqual(data["instrumentation_class"], "ThreadSanitizer")
+
+ backtraces = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReasonExtendedBacktraces(lldb.eInstrumentationRuntimeTypeThreadSanitizer)
+ self.assertTrue(backtraces.GetSize() >= 1)
+
+ self.runCmd("continue")
+
+ self.assertEqual(self.dbg.GetSelectedTarget().process.GetState(), lldb.eStateExited, PROCESS_EXITED)
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m b/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m
new file mode 100644
index 000000000000..f7c48b45422b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m
@@ -0,0 +1,138 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+#import <pthread.h>
+
+long my_global;
+
+void *Thread1(void *arg) {
+ my_global = 42;
+ return NULL;
+}
+
+void *Thread2(void *arg) {
+ my_global = 144;
+ return NULL;
+}
+
+void TestDataRace1() {
+ pthread_t t1, t2;
+ pthread_create(&t1, NULL, Thread1, NULL);
+ pthread_create(&t2, NULL, Thread2, NULL);
+
+ pthread_join(t1, NULL);
+ pthread_join(t2, NULL);
+}
+
+void TestInvalidMutex() {
+ pthread_mutex_t m = {0};
+ pthread_mutex_lock(&m);
+
+ pthread_mutex_init(&m, NULL);
+ pthread_mutex_lock(&m);
+ pthread_mutex_unlock(&m);
+ pthread_mutex_destroy(&m);
+ pthread_mutex_lock(&m);
+}
+
+void TestMutexWrongLock() {
+ pthread_mutex_t m = {0};
+ pthread_mutex_init(&m, NULL);
+ pthread_mutex_unlock(&m);
+}
+
+long some_global;
+
+void TestDataRaceBlocks1() {
+ dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);
+
+ for (int i = 0; i < 2; i++) {
+ dispatch_async(q, ^{
+ some_global++; // race 1
+
+ usleep(100000); // force the blocks to be on different threads
+ });
+ }
+
+ usleep(100000);
+ dispatch_barrier_sync(q, ^{ });
+}
+
+void TestDataRaceBlocks2() {
+ dispatch_queue_t q = dispatch_queue_create("my.queue2", DISPATCH_QUEUE_CONCURRENT);
+
+ char *c;
+
+ c = malloc((rand() % 1000) + 10);
+ for (int i = 0; i < 2; i++) {
+ dispatch_async(q, ^{
+ c[0] = 'x'; // race 2
+ fprintf(stderr, "tid: %p\n", pthread_self());
+ usleep(100000); // force the blocks to be on different threads
+ });
+ }
+ dispatch_barrier_sync(q, ^{ });
+
+ free(c);
+}
+
+void TestUseAfterFree() {
+ char *c;
+
+ c = malloc((rand() % 1000) + 10);
+ free(c);
+ c[0] = 'x';
+}
+
+void TestRacePipe() {
+ dispatch_queue_t q = dispatch_queue_create("my.queue3", DISPATCH_QUEUE_CONCURRENT);
+
+ int a[2];
+ pipe(a);
+ int fd = a[0];
+
+ for (int i = 0; i < 2; i++) {
+ dispatch_async(q, ^{
+ write(fd, "abc", 3);
+ usleep(100000); // force the blocks to be on different threads
+ });
+ dispatch_async(q, ^{
+ close(fd);
+ usleep(100000);
+ });
+ }
+
+ dispatch_barrier_sync(q, ^{ });
+}
+
+void TestThreadLeak() {
+ pthread_t t1;
+ pthread_create(&t1, NULL, Thread1, NULL);
+}
+
+int main(int argc, const char * argv[]) {
+ TestDataRace1();
+
+ TestInvalidMutex();
+
+ TestMutexWrongLock();
+
+ TestDataRaceBlocks1();
+
+ TestDataRaceBlocks2();
+
+ TestUseAfterFree();
+
+ TestRacePipe();
+
+ TestThreadLeak();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/Makefile b/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/Makefile
new file mode 100644
index 000000000000..c930ae563fc1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -fsanitize=thread -g
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/TestTsanThreadLeak.py b/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/TestTsanThreadLeak.py
new file mode 100644
index 000000000000..ed620093c1f3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/TestTsanThreadLeak.py
@@ -0,0 +1,40 @@
+"""
+Tests ThreadSanitizer's support to detect a leaked thread.
+"""
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+import json
+
+class TsanThreadLeakTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)")
+ @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
+ @skipIfRemote
+ @skipUnlessCompilerRt
+ @skipUnlessThreadSanitizer
+ def test (self):
+ self.build ()
+ self.tsan_tests ()
+
+ def tsan_tests (self):
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ])
+
+ self.runCmd("run")
+
+ stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()
+ if stop_reason == lldb.eStopReasonExec:
+ # On OS X 10.10 and older, we need to re-exec to enable interceptors.
+ self.runCmd("continue")
+
+ # the stop reason of the thread should be breakpoint.
+ self.expect("thread list", "A thread leak should be detected",
+ substrs = ['stopped', 'stop reason = Thread leak detected'])
+
+ self.assertEqual(self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), lldb.eStopReasonInstrumentation)
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/main.c b/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/main.c
new file mode 100644
index 000000000000..3c17e228487b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/main.c
@@ -0,0 +1,24 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void *f1(void *p) {
+ printf("hello\n");
+ return NULL;
+}
+
+int main (int argc, char const *argv[])
+{
+ pthread_t t1;
+ pthread_create(&t1, NULL, f1, NULL);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/Makefile b/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/Makefile
new file mode 100644
index 000000000000..c930ae563fc1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -fsanitize=thread -g
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/TestTsanThreadNumbers.py b/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/TestTsanThreadNumbers.py
new file mode 100644
index 000000000000..c7905bcb1c1d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/TestTsanThreadNumbers.py
@@ -0,0 +1,68 @@
+"""
+Tests that TSan and LLDB have correct thread numbers.
+"""
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+import json
+
+class TsanThreadNumbersTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)")
+ @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
+ @skipIfRemote
+ @skipUnlessCompilerRt
+ @skipUnlessThreadSanitizer
+ def test (self):
+ self.build ()
+ self.tsan_tests ()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def tsan_tests (self):
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ])
+
+ self.runCmd("run")
+
+ stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()
+ if stop_reason == lldb.eStopReasonExec:
+ # On OS X 10.10 and older, we need to re-exec to enable interceptors.
+ self.runCmd("continue")
+
+ # the stop reason of the thread should be breakpoint.
+ self.expect("thread list", "A data race should be detected",
+ substrs = ['stopped', 'stop reason = Data race detected'])
+
+ self.assertEqual(self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), lldb.eStopReasonInstrumentation)
+
+ report_thread_id = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetIndexID()
+
+ self.expect("thread info -s", "The extended stop info should contain the TSan provided fields",
+ substrs = ["instrumentation_class", "description", "mops"])
+
+ output_lines = self.res.GetOutput().split('\n')
+ json_line = '\n'.join(output_lines[2:])
+ data = json.loads(json_line)
+ self.assertEqual(data["instrumentation_class"], "ThreadSanitizer")
+ self.assertEqual(data["issue_type"], "data-race")
+ self.assertEqual(len(data["mops"]), 2)
+
+ self.assertEqual(data["mops"][0]["thread_id"], report_thread_id)
+
+ other_thread_id = data["mops"][1]["thread_id"]
+ self.assertTrue(other_thread_id != report_thread_id)
+ other_thread = self.dbg.GetSelectedTarget().process.GetThreadByIndexID(other_thread_id)
+ self.assertTrue(other_thread.IsValid())
+
+ self.runCmd("thread select %d" % other_thread_id)
+
+ self.expect("thread backtrace", "The other thread should be stopped in f1 or f2",
+ substrs = ["a.out", "main.c"])
diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/main.c b/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/main.c
new file mode 100644
index 000000000000..04ebb723c3b7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/main.c
@@ -0,0 +1,58 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+char *pointer;
+
+void *nothing(void *p) {
+ return NULL;
+}
+
+void *f1(void *p) {
+ pointer[0] = 'x';
+ sleep(100);
+ return NULL;
+}
+
+void *f2(void *p) {
+ pointer[0] = 'y';
+ sleep(100);
+ return NULL;
+}
+
+int main (int argc, char const *argv[])
+{
+ pointer = (char *)malloc(10);
+
+ for (int i = 0; i < 3; i++) {
+ pthread_t t;
+ pthread_create(&t, NULL, nothing, NULL);
+ pthread_join(t, NULL);
+ }
+
+ pthread_t t1;
+ pthread_create(&t1, NULL, f1, NULL);
+
+ for (int i = 0; i < 3; i++) {
+ pthread_t t;
+ pthread_create(&t, NULL, nothing, NULL);
+ pthread_join(t, NULL);
+ }
+
+ pthread_t t2;
+ pthread_create(&t2, NULL, f2, NULL);
+
+ pthread_join(t1, NULL);
+ pthread_join(t2, NULL);
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/tty/TestTerminal.py b/packages/Python/lldbsuite/test/functionalities/tty/TestTerminal.py
index 5697c2c37283..cebba1b4c573 100644
--- a/packages/Python/lldbsuite/test/functionalities/tty/TestTerminal.py
+++ b/packages/Python/lldbsuite/test/functionalities/tty/TestTerminal.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import unittest2
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class LaunchInTerminalTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/functionalities/type_completion/TestTypeCompletion.py b/packages/Python/lldbsuite/test/functionalities/type_completion/TestTypeCompletion.py
index 5a238b7d3542..2bf10204ea6b 100644
--- a/packages/Python/lldbsuite/test/functionalities/type_completion/TestTypeCompletion.py
+++ b/packages/Python/lldbsuite/test/functionalities/type_completion/TestTypeCompletion.py
@@ -8,14 +8,15 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TypeCompletionTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureIcc # often fails with 'NameAndAddress should be valid'
+ @expectedFailureAll(compiler="icc", bugnumber="often fails with 'NameAndAddress should be valid.")
# Fails with gcc 4.8.1 with llvm.org/pr15301 LLDB prints incorrect sizes of STL containers
def test_with_run_command(self):
"""Check that types only get completed when necessary."""
diff --git a/packages/Python/lldbsuite/test/functionalities/type_lookup/TestTypeLookup.py b/packages/Python/lldbsuite/test/functionalities/type_lookup/TestTypeLookup.py
index ca0b1f1d1e53..774eb437b78e 100644
--- a/packages/Python/lldbsuite/test/functionalities/type_lookup/TestTypeLookup.py
+++ b/packages/Python/lldbsuite/test/functionalities/type_lookup/TestTypeLookup.py
@@ -6,11 +6,12 @@ from __future__ import print_function
+import datetime
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import datetime
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TypeLookupTestCase(TestBase):
@@ -41,3 +42,4 @@ class TypeLookupTestCase(TestBase):
self.expect('type lookup NSURL', substrs=['NSURL'])
self.expect('type lookup NSArray', substrs=['NSArray'])
self.expect('type lookup NSObject', substrs=['NSObject', 'isa'])
+ self.expect('type lookup PleaseDontBeARealTypeThatExists', substrs=["no type was found matching 'PleaseDontBeARealTypeThatExists'"])
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/ehframe/Makefile b/packages/Python/lldbsuite/test/functionalities/unwind/ehframe/Makefile
new file mode 100644
index 000000000000..289d25698ffb
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/ehframe/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+CFLAGS ?= -g -fomit-frame-pointer
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/ehframe/TestEhFrameUnwind.py b/packages/Python/lldbsuite/test/functionalities/unwind/ehframe/TestEhFrameUnwind.py
new file mode 100644
index 000000000000..e17d5d36d394
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/ehframe/TestEhFrameUnwind.py
@@ -0,0 +1,51 @@
+"""
+Test that we can backtrace correctly from Non ABI functions on the stack
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class EHFrameBasedUnwind(TestBase):
+ mydir = TestBase.compute_mydir(__file__)
+
+
+ @skipUnlessPlatform(['linux'])
+ @skipIf(archs=["aarch64", "arm", "i386", "i686"])
+ def test (self):
+ """Test that we can backtrace correctly from Non ABI functions on the stack"""
+ self.build()
+ self.setTearDownCleanup()
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+
+ self.assertTrue(target, VALID_TARGET)
+
+ lldbutil.run_break_set_by_symbol (self, "func")
+
+ process = target.LaunchSimple (["abc", "xyz"], None, self.get_process_working_directory())
+
+ if not process:
+ self.fail("SBTarget.Launch() failed")
+
+ if process.GetState() != lldb.eStateStopped:
+ self.fail("Process should be in the 'stopped' state, "
+ "instead the actual state is: '%s'" %
+ lldbutil.state_type_to_str(process.GetState()))
+
+ stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
+ self.expect(stacktraces, exe=False,
+ substrs = ['(int)argc=3'])
+
+ self.runCmd("thread step-inst")
+
+ stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
+ self.expect(stacktraces, exe=False,
+ substrs = ['(int)argc=3'])
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/ehframe/main.c b/packages/Python/lldbsuite/test/functionalities/unwind/ehframe/main.c
new file mode 100644
index 000000000000..f62f7d814f38
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/ehframe/main.c
@@ -0,0 +1,20 @@
+void func() {
+ __asm__ (
+ "pushq $0x10;"
+ ".cfi_def_cfa_offset 16;"
+ "jmp label;"
+ "movq $0x48, %rax;"
+"label: subq $0x38, %rax;"
+ "movq $0x48, %rcx;"
+ "movq $0x48, %rdx;"
+ "movq $0x48, %rax;"
+ "popq %rax;"
+ );
+
+}
+
+
+int main(int argc, char const *argv[])
+{
+ func();
+} \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py b/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py
index c0a311f7ac9e..62c6c16080a3 100644
--- a/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py
@@ -8,13 +8,13 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class NoreturnUnwind(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailurei386("llvm.org/pr25338")
@skipIfWindows # clang-cl does not support gcc style attributes.
def test (self):
"""Test that we can backtrace correctly with 'noreturn' functions on the stack"""
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/TestSigtrampUnwind.py b/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/TestSigtrampUnwind.py
index ddfb1122b6f1..d2b36412f1f0 100644
--- a/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/TestSigtrampUnwind.py
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/sigtramp/TestSigtrampUnwind.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SigtrampUnwind(TestBase):
mydir = TestBase.compute_mydir(__file__)
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/standard/TestStandardUnwind.py b/packages/Python/lldbsuite/test/functionalities/unwind/standard/TestStandardUnwind.py
index 3f88e7b6e1aa..20532c6fc675 100644
--- a/packages/Python/lldbsuite/test/functionalities/unwind/standard/TestStandardUnwind.py
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/standard/TestStandardUnwind.py
@@ -17,8 +17,9 @@ from __future__ import print_function
import unittest2
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
test_source_dirs = ["."]
diff --git a/packages/Python/lldbsuite/test/functionalities/value_md5_crash/TestValueMD5Crash.py b/packages/Python/lldbsuite/test/functionalities/value_md5_crash/TestValueMD5Crash.py
index 763ecc94c2eb..cbea7d22cc44 100644
--- a/packages/Python/lldbsuite/test/functionalities/value_md5_crash/TestValueMD5Crash.py
+++ b/packages/Python/lldbsuite/test/functionalities/value_md5_crash/TestValueMD5Crash.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ValueMD5CrashTestCase(TestBase):
@@ -21,7 +22,7 @@ class ValueMD5CrashTestCase(TestBase):
# Find the line number to break at.
self.line = line_number('main.cpp', '// break here')
- @expectedFailureWindows("llvm.org/pr24663")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24663")
def test_with_run_command(self):
"""Verify that the hash computing logic for ValueObject's values can't crash us."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/TestWatchLocation.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/TestWatchLocation.py
index f0a0b5ab99d0..933f21a90bbf 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/TestWatchLocation.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/TestWatchLocation.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class HelloWatchLocationTestCase(TestBase):
@@ -30,8 +31,11 @@ class HelloWatchLocationTestCase(TestBase):
self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
- @expectedFailureAll(archs=['mips', 'mipsel', 'mips64', 'mips64el']) # Most of the MIPS boards provide only one H/W watchpoints, and S/W watchpoints are not supported yet
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAll(triple = re.compile('^mips')) # Most of the MIPS boards provide only one H/W watchpoints, and S/W watchpoints are not supported yet
+ @expectedFailureAll(archs=['s390x']) # SystemZ also currently supports only one H/W watchpoint
+ @expectedFailureAll(oslist=["linux"], archs=["arm", "aarch64"], bugnumber="llvm.org/pr27795")
+ @skipIfDarwin
def test_hello_watchlocation(self):
"""Test watching a location with '-s size' option."""
self.build(dictionary=self.d)
@@ -52,9 +56,6 @@ class HelloWatchLocationTestCase(TestBase):
'stop reason = breakpoint'])
# Now let's set a write-type watchpoint pointed to by 'g_char_ptr'.
- # The main.cpp, by design, misbehaves by not following the agreed upon
- # protocol of using a mutex while accessing the global pool and by not
- # incrmenting the global pool by 2.
self.expect("watchpoint set expression -w write -s 1 -- g_char_ptr", WATCHPOINT_CREATED,
substrs = ['Watchpoint created', 'size = 1', 'type = w'])
# Get a hold of the watchpoint id just created, it is used later on to
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/main.cpp b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/main.cpp
index 59b0afc6d5f7..e20a6d988c84 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchlocation/main.cpp
@@ -43,15 +43,13 @@ uint32_t
access_pool (bool flag = false)
{
static std::mutex g_access_mutex;
- if (!flag)
- g_access_mutex.lock();
+ g_access_mutex.lock();
char old_val = *g_char_ptr;
if (flag)
do_bad_thing_with_location(g_char_ptr, old_val + 1);
- if (!flag)
- g_access_mutex.unlock();
+ g_access_mutex.unlock();
return *g_char_ptr;
}
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py
index 57467c38d5f8..5214c7f5e089 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class HelloWatchpointTestCase(TestBase):
@@ -31,7 +32,7 @@ class HelloWatchpointTestCase(TestBase):
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
def test_hello_watchpoint_using_watchpoint_set(self):
"""Test a simple sequence of watchpoint creation and watchpoint hit."""
self.build(dictionary=self.d)
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py
index 2318214a0d5c..af8306c9a20e 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py
@@ -9,15 +9,16 @@ from __future__ import print_function
import os, time
import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class WatchpointForMultipleThreadsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
def test_watchpoint_multiple_threads(self):
"""Test that lldb watchpoint works for multiple threads."""
self.build()
@@ -25,7 +26,7 @@ class WatchpointForMultipleThreadsTestCase(TestBase):
self.hello_multiple_threads()
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
def test_watchpoint_multiple_threads_wp_set_and_then_delete(self):
"""Test that lldb watchpoint works for multiple threads, and after the watchpoint is deleted, the watchpoint event should no longer fires."""
self.build()
@@ -57,9 +58,6 @@ class WatchpointForMultipleThreadsTestCase(TestBase):
'stop reason = breakpoint'])
# Now let's set a write-type watchpoint for variable 'g_val'.
- # The main.cpp, by design, misbehaves by not following the agreed upon
- # protocol of using a mutex while accessing the global pool and by not
- # writing to the variable.
self.expect("watchpoint set variable -w write g_val", WATCHPOINT_CREATED,
substrs = ['Watchpoint created', 'size = 4', 'type = w'])
@@ -101,9 +99,6 @@ class WatchpointForMultipleThreadsTestCase(TestBase):
'stop reason = breakpoint'])
# Now let's set a write-type watchpoint for variable 'g_val'.
- # The main.cpp, by design, misbehaves by not following the agreed upon
- # protocol of using a mutex while accessing the global pool and by not
- # writing to the variable.
self.expect("watchpoint set variable -w write g_val", WATCHPOINT_CREATED,
substrs = ['Watchpoint created', 'size = 4', 'type = w'])
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/main.cpp b/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/main.cpp
index 8a31041f8fca..7f2e5e6e6cb5 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/main.cpp
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_threads/main.cpp
@@ -23,8 +23,7 @@ uint32_t
access_pool (bool flag = false)
{
static std::mutex g_access_mutex;
- if (!flag)
- g_access_mutex.lock();
+ g_access_mutex.lock();
uint32_t old_val = g_val;
if (flag)
@@ -33,17 +32,14 @@ access_pool (bool flag = false)
g_val = old_val + 1;
}
- if (!flag)
- g_access_mutex.unlock();
+ g_access_mutex.unlock();
return g_val;
}
void
thread_func (uint32_t thread_index)
{
- // Break here in order to allow the thread
- // to inherit the global watchpoint state.
- printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);
+ printf ("%s (thread index = %u) starting...\n", __FUNCTION__, thread_index);
uint32_t count = 0;
uint32_t val;
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py
index f51da36b72d7..22011f11352c 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py
@@ -5,8 +5,9 @@ from __future__ import print_function
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestStepOverWatchpoint(TestBase):
@@ -17,8 +18,9 @@ class TestStepOverWatchpoint(TestBase):
return ['basic_process']
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureLinux(bugnumber="llvm.org/pr26031", archs=['arm'])
- @expectedFailureWindows("llvm.org/pr24446")
+ @expectedFailureAll(oslist=["linux"], archs=['aarch64', 'arm'], bugnumber="llvm.org/pr26031")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAll(archs=['s390x']) # Read-write watchpoints not supported on SystemZ
def test(self):
"""Test stepping over watchpoints."""
self.build()
@@ -73,7 +75,7 @@ class TestStepOverWatchpoint(TestBase):
# Most of the MIPS boards provide only one H/W watchpoints, and S/W watchpoints are not supported yet
arch = self.getArchitecture()
- if arch in ['mips', 'mipsel', 'mips64', 'mips64el']:
+ if re.match("^mips",arch):
self.runCmd("watchpoint delete 1")
# resolve_location=True, read=False, write=True
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/TestWatchpointCommands.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/TestWatchpointCommands.py
index 339de45a085a..4ce05af96e2e 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/TestWatchpointCommands.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/TestWatchpointCommands.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class WatchpointCommandsTestCase(TestBase):
@@ -30,7 +31,8 @@ class WatchpointCommandsTestCase(TestBase):
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAll(archs=['s390x']) # Read-write watchpoints not supported on SystemZ
def test_rw_watchpoint(self):
"""Test read_write watchpoint and expect to stop two times."""
self.build(dictionary=self.d)
@@ -90,7 +92,8 @@ class WatchpointCommandsTestCase(TestBase):
substrs = ['hit_count = 2'])
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAll(archs=['s390x']) # Read-write watchpoints not supported on SystemZ
def test_rw_watchpoint_delete(self):
"""Test delete watchpoint and expect not to stop for watchpoint."""
self.build(dictionary=self.d)
@@ -135,7 +138,8 @@ class WatchpointCommandsTestCase(TestBase):
substrs = ['exited'])
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAll(archs=['s390x']) # Read-write watchpoints not supported on SystemZ
def test_rw_watchpoint_set_ignore_count(self):
"""Test watchpoint ignore count and expect to not to stop at all."""
self.build(dictionary=self.d)
@@ -184,7 +188,8 @@ class WatchpointCommandsTestCase(TestBase):
substrs = ['hit_count = 2', 'ignore_count = 2'])
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAll(archs=['s390x']) # Read-write watchpoints not supported on SystemZ
def test_rw_disable_after_first_stop(self):
"""Test read_write watchpoint but disable it after the first stop."""
self.build(dictionary=self.d)
@@ -243,7 +248,8 @@ class WatchpointCommandsTestCase(TestBase):
substrs = ['hit_count = 1'])
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAll(archs=['s390x']) # Read-write watchpoints not supported on SystemZ
def test_rw_disable_then_enable(self):
"""Test read_write watchpoint, disable initially, then enable it."""
self.build(dictionary=self.d)
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py
index f2bf90866330..ee276dd5687f 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class WatchpointLLDBCommandTestCase(TestBase):
@@ -29,7 +30,8 @@ class WatchpointLLDBCommandTestCase(TestBase):
self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["linux"], archs=["aarch64"], bugnumber="llvm.org/pr27710")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
def test_watchpoint_command(self):
"""Test 'watchpoint command'."""
self.build(dictionary=self.d)
@@ -83,7 +85,8 @@ class WatchpointLLDBCommandTestCase(TestBase):
substrs = ['(int32_t)', 'cookie = 777'])
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["linux"], archs=["aarch64"], bugnumber="llvm.org/pr27710")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
def test_watchpoint_command_can_disable_a_watchpoint(self):
"""Test that 'watchpoint command' action can disable a watchpoint after it is triggered."""
self.build(dictionary=self.d)
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py
index a476aebb8db9..f6ea4fc16861 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class WatchpointPythonCommandTestCase(TestBase):
@@ -29,8 +30,9 @@ class WatchpointPythonCommandTestCase(TestBase):
self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
@skipIfFreeBSD # timing out on buildbot
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureAll(oslist=["linux"], archs=["aarch64"], bugnumber="llvm.org/pr27710")
def test_watchpoint_command(self):
"""Test 'watchpoint command'."""
self.build(dictionary=self.d)
@@ -85,3 +87,57 @@ class WatchpointPythonCommandTestCase(TestBase):
# The watchpoint command "forced" our global variable 'cookie' to become 777.
self.expect("frame variable --show-globals cookie",
substrs = ['(int32_t)', 'cookie = 777'])
+
+ @skipIfFreeBSD # timing out on buildbot
+ @expectedFailureAll(bugnumber="llvm.org/pr28055: continue in watchpoint commands disables the watchpoint")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureAll(oslist=["linux"], archs=["aarch64"], bugnumber="llvm.org/pr27710")
+ def test_continue_in_watchpoint_command(self):
+ """Test continue in a watchpoint command."""
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+ lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
+# self.expect("breakpoint set -l %d" % self.line, BREAKPOINT_CREATED,
+# startstr = "Breakpoint created: 1: file ='%s', line = %d, locations = 1" %
+# (self.source, self.line))#
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # Now let's set a write-type watchpoint for 'global'.
+ self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = 4', 'type = w',
+ '%s:%d' % (self.source, self.decl)])
+
+ cmd_script_file = os.path.join(os.getcwd(), "watchpoint_command.py")
+ self.runCmd("command script import '%s'"%(cmd_script_file))
+
+ self.runCmd('watchpoint command add -F watchpoint_command.watchpoint_command')
+
+ # List the watchpoint command we just added.
+ self.expect("watchpoint command list 1",
+ substrs = ['watchpoint_command.watchpoint_command'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped again due to the watchpoint (write type).
+ # The stop reason of the thread should be watchpoint.
+ self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stop reason = watchpoint'])
+
+ # We should have hit the watchpoint once, set cookie to 888, then continued to the
+ # second hit and set it to 999
+ self.expect("frame variable --show-globals cookie",
+ substrs = ['(int32_t)', 'cookie = 999'])
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/watchpoint_command.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/watchpoint_command.py
new file mode 100644
index 000000000000..575a5160d219
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/command/watchpoint_command.py
@@ -0,0 +1,14 @@
+import lldb
+
+num_hits = 0
+def watchpoint_command (frame, wp, dict):
+ global num_hits
+ if num_hits == 0:
+ print ("I stopped the first time")
+ frame.EvaluateExpression("cookie = 888")
+ num_hits += 1
+ frame.thread.process.Continue()
+ else:
+ print ("I stopped the %d time"%(num_hits))
+ frame.EvaluateExpression("cookie = 999")
+
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/TestWatchpointConditionCmd.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/TestWatchpointConditionCmd.py
index 355204a4ce1e..64e01e5cb937 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/TestWatchpointConditionCmd.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_commands/condition/TestWatchpointConditionCmd.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class WatchpointConditionCmdTestCase(TestBase):
@@ -29,7 +30,8 @@ class WatchpointConditionCmdTestCase(TestBase):
self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["linux"], archs=["aarch64"], bugnumber="llvm.org/pr27710")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
def test_watchpoint_cond(self):
"""Test watchpoint condition."""
self.build(dictionary=self.d)
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/TestWatchpointEvents.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/TestWatchpointEvents.py
index e4d6e019c20e..fdeb4b8fa3b5 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/TestWatchpointEvents.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_events/TestWatchpointEvents.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestWatchpointEvents (TestBase):
@@ -21,7 +22,8 @@ class TestWatchpointEvents (TestBase):
@add_test_categories(['pyapi'])
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["linux"], archs=["aarch64"], bugnumber="llvm.org/pr27710")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
def test_with_python_api(self):
"""Test that adding, deleting and modifying watchpoints sends the appropriate events."""
self.build()
@@ -58,7 +60,7 @@ class TestWatchpointEvents (TestBase):
self.listener.StartListeningForEvents (self.target_bcast, lldb.SBTarget.eBroadcastBitWatchpointChanged)
error = lldb.SBError()
- local_watch = local_var.Watch(True, True, True, error)
+ local_watch = local_var.Watch(True, False, True, error)
if not error.Success():
self.fail ("Failed to make watchpoint for local_var: %s"%(error.GetCString()))
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/TestValueOfVectorVariable.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/TestValueOfVectorVariable.py
index 73752d2d18d5..c66ddb512884 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/TestValueOfVectorVariable.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/TestValueOfVectorVariable.py
@@ -8,15 +8,16 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestValueOfVectorVariableTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
def test_value_of_vector_variable_using_watchpoint_set(self):
"""Test verify displayed value of vector variable."""
self.build(dictionary=self.d)
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/main.c b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/main.c
index 98f8c477eb31..ac2370e32d2a 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/main.c
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_on_vectors/main.c
@@ -6,7 +6,7 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-typedef char v4i8 __attribute__ ((vector_size(4)));
+typedef signed char v4i8 __attribute__ ((vector_size(4)));
v4i8 global_vector = {1, 2, 3, 4};
int
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchLocationWithWatchSet.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchLocationWithWatchSet.py
index 9301a6f9fd00..735a5678c4f9 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchLocationWithWatchSet.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchLocationWithWatchSet.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class WatchLocationUsingWatchpointSetTestCase(TestBase):
@@ -27,8 +28,8 @@ class WatchLocationUsingWatchpointSetTestCase(TestBase):
# Build dictionary to have unique executable names for each test method.
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureLinux(bugnumber="llvm.org/pr26031", archs=['arm'])
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["linux"], archs=['aarch64', 'arm'], bugnumber="llvm.org/pr26031")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
def test_watchlocation_using_watchpoint_set(self):
"""Test watching a location with 'watchpoint set expression -w write -s size' option."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
index 27c759e6fb64..43597ec28f59 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
@@ -8,6 +8,7 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
@@ -24,6 +25,7 @@ class WatchpointSetErrorTestCase(TestBase):
self.line = line_number(self.source, '// Set break point at this line.')
# Build dictionary to have unique executable names for each test method.
+ @expectedFailureAll(oslist=["windows"])
def test_error_cases_with_watchpoint_set(self):
"""Test error cases with the 'watchpoint set' command."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/c/inlines/Makefile b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_size/Makefile
index c5b0d18f995d..b09a579159d4 100644
--- a/packages/Python/lldbsuite/test/lang/c/inlines/Makefile
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_size/Makefile
@@ -1,5 +1,5 @@
LEVEL = ../../../make
-C_SOURCES := inlines.c
+C_SOURCES := main.c
include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_size/TestWatchpointSizes.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_size/TestWatchpointSizes.py
new file mode 100644
index 000000000000..55e36649ce10
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_size/TestWatchpointSizes.py
@@ -0,0 +1,117 @@
+"""
+Test watchpoint size cases (1-byte, 2-byte, 4-byte).
+Make sure we can watch all bytes, words or double words individually
+when they are packed in a 8-byte region.
+
+"""
+
+from __future__ import print_function
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class WatchpointSizeTestCase(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ # Source filename.
+ self.source = 'main.c'
+
+ # Output filename.
+ self.exe_name = 'a.out'
+ self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAll(archs=['s390x']) # Read-write watchpoints not supported on SystemZ
+ def test_byte_size_watchpoints_with_byte_selection(self):
+ """Test to selectively watch different bytes in a 8-byte array."""
+ self.run_watchpoint_size_test('byteArray', 8, '1')
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAll(archs=['s390x']) # Read-write watchpoints not supported on SystemZ
+ def test_two_byte_watchpoints_with_word_selection(self):
+ """Test to selectively watch different words in an 8-byte word array."""
+ self.run_watchpoint_size_test('wordArray', 4, '2')
+
+ @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAll(archs=['s390x']) # Read-write watchpoints not supported on SystemZ
+ def test_four_byte_watchpoints_with_dword_selection(self):
+ """Test to selectively watch two double words in an 8-byte dword array."""
+ self.run_watchpoint_size_test('dwordArray', 2, '4')
+
+ def run_watchpoint_size_test(self, arrayName, array_size, watchsize):
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Detect line number after which we are going to increment arrayName.
+ loc_line = line_number('main.c', '// About to write ' + arrayName)
+
+ # Set a breakpoint on the line detected above.
+ lldbutil.run_break_set_by_file_and_line (self, "main.c",loc_line,
+ num_expected_locations=1, loc_exact=True)
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ for i in range(array_size):
+ # We should be stopped again due to the breakpoint.
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
+
+ # Set a read_write type watchpoint arrayName
+ watch_loc=arrayName+"[" + str(i) + "]"
+ self.expect("watchpoint set variable -w read_write " + watch_loc,
+ WATCHPOINT_CREATED,
+ substrs = ['Watchpoint created', 'size = ' + watchsize, 'type = rw'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should be 0 initially.
+ self.expect("watchpoint list -v", substrs = ['hit_count = 0'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped due to the watchpoint.
+ # The stop reason of the thread should be watchpoint.
+ self.expect("thread list", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stopped', 'stop reason = watchpoint'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should now be 1.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 1'])
+
+ self.runCmd("process continue")
+
+ # We should be stopped due to the watchpoint.
+ # The stop reason of the thread should be watchpoint.
+ self.expect("thread list", STOPPED_DUE_TO_WATCHPOINT,
+ substrs = ['stopped', 'stop reason = watchpoint'])
+
+ # Use the '-v' option to do verbose listing of the watchpoint.
+ # The hit count should now be 1.
+ # Verify hit_count has been updated after value has been read.
+ self.expect("watchpoint list -v",
+ substrs = ['hit_count = 2'])
+
+ # Delete the watchpoint immediately, but set auto-confirm to true first.
+ self.runCmd("settings set auto-confirm true")
+ self.expect("watchpoint delete", substrs = ['All watchpoints removed.'])
+ # Restore the original setting of auto-confirm.
+ self.runCmd("settings clear auto-confirm")
+
+ self.runCmd("process continue")
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_size/main.c b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_size/main.c
new file mode 100644
index 000000000000..ed9fed1e2113
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_size/main.c
@@ -0,0 +1,66 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <stdint.h>
+
+uint64_t pad0 = 0;
+uint8_t byteArray[8] = {0};
+uint64_t pad1 = 0;
+uint16_t wordArray[4] = {0};
+uint64_t pad2 = 0;
+uint32_t dwordArray[2] = {0};
+
+int main(int argc, char** argv) {
+
+ int i;
+ uint8_t localByte;
+ uint16_t localWord;
+ uint32_t localDword;
+
+ for (i = 0; i < 8; i++)
+ {
+ printf("About to write byteArray[%d] ...\n", i); // About to write byteArray
+ pad0++;
+ byteArray[i] = 7;
+ pad1++;
+ localByte = byteArray[i]; // Here onwards we should'nt be stopped in loop
+ byteArray[i]++;
+ localByte = byteArray[i];
+ }
+
+ pad0 = 0;
+ pad1 = 0;
+
+ for (i = 0; i < 4; i++)
+ {
+ printf("About to write wordArray[%d] ...\n", i); // About to write wordArray
+ pad0++;
+ wordArray[i] = 7;
+ pad1++;
+ localWord = wordArray[i]; // Here onwards we should'nt be stopped in loop
+ wordArray[i]++;
+ localWord = wordArray[i];
+ }
+
+ pad0 = 0;
+ pad1 = 0;
+
+ for (i = 0; i < 2; i++)
+ {
+ printf("About to write dwordArray[%d] ...\n", i); // About to write dwordArray
+ pad0++;
+ dwordArray[i] = 7;
+ pad1++;
+ localDword = dwordArray[i]; // Here onwards we shouldn't be stopped in loop
+ dwordArray[i]++;
+ localDword = dwordArray[i];
+ }
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/help/TestApropos.py b/packages/Python/lldbsuite/test/help/TestApropos.py
new file mode 100644
index 000000000000..7b2e69938a0e
--- /dev/null
+++ b/packages/Python/lldbsuite/test/help/TestApropos.py
@@ -0,0 +1,22 @@
+"""
+Test some lldb apropos commands.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class AproposCommandTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @no_debug_info_test
+ def test_apropos_variable(self):
+ """Test that 'apropos variable' prints the fully qualified command name"""
+ self.expect('apropos variable', substrs=['frame variable', 'target variable', 'watchpoint set variable'])
diff --git a/packages/Python/lldbsuite/test/help/TestHelp.py b/packages/Python/lldbsuite/test/help/TestHelp.py
index f51b6aa59f12..f4e9faff0edf 100644
--- a/packages/Python/lldbsuite/test/help/TestHelp.py
+++ b/packages/Python/lldbsuite/test/help/TestHelp.py
@@ -10,7 +10,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class HelpCommandTestCase(TestBase):
@@ -80,7 +82,7 @@ class HelpCommandTestCase(TestBase):
def test_help_version(self):
"""Test 'help version' and 'version' commands."""
self.expect("help version",
- substrs = ['Show version of LLDB debugger.'])
+ substrs = ['Show the LLDB debugger version.'])
version_str = self.version_number_string()
import re
match = re.match('[0-9]+', version_str)
@@ -163,3 +165,49 @@ class HelpCommandTestCase(TestBase):
substrs = ['The following subcommands are supported:'],
patterns = ['expression +--',
'variable +--'])
+
+ @no_debug_info_test
+ def test_help_po_hides_options(self):
+ """Test that 'help po' does not show all the options for expression"""
+ self.expect("help po",
+ substrs = ['--show-all-children', '--object-description'], matching=False)
+
+ @no_debug_info_test
+ def test_help_run_hides_options(self):
+ """Test that 'help run' does not show all the options for process launch"""
+ self.expect("help run",
+ substrs = ['--arch', '--environment'], matching=False)
+
+ @no_debug_info_test
+ def test_help_next_shows_options(self):
+ """Test that 'help next' shows all the options for thread step-over"""
+ self.expect("help next",
+ substrs = ['--python-class','--run-mode'], matching=True)
+
+ @no_debug_info_test
+ def test_help_provides_alternatives(self):
+ """Test that help on commands that don't exist provides information on additional help avenues"""
+ self.expect("help thisisnotadebuggercommand",
+ substrs = ["'thisisnotadebuggercommand' is not a known command.",
+ "Try 'help' to see a current list of commands.",
+ "Try 'apropos thisisnotadebuggercommand' for a list of related commands.",
+ "Try 'type lookup thisisnotadebuggercommand' for information on types, methods, functions, modules, etc."], error=True)
+
+ self.expect("help process thisisnotadebuggercommand",
+ substrs = ["'process thisisnotadebuggercommand' is not a known command.",
+ "Try 'help' to see a current list of commands.",
+ "Try 'apropos thisisnotadebuggercommand' for a list of related commands.",
+ "Try 'type lookup thisisnotadebuggercommand' for information on types, methods, functions, modules, etc."])
+
+ @no_debug_info_test
+ def test_custom_help_alias(self):
+ """Test that aliases pick up custom help text."""
+ def cleanup():
+ self.runCmd('command unalias afriendlyalias', check=False)
+ self.runCmd('command unalias averyfriendlyalias', check=False)
+
+ self.addTearDownHook(cleanup)
+ self.runCmd('command alias --help "I am a friendly alias" -- afriendlyalias help')
+ self.expect("help afriendlyalias", matching=True, substrs = ['I am a friendly alias'])
+ self.runCmd('command alias --long-help "I am a very friendly alias" -- averyfriendlyalias help')
+ self.expect("help averyfriendlyalias", matching=True, substrs = ['I am a very friendly alias'])
diff --git a/packages/Python/lldbsuite/test/issue_verification/TestInvalidDecorator.py.park b/packages/Python/lldbsuite/test/issue_verification/TestInvalidDecorator.py.park
new file mode 100644
index 000000000000..7f5c4cb79cf5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/issue_verification/TestInvalidDecorator.py.park
@@ -0,0 +1,13 @@
+from __future__ import print_function
+from lldbsuite.test import lldbtest
+from lldbsuite.test import decorators
+
+
+class NonExistentDecoratorTestCase(lldbtest.TestBase):
+
+ mydir = lldbtest.TestBase.compute_mydir(__file__)
+
+ @decorators.nonExistentDecorator(bugnumber="yt/1300")
+ def test(self):
+ """Verify non-existent decorators are picked up by test runner."""
+ pass
diff --git a/packages/Python/lldbsuite/test/issue_verification/TestRerunTimeout.py.park b/packages/Python/lldbsuite/test/issue_verification/TestRerunTimeout.py.park
index 1cf5373ac491..a8f5542ae2f5 100644
--- a/packages/Python/lldbsuite/test/issue_verification/TestRerunTimeout.py.park
+++ b/packages/Python/lldbsuite/test/issue_verification/TestRerunTimeout.py.park
@@ -3,19 +3,21 @@ from __future__ import print_function
import time
-import lldbsuite.test.lldbtest as lldbtest
+import lldbsuite.test.decorators as decorators
import rerun_base
class RerunTimeoutTestCase(rerun_base.RerunBaseTestCase):
- @lldbtest.no_debug_info_test
+ @decorators.no_debug_info_test
def test_timeout_rerun_succeeds(self):
- """Tests that timeout logic kicks in and is picked up."""
+ """Tests that the timeout logic kicks in and that this timeout is picked up."""
if not self.should_generate_issue():
# We pass this time.
return
+
# We time out this time.
while True:
+ # noinspection PyBroadException
try:
time.sleep(1)
except:
diff --git a/packages/Python/lldbsuite/test/lang/c/anonymous/TestAnonymous.py b/packages/Python/lldbsuite/test/lang/c/anonymous/TestAnonymous.py
index 7cb66ba8238b..e6f1092c702a 100644
--- a/packages/Python/lldbsuite/test/lang/c/anonymous/TestAnonymous.py
+++ b/packages/Python/lldbsuite/test/lang/c/anonymous/TestAnonymous.py
@@ -6,14 +6,15 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class AnonymousTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipIfIcc # llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by ICC
+ @skipIf(compiler="icc", bugnumber="llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by ICC")
def test_expr_nest(self):
self.build()
self.common_setup(self.line0)
@@ -36,7 +37,7 @@ class AnonymousTestCase(TestBase):
self.expect("expression c->grandchild.b", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["= 2"])
- @skipIfIcc # llvm.org/pr15036: This particular regression was introduced by r181498
+ @skipIf(compiler="icc", bugnumber="llvm.org/pr15036: This particular regression was introduced by r181498")
def test_expr_grandchild(self):
self.build()
self.common_setup(self.line2)
@@ -61,7 +62,7 @@ class AnonymousTestCase(TestBase):
self.expect("expression z.y", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["(type_y) $", "dummy = 2"])
- @expectedFailureWindows('llvm.org/pr21550')
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21550")
def test_expr_null(self):
self.build()
self.common_setup(self.line2)
@@ -111,6 +112,17 @@ class AnonymousTestCase(TestBase):
if not error.Success() or value != 0:
self.fail ("failed to get the correct value for element a in n")
+ def test_nest_flat(self):
+ self.build()
+ self.common_setup(self.line2)
+
+ # These should display correctly.
+ self.expect('frame variable n --flat',
+ substrs = ['n.a = 0',
+ 'n.b = 2',
+ 'n.foo.c = 0',
+ 'n.foo.d = 4'])
+
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
diff --git a/packages/Python/lldbsuite/test/lang/c/array_types/TestArrayTypes.py b/packages/Python/lldbsuite/test/lang/c/array_types/TestArrayTypes.py
index e835fb096496..5a4907465682 100644
--- a/packages/Python/lldbsuite/test/lang/c/array_types/TestArrayTypes.py
+++ b/packages/Python/lldbsuite/test/lang/c/array_types/TestArrayTypes.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ArrayTypesTestCase(TestBase):
@@ -100,11 +101,8 @@ class ArrayTypesTestCase(TestBase):
"executable = a.out"])
# The stop reason of the thread should be breakpoint.
- thread = process.GetThreadAtIndex(0)
- if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
- from lldbsuite.test.lldbutil import stop_reason_to_str
- self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
- stop_reason_to_str(thread.GetStopReason()))
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
# Sanity check the print representation of thread.
thr = str(thread)
@@ -120,7 +118,7 @@ class ArrayTypesTestCase(TestBase):
substrs = [tidstr])
# The breakpoint should have a hit count of 1.
- self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE)
+ self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE)
# The breakpoint should be resolved by now.
bp = str(breakpoint)
diff --git a/packages/Python/lldbsuite/test/lang/c/bitfields/TestBitfields.py b/packages/Python/lldbsuite/test/lang/c/bitfields/TestBitfields.py
index de7a333a18fa..30175c5e1c15 100644
--- a/packages/Python/lldbsuite/test/lang/c/bitfields/TestBitfields.py
+++ b/packages/Python/lldbsuite/test/lang/c/bitfields/TestBitfields.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class BitfieldsTestCase(TestBase):
@@ -95,8 +96,17 @@ class BitfieldsTestCase(TestBase):
self.expect("expr (more_bits.d)", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['uint8_t', '\\0'])
+ self.expect("expr (packed.a)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['char', "'a'"])
+ self.expect("expr (packed.b)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint32_t', "10"])
+ self.expect("expr/x (packed.c)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint32_t', "7112233"])
+
+
@add_test_categories(['pyapi'])
@skipIfWindows # BitFields exhibit crashes in record layout on Windows (http://llvm.org/pr21800)
+ @expectedFailureAll("llvm.org/pr27510", oslist=["linux"], compiler="clang", compiler_version=[">=", "3.9"])
def test_and_python_api(self):
"""Use Python APIs to inspect a bitfields variable."""
self.build()
@@ -112,14 +122,11 @@ class BitfieldsTestCase(TestBase):
self.assertTrue(process, PROCESS_IS_VALID)
# The stop reason of the thread should be breakpoint.
- thread = target.GetProcess().GetThreadAtIndex(0)
- if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
- from lldbsuite.test.lldbutil import stop_reason_to_str
- self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
- stop_reason_to_str(thread.GetStopReason()))
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
# The breakpoint should have a hit count of 1.
- self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE)
+ self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE)
# Lookup the "bits" variable which contains 8 bitfields.
frame = thread.GetFrameAtIndex(0)
diff --git a/packages/Python/lldbsuite/test/lang/c/bitfields/main.c b/packages/Python/lldbsuite/test/lang/c/bitfields/main.c
index 26c0176d759c..236c926d81bd 100644
--- a/packages/Python/lldbsuite/test/lang/c/bitfields/main.c
+++ b/packages/Python/lldbsuite/test/lang/c/bitfields/main.c
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include <stdint.h>
#include <stdio.h>
+
int main (int argc, char const *argv[])
{
struct Bits
@@ -62,6 +63,19 @@ int main (int argc, char const *argv[])
more_bits.c = 1;
more_bits.d = 0;
+#pragma pack(1)
+ struct PackedBits
+ {
+ char a;
+ uint32_t b : 5,
+ c : 27;
+ };
+#pragma pack()
+ struct PackedBits packed;
+ packed.a = 'a';
+ packed.b = 10;
+ packed.c = 0x7112233;
+
return 0; //// Set break point at this line.
}
diff --git a/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py b/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py
index 8f1c3be22836..0cc9456af32e 100644
--- a/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py
+++ b/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py
@@ -8,6 +8,7 @@ import unittest2
import os, time
import lldb
from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
class BlocksTestCase(TestBase):
@@ -21,9 +22,8 @@ class BlocksTestCase(TestBase):
# Find the line numbers to break at.
self.lines.append(line_number('main.c', '// Set breakpoint 0 here.'))
self.lines.append(line_number('main.c', '// Set breakpoint 1 here.'))
-
- @unittest2.expectedFailure("rdar://problem/10413887 - Call blocks in expressions")
- def test_expr(self):
+
+ def launch_common(self):
self.build()
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
@@ -35,6 +35,10 @@ class BlocksTestCase(TestBase):
lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
self.wait_for_breakpoint()
+
+ @skipUnlessDarwin
+ def test_expr(self):
+ self.launch_common()
self.expect("expression a + b", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["= 7"])
@@ -47,6 +51,14 @@ class BlocksTestCase(TestBase):
# This should display correctly.
self.expect("expression (int)neg (-12)", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["= 12"])
+
+ @skipUnlessDarwin
+ def test_define(self):
+ self.launch_common()
+
+ self.runCmd("expression int (^$add)(int, int) = ^int(int a, int b) { return a + b; };")
+
+ self.expect("expression $add(2,3)", VARIABLES_DISPLAYED_CORRECTLY, substrs = [" = 5"])
def wait_for_breakpoint(self):
if self.is_started == False:
diff --git a/packages/Python/lldbsuite/test/lang/c/const_variables/TestConstVariables.py b/packages/Python/lldbsuite/test/lang/c/const_variables/TestConstVariables.py
index a112b2a1777c..99544c7bd80e 100644
--- a/packages/Python/lldbsuite/test/lang/c/const_variables/TestConstVariables.py
+++ b/packages/Python/lldbsuite/test/lang/c/const_variables/TestConstVariables.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ConstVariableTestCase(TestBase):
@@ -24,8 +25,8 @@ class ConstVariableTestCase(TestBase):
compiler="clang", compiler_version=["=", "3.8"])
@expectedFailureAll(oslist=["freebsd", "linux"], compiler="icc")
@expectedFailureAll(archs=['mips', 'mipsel', 'mips64', 'mips64el'])
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
- @expectedFailureWindows("llvm.org/pr24490: We shouldn't be using platform-specific names like `getpid` in tests")
+ @expectedFailureAll(oslist=["linux"], archs=['arm', 'aarch64'], bugnumber="llvm.org/pr27883")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows")
def test_and_run_command(self):
"""Test interpreted and JITted expressions on constant values."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py b/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py
index b0c5c882f6a9..044accf14f65 100644
--- a/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py
+++ b/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py
@@ -8,6 +8,7 @@ import os, time
import lldb
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
class EnumTypesTestCase(TestBase):
@@ -19,6 +20,7 @@ class EnumTypesTestCase(TestBase):
# Find the line number to break inside main().
self.line = line_number('main.c', '// Set break point at this line.')
+ @expectedFailureAll(oslist=['windows']) # derefing the null pointer "works" on Windows
def test(self):
"""Test 'image lookup -t days' and check for correct display and enum value printing."""
self.build()
@@ -53,10 +55,10 @@ class EnumTypesTestCase(TestBase):
'kNumDays',
'}'])
- enum_values = [ '-4',
- 'Monday',
- 'Tuesday',
- 'Wednesday',
+ enum_values = [ '-4',
+ 'Monday',
+ 'Tuesday',
+ 'Wednesday',
'Thursday',
'Friday',
'Saturday',
@@ -64,6 +66,13 @@ class EnumTypesTestCase(TestBase):
'kNumDays',
'5'];
+ # Make sure a pointer to an anonymous enum type does crash LLDB and displays correctly using
+ # frame variable and expression commands
+ self.expect('frame variable f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['ops *', 'f.op'], patterns = ['0x0+$'])
+ self.expect('frame variable *f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['ops', '*f.op', '<parent is NULL>'])
+ self.expect('expr f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['ops *', '$'], patterns = ['0x0+$'])
+ self.expect('expr *f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['error:'], error = True)
+
bkpt = self.target().FindBreakpointByID(bkpt_id)
for enum_value in enum_values:
self.expect("frame variable day", 'check for valid enumeration value',
diff --git a/packages/Python/lldbsuite/test/lang/c/enum_types/main.c b/packages/Python/lldbsuite/test/lang/c/enum_types/main.c
index 3d59654eff69..59ea21300693 100644
--- a/packages/Python/lldbsuite/test/lang/c/enum_types/main.c
+++ b/packages/Python/lldbsuite/test/lang/c/enum_types/main.c
@@ -8,6 +8,15 @@
//===----------------------------------------------------------------------===//
#include <stdio.h>
+#include <stdio.h>
+
+// Forward declare an enumeration (only works in C, not C++)
+typedef enum ops ops;
+
+struct foo {
+ ops *op;
+};
+
int main (int argc, char const *argv[])
{
enum days {
@@ -21,6 +30,8 @@ int main (int argc, char const *argv[])
kNumDays
};
enum days day;
+ struct foo f;
+ f.op = NULL;
for (day = Monday - 1; day <= kNumDays + 1; day++)
{
printf("day as int is %i\n", (int)day); // Set break point at this line.
diff --git a/packages/Python/lldbsuite/test/lang/c/function_types/TestFunctionTypes.py b/packages/Python/lldbsuite/test/lang/c/function_types/TestFunctionTypes.py
index 2f9f1d10b58c..67ccb1aa3fa4 100644
--- a/packages/Python/lldbsuite/test/lang/c/function_types/TestFunctionTypes.py
+++ b/packages/Python/lldbsuite/test/lang/c/function_types/TestFunctionTypes.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class FunctionTypesTestCase(TestBase):
@@ -37,7 +38,7 @@ class FunctionTypesTestCase(TestBase):
substrs = ['a.out`string_not_empty',
'stop reason = breakpoint'])
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_pointers(self):
"""Test that a function pointer to 'printf' works and can be called."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py b/packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py
index 1f91cd1660c3..87160f5252be 100644
--- a/packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py
+++ b/packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py
@@ -3,8 +3,9 @@
from __future__ import print_function
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class GlobalVariablesTestCase(TestBase):
@@ -18,8 +19,8 @@ class GlobalVariablesTestCase(TestBase):
self.line = line_number(self.source, '// Set break point at this line.')
self.shlib_names = ["a"]
- @expectedFailureWindows("llvm.org/pr24764")
- @expectedFailureAll("llvm.org/pr25872", oslist=["macosx"], debug_info="dwarf")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")
+ @expectedFailureAll("llvm.org/pr25872", oslist=["macosx"], debug_info=["dwarf", "gmodules"])
def test_c_global_variables(self):
"""Test 'frame variable --scope --no-args' which omits args and shows scopes."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/c/inlines/TestRedefinitionsInInlines.py b/packages/Python/lldbsuite/test/lang/c/inlines/TestRedefinitionsInInlines.py
new file mode 100644
index 000000000000..d6fbf42b7570
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/inlines/TestRedefinitionsInInlines.py
@@ -0,0 +1,5 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr27845"),
+ decorators.expectedFailureAll(compiler="clang", compiler_version=["<", "3.5"], bugnumber="llvm.org/pr27845")])
diff --git a/packages/Python/lldbsuite/test/lang/c/inlines/main.c b/packages/Python/lldbsuite/test/lang/c/inlines/main.c
new file mode 100644
index 000000000000..e9bd894bf726
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/inlines/main.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+
+inline void test1(int) __attribute__ ((always_inline));
+inline void test2(int) __attribute__ ((always_inline));
+
+void test2(int b) {
+ printf("test2(%d)\n", b); //% self.expect("expression b", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["42"])
+}
+
+void test1(int a) {
+ printf("test1(%d)\n", a);
+ test2(a+1);//% self.dbg.HandleCommand("step")
+ //% self.expect("expression b", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["24"])
+}
+
+int main() {
+ test2(42);
+ test1(23);
+}
diff --git a/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py b/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py
index cd31f9dbacfe..5a940e2e5eff 100644
--- a/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py
+++ b/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py
@@ -4,23 +4,22 @@ from __future__ import print_function
+from distutils.version import StrictVersion
import os, time
-import lldb
import platform
-import lldbsuite.test.lldbutil as lldbutil
-
-from distutils.version import StrictVersion
+import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class CModulesTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfFreeBSD
- @expectedFailureDarwin('http://llvm.org/pr24302')
- @expectedFailureLinux('http://llvm.org/pr23456') # 'fopen' has unknown return type
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
+ @expectedFailureAll(oslist=["linux"], bugnumber="http://llvm.org/pr23456 'fopen' has unknown return type")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows")
def test_expr(self):
if platform.system() == "Darwin" and platform.release() < StrictVersion('12.0.0'):
self.skipTest()
@@ -43,11 +42,11 @@ class CModulesTestCase(TestBase):
self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
substrs = [' resolved, hit count = 1'])
- self.expect("expr @import Darwin; 3", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr -l objc++ -- @import Darwin; 3", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["int", "3"])
self.expect("expr *fopen(\"/dev/zero\", \"w\")", VARIABLES_DISPLAYED_CORRECTLY,
- substrs = ["FILE", "_close", "__sclose"])
+ substrs = ["FILE", "_close"])
self.expect("expr *myFile", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["a", "5", "b", "9"])
diff --git a/packages/Python/lldbsuite/test/lang/c/register_variables/Makefile b/packages/Python/lldbsuite/test/lang/c/register_variables/Makefile
index 12e55616b540..a09f73fb3fa7 100644
--- a/packages/Python/lldbsuite/test/lang/c/register_variables/Makefile
+++ b/packages/Python/lldbsuite/test/lang/c/register_variables/Makefile
@@ -2,6 +2,6 @@ LEVEL = ../../../make
C_SOURCES := test.c
-CFLAGS ?= -g -O1
+CFLAGS_EXTRAS += -O1
include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py b/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py
index 7ef1f246bfd3..6b2dc6a9b126 100644
--- a/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py
+++ b/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py
@@ -2,28 +2,113 @@
from __future__ import print_function
-
-
import os, time
+import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
+
+# This method attempts to figure out if a given variable
+# is in a register.
+#
+# Return:
+# True if the value has a readable value and is in a register
+# False otherwise
+def is_variable_in_register(frame, var_name):
+ # Ensure we can lookup the variable.
+ var = frame.FindVariable(var_name)
+ # print("\nchecking {}...".format(var_name))
+ if var is None or not var.IsValid():
+ # print("{} cannot be found".format(var_name))
+ return False
+
+ # Check that we can get its value. If not, this
+ # may be a variable that is just out of scope at this point.
+ value = var.GetValue()
+ # print("checking value...")
+ if value is None:
+ # print("value is invalid")
+ return False
+ # else:
+ # print("value is {}".format(value))
+
+ # We have a variable and we can get its value. The variable is in
+ # a register if we cannot get an address for it, assuming it is
+ # not a struct pointer. (This is an approximation - compilers can
+ # do other things with spitting up a value into multiple parts of
+ # multiple registers, but what we're verifying here is much more
+ # than it was doing before).
+ var_addr = var.GetAddress()
+ # print("checking address...")
+ if var_addr.IsValid():
+ # We have an address, it must not be in a register.
+ # print("var {} is not in a register: has a valid address {}".format(var_name, var_addr))
+ return False
+ else:
+ # We don't have an address but we can read the value.
+ # It is likely stored in a register.
+ # print("var {} is in a register (we don't have an address for it)".format(var_name))
+ return True
+
+
+def is_struct_pointer_in_register(frame, var_name):
+ # Ensure we can lookup the variable.
+ var = frame.FindVariable(var_name)
+ # print("\nchecking {}...".format(var_name))
+ if var is None or not var.IsValid():
+ # print("{} cannot be found".format(var_name))
+ return False
+
+ # Check that we can get its value. If not, this
+ # may be a variable that is just out of scope at this point.
+ value = var.GetValue()
+ # print("checking value...")
+ if value is None:
+ # print("value is invalid")
+ return False
+ # else:
+ # print("value is {}".format(value))
+
+ var_loc = var.GetLocation()
+ # print("checking location: {}".format(var_loc))
+ if var_loc is None or var_loc.startswith("0x"):
+ # The frame var is not in a register but rather a memory location.
+ # print("frame var {} is not in a register".format(var_name))
+ return False
+ else:
+ # print("frame var {} is in a register".format(var_name))
+ return True
+
+
+def re_expr_equals(val_type, val):
+ # Match ({val_type}) ${sum_digits} = {val}
+ return re.compile(r'\(' + val_type + '\) \$\d+ = ' + str(val))
+
class RegisterVariableTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureAll(oslist=['macosx'], compiler='clang', compiler_version=['<', '7.0.0'], debug_info="dsym")
- @expectedFailureClang(None, ['<', '3.5'])
- @expectedFailureGcc(None, ['is', '4.8.2'])
+
+ @expectedFailureAll(compiler="clang", compiler_version=['<', '3.5'])
+ @expectedFailureAll(compiler="gcc", compiler_version=['>=', '4.8.2'], archs=["i386", "x86_64"])
def test_and_run_command(self):
"""Test expressions on register values."""
+
+ # This test now ensures that each probable
+ # register variable location is actually a register, and
+ # if so, whether we can print out the variable there.
+ # It only requires one of them to be handled in a non-error
+ # way.
+ register_variables_count = 0
+
self.build()
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Break inside the main.
- lldbutil.run_break_set_by_source_regexp(self, "break", num_expected_locations=2)
+ lldbutil.run_break_set_by_source_regexp(self, "break", num_expected_locations=3)
####################
# First breakpoint
@@ -40,11 +125,16 @@ class RegisterVariableTestCase(TestBase):
substrs = [' resolved, hit count = 1'])
# Try some variables that should be visible
- self.expect("expr a", VARIABLES_DISPLAYED_CORRECTLY,
- substrs = ['(int) $0 = 2'])
+ frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
+ if is_variable_in_register(frame, 'a'):
+ register_variables_count += 1
+ self.expect("expr a", VARIABLES_DISPLAYED_CORRECTLY,
+ patterns = [re_expr_equals('int', 2)])
- self.expect("expr b->m1", VARIABLES_DISPLAYED_CORRECTLY,
- substrs = ['(int) $1 = 3'])
+ if is_struct_pointer_in_register(frame, 'b'):
+ register_variables_count += 1
+ self.expect("expr b->m1", VARIABLES_DISPLAYED_CORRECTLY,
+ patterns = [re_expr_equals('int', 3)])
#####################
# Second breakpoint
@@ -61,10 +151,40 @@ class RegisterVariableTestCase(TestBase):
substrs = [' resolved, hit count = 1'])
# Try some variables that should be visible
- self.expect("expr b->m2", VARIABLES_DISPLAYED_CORRECTLY,
- substrs = ['(int) $2 = 5'])
+ frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
+ if is_struct_pointer_in_register(frame, 'b'):
+ register_variables_count += 1
+ self.expect("expr b->m2", VARIABLES_DISPLAYED_CORRECTLY,
+ patterns = [re_expr_equals('int', 5)])
+
+ if is_variable_in_register(frame, 'c'):
+ register_variables_count += 1
+ self.expect("expr c", VARIABLES_DISPLAYED_CORRECTLY,
+ patterns = [re_expr_equals('int', 5)])
+
+ #####################
+ # Third breakpoint
+
+ self.runCmd("continue")
- self.expect("expr c", VARIABLES_DISPLAYED_CORRECTLY,
- substrs = ['(int) $3 = 5'])
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
+
+ # Try some variables that should be visible
+ frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
+ if is_variable_in_register(frame, 'f'):
+ register_variables_count += 1
+ self.expect("expr f", VARIABLES_DISPLAYED_CORRECTLY,
+ patterns = [re_expr_equals('float', '3.1')])
+
+ # Validate that we verified at least one register variable
+ self.assertTrue(register_variables_count > 0, "expected to verify at least one variable in a register")
+ # print("executed {} expressions with values in registers".format(register_variables_count))
self.runCmd("kill")
diff --git a/packages/Python/lldbsuite/test/lang/c/register_variables/test.c b/packages/Python/lldbsuite/test/lang/c/register_variables/test.c
index e467ac48f745..476c32899edc 100644
--- a/packages/Python/lldbsuite/test/lang/c/register_variables/test.c
+++ b/packages/Python/lldbsuite/test/lang/c/register_variables/test.c
@@ -5,23 +5,31 @@ struct bar {
int m2;
};
-void f1(int a, struct bar *b) __attribute__ ((noinline));
+void f1(int a, struct bar *b) __attribute__((noinline)) __attribute__((regparm(2)));
void f1(int a, struct bar *b)
{
b->m2 = b->m1 + a; // set breakpoint here
}
-void f2(struct bar *b) __attribute__ ((noinline));
+void f2(struct bar *b) __attribute__((noinline)) __attribute__((regparm(1)));
void f2(struct bar *b)
{
int c = b->m2;
printf("%d\n", c); // set breakpoint here
}
+float f3() __attribute__((noinline));
+float f3() {
+ return 3.14f;
+}
+
int main()
{
struct bar myBar = { 3, 4 };
f1(2, &myBar);
f2(&myBar);
+
+ float f = f3();
+ printf("%f\n", f); // set breakpoint here
return 0;
}
diff --git a/packages/Python/lldbsuite/test/lang/c/set_values/TestSetValues.py b/packages/Python/lldbsuite/test/lang/c/set_values/TestSetValues.py
index ab8102496091..12e20dd42d44 100644
--- a/packages/Python/lldbsuite/test/lang/c/set_values/TestSetValues.py
+++ b/packages/Python/lldbsuite/test/lang/c/set_values/TestSetValues.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SetValuesTestCase(TestBase):
@@ -23,7 +24,6 @@ class SetValuesTestCase(TestBase):
self.line4 = line_number('main.c', '// Set break point #4.')
self.line5 = line_number('main.c', '// Set break point #5.')
- @expectedFailureWindows("llvm.org/pr21765")
def test(self):
"""Test settings and readings of program variables."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py b/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py
index a9cb46ca137b..011e4d1f22a4 100644
--- a/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py
+++ b/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py
@@ -6,14 +6,15 @@ from __future__ import print_function
import unittest2
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SharedLibStrippedTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows # Test crashes
+ @expectedFailureAll(oslist=["windows"])
def test_expr(self):
"""Test that types work when defined in a shared library and forward-declared in the main executable"""
if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion():
@@ -26,7 +27,7 @@ class SharedLibStrippedTestCase(TestBase):
self.expect("expression --show-types -- *my_foo_ptr", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["(foo)", "(sub_foo)", "other_element = 3"])
- @expectedFailureWindows # Test crashes
+ @expectedFailureAll(oslist=["windows"])
@unittest2.expectedFailure("rdar://problem/10381325")
def test_frame_variable(self):
"""Test that types work when defined in a shared library and forward-declared in the main executable"""
diff --git a/packages/Python/lldbsuite/test/lang/c/step-target/Makefile b/packages/Python/lldbsuite/test/lang/c/step-target/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/step-target/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/c/step-target/TestStepTarget.py b/packages/Python/lldbsuite/test/lang/c/step-target/TestStepTarget.py
new file mode 100644
index 000000000000..2bd72434d390
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/step-target/TestStepTarget.py
@@ -0,0 +1,113 @@
+"""Test the 'step target' feature."""
+
+from __future__ import print_function
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestStepTarget(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def getCategories(self):
+ return ['basic_process']
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers that we will step to in main:
+ self.main_source = "main.c"
+ self.end_line = line_number(self.main_source, "All done")
+
+ @add_test_categories(['pyapi'])
+
+ def get_to_start (self):
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ self.main_source_spec = lldb.SBFileSpec (self.main_source)
+
+ break_in_main = target.BreakpointCreateBySourceRegex ('Break here to try targetted stepping', self.main_source_spec)
+ self.assertTrue(break_in_main, VALID_BREAKPOINT)
+ self.assertTrue(break_in_main.GetNumLocations() > 0,"Has locations.")
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # The stop reason of the thread should be breakpoint.
+ threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_main)
+
+ if len(threads) != 1:
+ self.fail ("Failed to stop at first breakpoint in main.")
+
+ thread = threads[0]
+ return thread
+
+ def test_with_end_line(self):
+ """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms."""
+
+ thread = self.get_to_start()
+
+ error = lldb.SBError()
+ thread.StepInto("lotsOfArgs", self.end_line, error)
+ frame = thread.frames[0]
+
+ self.assertTrue (frame.name == "lotsOfArgs", "Stepped to lotsOfArgs.")
+
+ def test_with_end_line_bad_name(self):
+ """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms."""
+
+ thread = self.get_to_start()
+
+ error = lldb.SBError()
+ thread.StepInto("lotsOfArgssss", self.end_line, error)
+ frame = thread.frames[0]
+ self.assertTrue (frame.line_entry.line == self.end_line, "Stepped to the block end.")
+
+ def test_with_end_line_deeper(self):
+ """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms."""
+
+ thread = self.get_to_start()
+
+ error = lldb.SBError()
+ thread.StepInto("modifyInt", self.end_line, error)
+ frame = thread.frames[0]
+ self.assertTrue (frame.name == "modifyInt", "Stepped to modifyInt.")
+
+ def test_with_command_and_block(self):
+ """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms."""
+
+ thread = self.get_to_start()
+
+ result = lldb.SBCommandReturnObject()
+ self.dbg.GetCommandInterpreter().HandleCommand('thread step-in -t "lotsOfArgs" -e block', result)
+ self.assertTrue(result.Succeeded(), "thread step-in command succeeded.")
+
+ frame = thread.frames[0]
+ self.assertTrue (frame.name == "lotsOfArgs", "Stepped to lotsOfArgs.")
+
+ def test_with_command_and_block_and_bad_name(self):
+ """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms."""
+
+ thread = self.get_to_start()
+
+ result = lldb.SBCommandReturnObject()
+ self.dbg.GetCommandInterpreter().HandleCommand('thread step-in -t "lotsOfArgsssss" -e block', result)
+ self.assertTrue(result.Succeeded(), "thread step-in command succeeded.")
+
+ frame = thread.frames[0]
+
+ self.assertTrue (frame.name == "main", "Stepped back out to main.")
+ # end_line is set to the line after the containing block. Check that we got there:
+ self.assertTrue(frame.line_entry.line == self.end_line, "Got out of the block")
+
+
+
diff --git a/packages/Python/lldbsuite/test/lang/c/step-target/main.c b/packages/Python/lldbsuite/test/lang/c/step-target/main.c
new file mode 100644
index 000000000000..86a26c4d47a4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/step-target/main.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+
+void
+lotsOfArgs
+(
+ int firstArg,
+ int secondArg,
+ int thirdArg,
+ int fourthArg
+)
+{
+ printf ("First: %d Second: %d Third: %d Fourth: %d.\n",
+ firstArg,
+ secondArg,
+ thirdArg,
+ fourthArg);
+}
+
+int
+modifyInt(int incoming)
+{
+ return incoming % 2;
+}
+
+int
+main (int argc, char **argv)
+{
+ if (argc > 0)
+ {
+ int var_makes_block = argc + 1;
+ printf ("Break here to try targetted stepping.\n");
+ lotsOfArgs(var_makes_block,
+ modifyInt(20),
+ 30,
+ modifyInt(40));
+ printf ("Done calling lotsOfArgs.");
+ }
+ printf ("All done.\n");
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py b/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py
index c7a3de4b6846..cfaff91daa45 100644
--- a/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py
+++ b/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestCStepping(TestBase):
@@ -22,10 +23,10 @@ class TestCStepping(TestBase):
# Find the line numbers that we will step to in main:
self.main_source = "main.c"
- @expectedFailureFreeBSD('llvm.org/pr17932')
- @expectedFailureLinux # llvm.org/pr14437
- @expectedFailureWindows("llvm.org/pr24777")
@add_test_categories(['pyapi'])
+ @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr17932')
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr14437")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24777")
def test_and_python_api(self):
"""Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms."""
self.build()
@@ -155,9 +156,14 @@ class TestCStepping(TestBase):
current_file = frame.GetLineEntry().GetFileSpec()
break_in_b.SetEnabled(True)
- frame.EvaluateExpression ("b (4)", lldb.eNoDynamicValues, False)
+ options = lldb.SBExpressionOptions()
+ options.SetIgnoreBreakpoints(False)
+ options.SetFetchDynamicValue(False)
+ options.SetUnwindOnError(False)
+ frame.EvaluateExpression ("b (4)", options)
threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_b)
+
if len(threads) != 1:
self.fail ("Failed to stop at breakpoint in b when calling b.")
thread = threads[0]
diff --git a/packages/Python/lldbsuite/test/lang/c/strings/TestCStrings.py b/packages/Python/lldbsuite/test/lang/c/strings/TestCStrings.py
index 6f2a9ff03be0..a9f49c30d101 100644
--- a/packages/Python/lldbsuite/test/lang/c/strings/TestCStrings.py
+++ b/packages/Python/lldbsuite/test/lang/c/strings/TestCStrings.py
@@ -2,14 +2,15 @@
Tests that C strings work as expected in expressions
"""
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CStringsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_with_run_command(self):
"""Tests that C strings work as expected in expressions"""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/c/struct_types/TestStructTypes.py b/packages/Python/lldbsuite/test/lang/c/struct_types/TestStructTypes.py
index 87ad326f3181..2249a8c9b16a 100644
--- a/packages/Python/lldbsuite/test/lang/c/struct_types/TestStructTypes.py
+++ b/packages/Python/lldbsuite/test/lang/c/struct_types/TestStructTypes.py
@@ -1,4 +1,4 @@
-import lldbsuite.test.lldbinline as lldbinline
-import lldbsuite.test.lldbtest as lldbtest
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
-lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.expectedFailureWindows("llvm.org/pr24764")] )
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")] )
diff --git a/packages/Python/lldbsuite/test/lang/c/tls_globals/TestTlsGlobals.py b/packages/Python/lldbsuite/test/lang/c/tls_globals/TestTlsGlobals.py
index 0d9e22ec3adf..0ca9923c89a6 100644
--- a/packages/Python/lldbsuite/test/lang/c/tls_globals/TestTlsGlobals.py
+++ b/packages/Python/lldbsuite/test/lang/c/tls_globals/TestTlsGlobals.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import unittest2
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TlsGlobalTestCase(TestBase):
@@ -25,8 +26,8 @@ class TlsGlobalTestCase(TestBase):
self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.getcwd())
self.addTearDownHook(lambda: self.runCmd("settings remove target.env-vars " + self.dylibPath))
- @unittest2.expectedFailure("rdar://7796742")
@skipIfWindows # TLS works differently on Windows, this would need to be implemented separately.
+ @expectedFailureAll(bugnumber="llvm.org/pr28392", oslist=no_match(lldbplatformutil.getDarwinOSTriples()))
def test(self):
"""Test thread-local storage."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/c/tls_globals/a.c b/packages/Python/lldbsuite/test/lang/c/tls_globals/a.c
index b9a85902d117..ab1022514d1e 100644
--- a/packages/Python/lldbsuite/test/lang/c/tls_globals/a.c
+++ b/packages/Python/lldbsuite/test/lang/c/tls_globals/a.c
@@ -11,6 +11,12 @@
__thread int var_shared = 33;
+int
+touch_shared()
+{
+ return var_shared;
+}
+
void shared_check()
{
var_shared *= 2;
diff --git a/packages/Python/lldbsuite/test/lang/c/tls_globals/main.c b/packages/Python/lldbsuite/test/lang/c/tls_globals/main.c
index cbe01b89b7ef..73e32ca39a58 100644
--- a/packages/Python/lldbsuite/test/lang/c/tls_globals/main.c
+++ b/packages/Python/lldbsuite/test/lang/c/tls_globals/main.c
@@ -11,6 +11,10 @@
#include <unistd.h>
void shared_check();
+// On some OS's (darwin) you must actually access a thread local variable
+// before you can read it
+int
+touch_shared();
// Create some TLS storage within the static executable.
__thread int var_static = 44;
@@ -28,9 +32,11 @@ int main (int argc, char const *argv[])
{
pthread_t handle;
pthread_create(&handle, NULL, &fn_static, NULL);
+ touch_shared();
+ for (; var_static;)
+ {
+ usleep(1); // main breakpoint
+ }
- for(;;)
- usleep(1); // main breakpoint
-
- return 0;
+ return 0;
}
diff --git a/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py b/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py
index a4870de1d177..232a86a2cde3 100644
--- a/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py
+++ b/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py
@@ -6,15 +6,16 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TypedefTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureAll(bugnumber="llvm.org/pr19238", compiler="clang")
- @expectedFailureAll(bugnumber="llvm.org/pr25626 expectedFailureClang fails on FreeBSD", oslist=["freebsd"])
+ @expectedFailureAll(compiler="clang", bugnumber="llvm.org/pr19238")
+ @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr25626 expectedFailureClang fails on FreeBSD")
def test_typedef(self):
"""Test 'image lookup -t a' and check for correct display at different scopes."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/c/unions/Makefile b/packages/Python/lldbsuite/test/lang/c/unions/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/unions/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/c/unions/TestUnionMembers.py b/packages/Python/lldbsuite/test/lang/c/unions/TestUnionMembers.py
new file mode 100644
index 000000000000..114be3ade01a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/unions/TestUnionMembers.py
@@ -0,0 +1,46 @@
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class TestUnionMembers(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_union_members(self):
+ self._load_exe()
+
+ # Set breakpoints
+ bp = self.target.BreakpointCreateBySourceRegex("Break here", self.src_file_spec)
+ self.assertTrue(bp.IsValid() and bp.GetNumLocations() >= 1, VALID_BREAKPOINT)
+
+ # Launch the process
+ self.process = self.target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID)
+ self.assertTrue(self.process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+
+ thread = lldbutil.get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid())
+ frame = thread.GetSelectedFrame()
+ self.assertTrue(frame.IsValid())
+
+ val = frame.EvaluateExpression("u");
+ self.assertTrue(val.IsValid())
+ val = frame.EvaluateExpression("u.s");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetNumChildren(), 2)
+
+ def _load_exe(self):
+ self.build()
+
+ cwd = os.getcwd()
+
+ src_file = os.path.join(cwd, "main.c")
+ self.src_file_spec = lldb.SBFileSpec(src_file)
+ self.assertTrue(self.src_file_spec.IsValid(), "breakpoint file")
+
+ # Get the path of the executable
+ exe_path = os.path.join(cwd, 'a.out')
+
+ # Load the executable
+ self.target = self.dbg.CreateTarget(exe_path)
+ self.assertTrue(self.target.IsValid(), VALID_TARGET)
diff --git a/packages/Python/lldbsuite/test/lang/c/unions/main.c b/packages/Python/lldbsuite/test/lang/c/unions/main.c
new file mode 100644
index 000000000000..2c6a7d1e7821
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/unions/main.c
@@ -0,0 +1,18 @@
+#include <stdint.h>
+
+union S
+{
+ int32_t n; // occupies 4 bytes
+ uint16_t s[2]; // occupies 4 bytes
+ uint8_t c; // occupies 1 byte
+}; // the whole union occupies 4 bytes
+
+int main()
+{
+ union S u;
+
+ u.s[0] = 1234;
+ u.s[1] = 4321;
+
+ return 0; // Break here
+}
diff --git a/packages/Python/lldbsuite/test/lang/cpp/auto/TestCPPAuto.py b/packages/Python/lldbsuite/test/lang/cpp/auto/TestCPPAuto.py
index 9746dec2fa3d..ea210a1e9ea2 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/auto/TestCPPAuto.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/auto/TestCPPAuto.py
@@ -2,14 +2,16 @@
Tests that auto types work
"""
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CPPAutoTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureGcc("GCC does not generate complete debug info")
+ @expectedFailureAll(compiler="gcc", bugnumber="GCC generates incomplete debug info")
+ @expectedFailureAll(oslist=['windows'], bugnumber="llvm.org/pr26339")
def test_with_run_command(self):
"""Test that auto types work in the expression parser"""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/TestCPPBreakpointCommands.py b/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/TestCPPBreakpointCommands.py
index 6c06f3750d13..0a1ac11adcea 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/TestCPPBreakpointCommands.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/TestCPPBreakpointCommands.py
@@ -8,13 +8,15 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class CPPBreakpointCommandsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows
+ @expectedFailureAll(oslist=["windows"])
def test(self):
"""Test a sequence of breakpoint command add, list, and delete."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/call-function/TestCallCPPFunction.py b/packages/Python/lldbsuite/test/lang/cpp/call-function/TestCallCPPFunction.py
index 3aa97af68819..260dd763c007 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/call-function/TestCallCPPFunction.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/call-function/TestCallCPPFunction.py
@@ -3,8 +3,9 @@ Tests calling a function by basename
"""
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CallCPPFunctionTestCase(TestBase):
@@ -14,7 +15,7 @@ class CallCPPFunctionTestCase(TestBase):
TestBase.setUp(self)
self.line = line_number('main.cpp', '// breakpoint')
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows")
def test_with_run_command(self):
"""Test calling a function by basename"""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/chained-calls/TestCppChainedCalls.py b/packages/Python/lldbsuite/test/lang/cpp/chained-calls/TestCppChainedCalls.py
index 272665a78577..140c4a832fd9 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/chained-calls/TestCppChainedCalls.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/chained-calls/TestCppChainedCalls.py
@@ -1,12 +1,13 @@
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestCppChainedCalls(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_with_run_command(self):
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/char1632_t/TestChar1632T.py b/packages/Python/lldbsuite/test/lang/cpp/char1632_t/TestChar1632T.py
index 9bb1faf4ba6d..d4400d3a488d 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/char1632_t/TestChar1632T.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/char1632_t/TestChar1632T.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class Char1632TestCase(TestBase):
@@ -24,8 +25,7 @@ class Char1632TestCase(TestBase):
self.lines = [ line_number(self.source, '// breakpoint1'),
line_number(self.source, '// breakpoint2') ]
- @expectedFailureIcc # ICC (13.1) does not emit the DW_TAG_base_type for char16_t and char32_t.
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
+ @expectedFailureAll(compiler="icc", bugnumber="ICC (13.1) does not emit the DW_TAG_base_type for char16_t and char32_t.")
def test(self):
"""Test that the C++11 support for char16_t and char32_t works correctly."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py b/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py
index d47d1b7dde41..acce769bf949 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class StaticVariableTestCase(TestBase):
@@ -21,7 +22,7 @@ class StaticVariableTestCase(TestBase):
# Find the line number to break at.
self.line = line_number('main.cpp', '// Set break point at this line.')
- @expectedFailureWindows("llvm.org/pr24764")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")
def test_with_run_command(self):
"""Test that file and class static variables display correctly."""
self.build()
@@ -49,9 +50,8 @@ class StaticVariableTestCase(TestBase):
startstr = "(int) A::g_points[1].x = 11")
@expectedFailureDarwin(9980907)
- @expectedFailureClang('Clang emits incomplete debug info.')
- @expectedFailureFreeBSD('llvm.org/pr20550 failing on FreeBSD-11')
- @expectedFailureGcc('GCC emits incomplete debug info.')
+ @expectedFailureAll(compiler=["clang", "gcc"], bugnumber="Compiler emits incomplete debug info")
+ @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr20550 failing on FreeBSD-11')
@add_test_categories(['pyapi'])
def test_with_python_api(self):
"""Test Python APIs on file and class static variables."""
@@ -69,11 +69,8 @@ class StaticVariableTestCase(TestBase):
self.assertTrue(process, PROCESS_IS_VALID)
# The stop reason of the thread should be breakpoint.
- thread = process.GetThreadAtIndex(0)
- if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
- from lldbsuite.test.lldbutil import stop_reason_to_str
- self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
- stop_reason_to_str(thread.GetStopReason()))
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
# Get the SBValue of 'A::g_points' and 'g_points'.
frame = thread.GetFrameAtIndex(0)
diff --git a/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypes.py b/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypes.py
index b67e53c30745..fe10120d497e 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypes.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypes.py
@@ -6,9 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ClassTypesTestCase(TestBase):
@@ -92,11 +92,8 @@ class ClassTypesTestCase(TestBase):
lldbutil.state_type_to_str(process.GetState()))
# The stop reason of the thread should be breakpoint.
- thread = process.GetThreadAtIndex(0)
- if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
- from lldbsuite.test.lldbutil import stop_reason_to_str
- self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
- stop_reason_to_str(thread.GetStopReason()))
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
# The filename of frame #0 should be 'main.cpp' and the line number
# should be 93.
@@ -203,11 +200,8 @@ class ClassTypesTestCase(TestBase):
lldbutil.state_type_to_str(process.GetState()))
# The stop reason of the thread should be breakpoint.
- thread = process.GetThreadAtIndex(0)
- if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
- from lldbsuite.test.lldbutil import stop_reason_to_str
- self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
- stop_reason_to_str(thread.GetStopReason()))
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
frame = thread.frames[0]
self.assertTrue (frame.IsValid(), "Got a valid frame.")
diff --git a/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypesDisassembly.py b/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypesDisassembly.py
index 595d075d5180..6413b3e056ff 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypesDisassembly.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypesDisassembly.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class IterateFrameAndDisassembleTestCase(TestBase):
@@ -46,7 +47,8 @@ class IterateFrameAndDisassembleTestCase(TestBase):
# disassemble it.
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
- thread = process.GetThreadAtIndex(0)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
depth = thread.GetNumFrames()
for i in range(depth - 1):
frame = thread.GetFrameAtIndex(i)
diff --git a/packages/Python/lldbsuite/test/lang/cpp/const_this/Makefile b/packages/Python/lldbsuite/test/lang/cpp/const_this/Makefile
new file mode 100644
index 000000000000..52a92c0b61ae
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/const_this/Makefile
@@ -0,0 +1,8 @@
+LEVEL = ../../../make
+CXX_SOURCES := main.cpp
+CXXFLAGS += -std=c++11
+include $(LEVEL)/Makefile.rules
+
+cleanup:
+ rm -f Makefile *.d
+
diff --git a/packages/Python/lldbsuite/test/lang/cpp/const_this/TestConstThis.py b/packages/Python/lldbsuite/test/lang/cpp/const_this/TestConstThis.py
new file mode 100644
index 000000000000..a08af5d091e1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/const_this/TestConstThis.py
@@ -0,0 +1,4 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals(), [] )
diff --git a/packages/Python/lldbsuite/test/lang/cpp/const_this/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/const_this/main.cpp
new file mode 100644
index 000000000000..7614977b245f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/const_this/main.cpp
@@ -0,0 +1,23 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+
+class foo {
+public:
+ template <class T> T func(T x) const {
+ return x+2; //% self.expect("expr 2+3", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["5"])
+ }
+};
+
+int i;
+
+int main() {
+ return foo().func(i);
+}
diff --git a/packages/Python/lldbsuite/test/lang/cpp/diamond/TestDiamond.py b/packages/Python/lldbsuite/test/lang/cpp/diamond/TestDiamond.py
index 67de03b54b20..d525e12b31ee 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/diamond/TestDiamond.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/diamond/TestDiamond.py
@@ -20,7 +20,8 @@ class CPPTestDiamondInheritance(TestBase):
self.set_breakpoint(line_number('main.cpp', '// breakpoint 2'))
process = target.LaunchSimple (None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
- thread = process.GetThreadAtIndex(0)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
frame = thread.GetFrameAtIndex(0)
j1 = frame.FindVariable("j1")
j1_Derived1 = j1.GetChildAtIndex(0)
diff --git a/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestCppValueCast.py b/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestCppValueCast.py
index 4e23cd899285..b456de450a82 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestCppValueCast.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestCppValueCast.py
@@ -10,8 +10,9 @@ import unittest2
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class CppValueCastTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestDynamicValue.py b/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestDynamicValue.py
index 56e81c56cfa6..98e6ef92665d 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestDynamicValue.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestDynamicValue.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class DynamicValueTestCase(TestBase):
@@ -28,9 +29,8 @@ class DynamicValueTestCase(TestBase):
self.main_second_call_line = line_number('pass-to-base.cpp',
'// Break here and get real address of reallyA.')
- @expectedFailureFreeBSD # FIXME: This needs to be root-caused.
- @expectedFailureWindows("llvm.org/pr24663")
@add_test_categories(['pyapi'])
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24663")
def test_get_dynamic_vals(self):
"""Test fetching C++ dynamic values from pointers & references."""
self.build(dictionary=self.getBuildFlags())
diff --git a/packages/Python/lldbsuite/test/lang/cpp/exceptions/TestCPPExceptionBreakpoints.py b/packages/Python/lldbsuite/test/lang/cpp/exceptions/TestCPPExceptionBreakpoints.py
index 65cf0b361d84..4ca4cb8b79ef 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/exceptions/TestCPPExceptionBreakpoints.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/exceptions/TestCPPExceptionBreakpoints.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class CPPBreakpointTestCase(TestBase):
@@ -21,7 +22,7 @@ class CPPBreakpointTestCase(TestBase):
self.source = 'exceptions.cpp'
self.catch_line = line_number(self.source, '// This is the line you should stop at for catch')
- @expectedFailureWindows("llvm.org/pr24538") # clang-cl does not support throw or catch
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24538, clang-cl does not support throw or catch")
def test(self):
"""Test lldb exception breakpoint command for CPP."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/extern_c/Makefile b/packages/Python/lldbsuite/test/lang/cpp/extern_c/Makefile
new file mode 100644
index 000000000000..99bfa7e03b47
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/extern_c/Makefile
@@ -0,0 +1,3 @@
+LEVEL = ../../../make
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/cpp/extern_c/TestExternCSymbols.py b/packages/Python/lldbsuite/test/lang/cpp/extern_c/TestExternCSymbols.py
new file mode 100644
index 000000000000..f08c0dcbda98
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/extern_c/TestExternCSymbols.py
@@ -0,0 +1,4 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals(), [])
diff --git a/packages/Python/lldbsuite/test/lang/cpp/extern_c/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/extern_c/main.cpp
new file mode 100644
index 000000000000..a4006c2f7ed1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/extern_c/main.cpp
@@ -0,0 +1,29 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdint.h>
+
+extern "C"
+{
+ int foo();
+};
+
+int foo()
+{
+ puts("foo");
+ return 2;
+}
+
+int main (int argc, char const *argv[], char const *envp[])
+{
+ foo();
+ return 0; //% self.expect("expression -- foo()", substrs = ['2'])
+}
+
diff --git a/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/TestFrameVariableAnonymousUnions.py b/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/TestFrameVariableAnonymousUnions.py
index 396a637041cb..d5d536388222 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/TestFrameVariableAnonymousUnions.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/TestFrameVariableAnonymousUnions.py
@@ -19,7 +19,13 @@ class FrameVariableAnonymousUnionsTestCase(TestBase):
self.runCmd("process launch", RUN_SUCCEEDED)
- self.expect('frame variable -f x i', substrs=['ffffff41'])
+ process = self.dbg.GetSelectedTarget().GetProcess()
+
+ if process.GetByteOrder() == lldb.eByteOrderLittle:
+ self.expect('frame variable -f x i', substrs=['ffffff41'])
+ else:
+ self.expect('frame variable -f x i', substrs=['41ffff00'])
+
self.expect('frame variable c', substrs=["'A"])
self.expect('frame variable x', matching=False, substrs=['3'])
diff --git a/packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py b/packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py
index de56cd6a6c49..eac78cd29951 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py
@@ -2,14 +2,15 @@
Test that global operators are found and evaluated.
"""
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestCppGlobalOperators(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_with_run_command(self):
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/gmodules/Makefile b/packages/Python/lldbsuite/test/lang/cpp/gmodules/Makefile
new file mode 100644
index 000000000000..da6f39a7488c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/gmodules/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+PCH_CXX_SOURCE = pch.h
+CXX_SOURCES = main.cpp
+CFLAGS_EXTRAS += $(MODULE_DEBUG_INFO_FLAGS)
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py b/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py
new file mode 100644
index 000000000000..942149f6173b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py
@@ -0,0 +1,50 @@
+import lldb, os
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestWithGmodulesDebugInfo(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @add_test_categories(["gmodules"])
+ @expectedFailureAll(oslist=["macosx"], bugnumber="llvm.org/pr28156")
+ def test_specialized_typedef_from_pch(self):
+ self.build()
+ cwd = os.getcwd()
+
+ src_file = os.path.join(cwd, "main.cpp")
+ src_file_spec = lldb.SBFileSpec(src_file)
+ self.assertTrue(src_file_spec.IsValid(), "breakpoint file")
+
+ # Get the path of the executable
+ exe_path = os.path.join(cwd, 'a.out')
+
+ # Load the executable
+ target = self.dbg.CreateTarget(exe_path)
+ self.assertTrue(target.IsValid(), VALID_TARGET)
+
+ # Break on interesting line
+ breakpoint = target.BreakpointCreateBySourceRegex("break here", src_file_spec)
+ self.assertTrue(breakpoint.IsValid() and breakpoint.GetNumLocations() >= 1, VALID_BREAKPOINT)
+
+ # Launch the process
+ process = target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertTrue(process.IsValid(), PROCESS_IS_VALID)
+
+ # Get the thread of the process
+ self.assertTrue(process.GetState() == lldb.eStateStopped)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
+
+ # Get frame for current thread
+ frame = thread.frames[0]
+
+ testValue = frame.EvaluateExpression("test")
+ self.assertTrue(testValue.GetError().Success(), "Test expression value invalid: %s" % (testValue.GetError().GetCString()))
+ self.assertTrue(testValue.GetTypeName() == "IntContainer", "Test expression type incorrect")
+
+ memberValue = testValue.GetChildMemberWithName("storage")
+ self.assertTrue(memberValue.GetError().Success(), "Member value missing or invalid: %s" % (testValue.GetError().GetCString()))
+ self.assertTrue(memberValue.GetTypeName() == "int", "Member type incorrect")
+ self.assertEqual(42, memberValue.GetValueAsSigned(), "Member value incorrect")
diff --git a/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp
new file mode 100644
index 000000000000..aa4013685171
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp
@@ -0,0 +1,5 @@
+int main(int argc, const char * argv[])
+{
+ IntContainer test(42);
+ return 0; // break here
+}
diff --git a/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h b/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h
new file mode 100644
index 000000000000..a6c59b94c896
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h
@@ -0,0 +1,12 @@
+template<typename T>
+class GenericContainer {
+ private:
+ T storage;
+
+ public:
+ GenericContainer(T value) {
+ storage = value;
+ };
+};
+
+typedef GenericContainer<int> IntContainer;
diff --git a/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py b/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py
index 324f476efb9b..1e3359ecde49 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py
@@ -1,13 +1,13 @@
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestCppIncompleteTypes(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureFreeBSD("llvm.org/pr25626 test executable not built correctly on FreeBSD")
- @skipIfGcc
+ @skipIf(compiler="gcc")
def test_limit_debug_info(self):
self.build()
frame = self.get_test_frame('limit')
@@ -20,7 +20,7 @@ class TestCppIncompleteTypes(TestBase):
self.assertTrue(value_a.IsValid(), "'expr a' results in a valid SBValue object")
self.assertTrue(value_a.GetError().Success(), "'expr a' is successful")
- @skipIfGcc
+ @skipIf(compiler="gcc")
@skipIfWindows # Clang on Windows asserts in external record layout in this case.
def test_partial_limit_debug_info(self):
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/inlines/Makefile b/packages/Python/lldbsuite/test/lang/cpp/inlines/Makefile
new file mode 100644
index 000000000000..8f67abdf2b34
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/inlines/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := inlines.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/cpp/inlines/TestInlines.py b/packages/Python/lldbsuite/test/lang/cpp/inlines/TestInlines.py
new file mode 100644
index 000000000000..284057de9dcd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/inlines/TestInlines.py
@@ -0,0 +1,52 @@
+"""Test variable lookup when stopped in inline functions."""
+
+from __future__ import print_function
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class InlinesTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('inlines.cpp', '// Set break point at this line.')
+
+ @expectedFailureAll("llvm.org/pr26710", oslist=["linux"], compiler="gcc")
+ def test(self):
+ """Test that local variables are visible in expressions."""
+ self.build()
+ self.runToBreakpoint()
+
+ # Check that 'frame variable' finds a variable
+ self.expect("frame variable inner_input", VARIABLES_DISPLAYED_CORRECTLY,
+ startstr = '(int) inner_input =')
+
+ # Check that 'expr' finds a variable
+ self.expect("expr inner_input", VARIABLES_DISPLAYED_CORRECTLY,
+ startstr = '(int) $0 =')
+
+ def runToBreakpoint(self):
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break inside the main.
+ lldbutil.run_break_set_by_file_and_line(self, "inlines.cpp", self.line, num_expected_locations=2,
+ loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
diff --git a/packages/Python/lldbsuite/test/lang/c/inlines/inlines.c b/packages/Python/lldbsuite/test/lang/cpp/inlines/inlines.cpp
index 1e920f1ef2f6..822d88e22f9b 100644
--- a/packages/Python/lldbsuite/test/lang/c/inlines/inlines.c
+++ b/packages/Python/lldbsuite/test/lang/cpp/inlines/inlines.cpp
@@ -23,7 +23,7 @@ inner_inline (int inner_input, int mod_value)
int inner_result;
inner_result = inner_input % mod_value;
printf ("Returning: %d.\n", inner_result);
- return not_inlined_1 (inner_result);
+ return not_inlined_1 (inner_result); // Set break point at this line.
}
INLINE_ME int
diff --git a/packages/Python/lldbsuite/test/lang/c/inlines/inlines.h b/packages/Python/lldbsuite/test/lang/cpp/inlines/inlines.h
index 265d7b4966ed..265d7b4966ed 100644
--- a/packages/Python/lldbsuite/test/lang/c/inlines/inlines.h
+++ b/packages/Python/lldbsuite/test/lang/cpp/inlines/inlines.h
diff --git a/packages/Python/lldbsuite/test/lang/cpp/lambdas/TestLambdas.py b/packages/Python/lldbsuite/test/lang/cpp/lambdas/TestLambdas.py
new file mode 100644
index 000000000000..97cc177aab70
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/lambdas/TestLambdas.py
@@ -0,0 +1,4 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals(), [lldbinline.expectedFailureAll(oslist=["windows"])])
diff --git a/packages/Python/lldbsuite/test/lang/cpp/lambdas/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/lambdas/main.cpp
new file mode 100644
index 000000000000..3cce3baf2924
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/lambdas/main.cpp
@@ -0,0 +1,17 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+
+int main (int argc, char const *argv[])
+{
+ printf("Stop here\n"); //% self.runCmd("expression auto $add = [](int a, int b) { return a + b; }")
+ //% self.expect("expression $add(2,3)", substrs = ['= 5'])
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py b/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py
index ec26f9efe907..9d4d1b54a9d3 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py
@@ -1,12 +1,13 @@
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestWithLimitDebugInfo(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipIf(debug_info=not_in(["dwarf"]))
+ @skipIf(debug_info=no_match(["dwarf"]))
def test_limit_debug_info(self):
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/Makefile b/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/Makefile
new file mode 100644
index 000000000000..35eb63f922f7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES = main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/TestMembersAndLocalsWithSameName.py b/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/TestMembersAndLocalsWithSameName.py
new file mode 100644
index 000000000000..12fc4c236376
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/TestMembersAndLocalsWithSameName.py
@@ -0,0 +1,197 @@
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class TestMembersAndLocalsWithSameName(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_when_stopped_in_method(self):
+ self._load_exe()
+
+ # Set breakpoints
+ bp1 = self.target.BreakpointCreateBySourceRegex("Break 1", self.src_file_spec)
+ self.assertTrue(bp1.IsValid() and bp1.GetNumLocations() >= 1, VALID_BREAKPOINT)
+ bp2 = self.target.BreakpointCreateBySourceRegex("Break 2", self.src_file_spec)
+ self.assertTrue(bp2.IsValid() and bp2.GetNumLocations() >= 1, VALID_BREAKPOINT)
+ bp3 = self.target.BreakpointCreateBySourceRegex("Break 3", self.src_file_spec)
+ self.assertTrue(bp3.IsValid() and bp3.GetNumLocations() >= 1, VALID_BREAKPOINT)
+ bp4 = self.target.BreakpointCreateBySourceRegex("Break 4", self.src_file_spec)
+ self.assertTrue(bp4.IsValid() and bp4.GetNumLocations() >= 1, VALID_BREAKPOINT)
+
+ # Launch the process
+ self.process = self.target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID)
+
+ self.assertTrue(self.process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+
+ self._test_globals()
+
+ self.process.Continue()
+ self.assertTrue(self.process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+ thread = lldbutil.get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid())
+ frame = thread.GetSelectedFrame()
+ self.assertTrue(frame.IsValid())
+
+ val = frame.EvaluateExpression("a");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 12345)
+
+ val = frame.EvaluateExpression("b");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 54321)
+
+ val = frame.EvaluateExpression("c");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 34567)
+
+ self.process.Continue()
+ self.assertTrue(self.process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+ thread = lldbutil.get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid())
+ frame = thread.GetSelectedFrame()
+ self.assertTrue(frame.IsValid())
+
+ val = frame.EvaluateExpression("a");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 10001)
+
+ val = frame.EvaluateExpression("b");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 10002)
+
+ val = frame.EvaluateExpression("c");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 10003)
+
+ self.process.Continue()
+ self.assertTrue(self.process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+ thread = lldbutil.get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid())
+ frame = thread.GetSelectedFrame()
+ self.assertTrue(frame.IsValid())
+
+ val = frame.EvaluateExpression("a");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 1)
+
+ val = frame.EvaluateExpression("b");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 2)
+
+ val = frame.EvaluateExpression("c");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 778899)
+
+ def test_when_stopped_in_function(self):
+ self._load_exe()
+
+ # Set breakpoints
+ bp1 = self.target.BreakpointCreateBySourceRegex("Break 1", self.src_file_spec)
+ self.assertTrue(bp1.IsValid() and bp1.GetNumLocations() >= 1, VALID_BREAKPOINT)
+ bp5 = self.target.BreakpointCreateBySourceRegex("Break 5", self.src_file_spec)
+ self.assertTrue(bp5.IsValid() and bp5.GetNumLocations() >= 1, VALID_BREAKPOINT)
+ bp6 = self.target.BreakpointCreateBySourceRegex("Break 6", self.src_file_spec)
+ self.assertTrue(bp6.IsValid() and bp6.GetNumLocations() >= 1, VALID_BREAKPOINT)
+ bp7 = self.target.BreakpointCreateBySourceRegex("Break 7", self.src_file_spec)
+ self.assertTrue(bp7.IsValid() and bp7.GetNumLocations() >= 1, VALID_BREAKPOINT)
+
+ # Launch the process
+ self.process = self.target.LaunchSimple(None, None, self.get_process_working_directory())
+ self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID)
+
+ self.assertTrue(self.process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+
+ self._test_globals()
+
+ self.process.Continue()
+ self.assertTrue(self.process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+ thread = lldbutil.get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid())
+ frame = thread.GetSelectedFrame()
+ self.assertTrue(frame.IsValid())
+
+ val = frame.EvaluateExpression("a");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 12345)
+
+ val = frame.EvaluateExpression("b");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 54321)
+
+ val = frame.EvaluateExpression("c");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 34567)
+
+ self.process.Continue()
+ self.assertTrue(self.process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+ thread = lldbutil.get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid())
+ frame = thread.GetSelectedFrame()
+ self.assertTrue(frame.IsValid())
+
+ val = frame.EvaluateExpression("a");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 10001)
+
+ val = frame.EvaluateExpression("b");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 10002)
+
+ val = frame.EvaluateExpression("c");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 10003)
+
+ self.process.Continue()
+ self.assertTrue(self.process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+ thread = lldbutil.get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid())
+ frame = thread.GetSelectedFrame()
+ self.assertTrue(frame.IsValid())
+
+ val = frame.EvaluateExpression("a");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 1)
+
+ val = frame.EvaluateExpression("b");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 2)
+
+ val = frame.EvaluateExpression("c");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 778899)
+
+ def _load_exe(self):
+ self.build()
+
+ cwd = os.getcwd()
+
+ src_file = os.path.join(cwd, "main.cpp")
+ self.src_file_spec = lldb.SBFileSpec(src_file)
+ self.assertTrue(self.src_file_spec.IsValid(), "breakpoint file")
+
+ # Get the path of the executable
+ exe_path = os.path.join(cwd, 'a.out')
+
+ # Load the executable
+ self.target = self.dbg.CreateTarget(exe_path)
+ self.assertTrue(self.target.IsValid(), VALID_TARGET)
+
+ def _test_globals(self):
+ thread = lldbutil.get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread.IsValid())
+ frame = thread.GetSelectedFrame()
+ self.assertTrue(frame.IsValid())
+
+ val = frame.EvaluateExpression("a");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 112233)
+
+ val = frame.EvaluateExpression("b");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 445566)
+
+ val = frame.EvaluateExpression("c");
+ self.assertTrue(val.IsValid())
+ self.assertEqual(val.GetValueAsUnsigned(), 778899)
diff --git a/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/main.cpp
new file mode 100644
index 000000000000..baf08f6a9832
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/main.cpp
@@ -0,0 +1,73 @@
+namespace NN
+{
+ int a = 778899;
+ int b = 665544;
+ int c = 445566;
+}
+
+class A
+{
+public:
+ A();
+ int Method(int a, int b);
+
+private:
+ int a, b;
+};
+
+A::A() : a(10), b(100) { }
+
+int a = 112233;
+int b = 445566;
+int c = 778899;
+
+int
+A::Method(int a, int b)
+{
+ {
+ int a = 12345;
+ int b = 54321;
+ int c = 34567;
+ this->a = a + b + this->b; // Break 2
+ }
+
+ {
+ using namespace NN;
+ int a = 10001;
+ int b = 10002;
+ int c = 10003;
+ this->a = a + b + this->b; // Break 3
+ }
+
+ return this->a + this->b + a + b; // Break 4
+}
+
+int
+Function(int a, int b)
+{
+ int A;
+
+ {
+ int a = 12345;
+ int b = 54321;
+ int c = 34567;
+ A = a + b + c; // Break 5
+ }
+
+ {
+ using namespace NN;
+ int a = 10001;
+ int b = 10002;
+ int c = 10003;
+ A = a + b + c; // Break 6
+ }
+
+ return A + a + b; // Break 7
+}
+
+int
+main()
+{
+ A obj;
+ return obj.Method(1, 2) + Function(1, 2); // Break 1
+}
diff --git a/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespace.py b/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespace.py
index a60d8252e9f0..93d53c7de712 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespace.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespace.py
@@ -8,8 +8,78 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
+
+class NamespaceBreakpointTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAll(bugnumber="llvm.org/pr28548", compiler="gcc")
+ def test_breakpoints_func_auto(self):
+ """Test that we can set breakpoints correctly by basename to find all functions whose basename is "func"."""
+ self.build()
+
+ names = [ "func()", "func(int)", "A::B::func()", "A::func()", "A::func(int)"]
+
+ # Create a target by the debugger.
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+ module_list = lldb.SBFileSpecList()
+ module_list.Append(lldb.SBFileSpec(exe, False))
+ cu_list = lldb.SBFileSpecList()
+ # Set a breakpoint by name "func" which should pick up all functions whose basename is "func"
+ bp = target.BreakpointCreateByName ("func", lldb.eFunctionNameTypeAuto, module_list, cu_list);
+ for bp_loc in bp:
+ name = bp_loc.GetAddress().GetFunction().GetName()
+ self.assertTrue(name in names, "make sure breakpoint locations are correct for 'func' with eFunctionNameTypeAuto")
+
+ @expectedFailureAll(bugnumber="llvm.org/pr28548", compiler="gcc")
+ def test_breakpoints_func_full(self):
+ """Test that we can set breakpoints correctly by fullname to find all functions whose fully qualified name is "func"
+ (no namespaces)."""
+ self.build()
+
+ names = [ "func()", "func(int)"]
+
+ # Create a target by the debugger.
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+ module_list = lldb.SBFileSpecList()
+ module_list.Append(lldb.SBFileSpec(exe, False))
+ cu_list = lldb.SBFileSpecList()
+
+ # Set a breakpoint by name "func" whose fullly qualified named matches "func" which
+ # should pick up only functions whose basename is "func" and has no containing context
+ bp = target.BreakpointCreateByName ("func", lldb.eFunctionNameTypeFull, module_list, cu_list);
+ for bp_loc in bp:
+ name = bp_loc.GetAddress().GetFunction().GetName()
+ self.assertTrue(name in names, "make sure breakpoint locations are correct for 'func' with eFunctionNameTypeFull")
+
+ def test_breakpoints_a_func_full(self):
+ """Test that we can set breakpoints correctly by fullname to find all functions whose fully qualified name is "A::func"."""
+ self.build()
+
+ names = [ "A::func()", "A::func(int)"]
+
+ # Create a target by the debugger.
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+ module_list = lldb.SBFileSpecList()
+ module_list.Append(lldb.SBFileSpec(exe, False))
+ cu_list = lldb.SBFileSpecList()
+
+ # Set a breakpoint by name "A::func" whose fullly qualified named matches "A::func" which
+ # should pick up only functions whose basename is "func" and is contained in the "A" namespace
+ bp = target.BreakpointCreateByName ("A::func", lldb.eFunctionNameTypeFull, module_list, cu_list);
+ for bp_loc in bp:
+ name = bp_loc.GetAddress().GetFunction().GetName()
+ self.assertTrue(name in names, "make sure breakpoint locations are correct for 'A::func' with eFunctionNameTypeFull")
+
class NamespaceTestCase(TestBase):
@@ -38,7 +108,7 @@ class NamespaceTestCase(TestBase):
'stop reason = breakpoint'])
# rdar://problem/8668674
- @expectedFailureWindows("llvm.org/pr24764")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")
def test_with_run_command(self):
"""Test that anonymous and named namespace variables display correctly."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespaceLookup.py b/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespaceLookup.py
index 4cad45564c87..12e8eef40cf3 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespaceLookup.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespaceLookup.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class NamespaceLookupTestCase(TestBase):
@@ -33,8 +34,7 @@ class NamespaceLookupTestCase(TestBase):
substrs = ['stopped',
'stop reason = breakpoint'])
- @expectedFailureFreeBSD("llvm.org/pr25819")
- @expectedFailureLinux("llvm.org/pr25819")
+ @expectedFailureAll(oslist=["windows", "linux", "freebsd"], bugnumber="llvm.org/pr25819")
def test_scope_lookup_with_run_command(self):
"""Test scope lookup of functions in lldb."""
self.build()
@@ -144,7 +144,7 @@ class NamespaceLookupTestCase(TestBase):
# finds the global ::func().
self.expect("expr -- func()", startstr = "(int) $0 = 2")
- @expectedFailureLinux("llvm.org/pr25819")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr25819")
def test_scope_lookup_before_using_with_run_command(self):
"""Test scope lookup before using in lldb."""
self.build()
@@ -158,9 +158,9 @@ class NamespaceLookupTestCase(TestBase):
self.expect("expr -- func()", startstr = "(int) $0 = 1")
# NOTE: this test may fail on older systems that don't emit import
- # emtries in DWARF - may need to add checks for compiler versions here.
- @expectedFailureFreeBSD("llvm.org/pr25819")
- @expectedFailureLinux("llvm.org/pr25819")
+ # entries in DWARF - may need to add checks for compiler versions here.
+ @skipIf(compiler="gcc", oslist=["linux"], debug_info=["dwo"]) # Skip to avoid crash
+ @expectedFailureAll(oslist=["windows", "linux", "freebsd"], bugnumber="llvm.org/pr25819")
def test_scope_after_using_directive_lookup_with_run_command(self):
"""Test scope lookup after using directive in lldb."""
self.build()
@@ -203,8 +203,7 @@ class NamespaceLookupTestCase(TestBase):
# the same type.
self.expect("expr -- func()", startstr = "error")
- @expectedFailureFreeBSD("llvm.org/pr25819")
- @expectedFailureLinux("llvm.org/pr25819")
+ @expectedFailureAll(oslist=["windows", "linux", "freebsd"], bugnumber="llvm.org/pr25819")
def test_scope_lookup_shadowed_by_using_with_run_command(self):
"""Test scope lookup shadowed by using in lldb."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/Makefile b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/Makefile
new file mode 100644
index 000000000000..0041add935a6
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/Makefile
@@ -0,0 +1,19 @@
+LEVEL := ../../../make
+
+LD_EXTRAS := -L. -l$(LIB_PREFIX)a -l$(LIB_PREFIX)b
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
+
+.PHONY:
+a.out: lib_a lib_b
+
+lib_%:
+ $(MAKE) -f $*.mk
+
+hidden_lib_d:
+ $(MAKE) -C hidden
+
+clean::
+ $(MAKE) -f a.mk clean
+ $(MAKE) -f b.mk clean
diff --git a/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/TestNamespaceDefinitions.py b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/TestNamespaceDefinitions.py
new file mode 100644
index 000000000000..f45969429004
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/TestNamespaceDefinitions.py
@@ -0,0 +1,57 @@
+"""Test that forward declarations don't cause bogus conflicts in namespaced types"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class NamespaceDefinitionsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_expr(self):
+ self.build()
+ self.common_setup()
+
+ self.expect("expression -- Foo::MyClass()", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['thing = '])
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.source = 'main.cpp'
+ self.line = line_number(self.source, '// Set breakpoint here')
+ self.shlib_names = ["a", "b"]
+
+ def common_setup(self):
+ # Run in synchronous mode
+ self.dbg.SetAsync(False)
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget("a.out")
+ self.assertTrue(target, VALID_TARGET)
+
+ # Break inside the foo function which takes a bar_ptr argument.
+ lldbutil.run_break_set_by_file_and_line (self, self.source, self.line, num_expected_locations=1, loc_exact=True)
+
+ # Register our shared libraries for remote targets so they get automatically uploaded
+ environment = self.registerSharedLibrariesWithTarget(target, self.shlib_names)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (None, environment, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
+
diff --git a/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/a.cpp b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/a.cpp
new file mode 100644
index 000000000000..2ea0d2df2eca
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/a.cpp
@@ -0,0 +1,16 @@
+//===-- a.cpp ---------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "foo.h"
+
+class ThingInside {
+ int a;
+};
+
+Foo::MyClass a_class;
diff --git a/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/a.mk b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/a.mk
new file mode 100644
index 000000000000..5943e5077c54
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/a.mk
@@ -0,0 +1,9 @@
+LEVEL := ../../../make
+
+DYLIB_NAME := a
+DYLIB_CXX_SOURCES := a.cpp
+DYLIB_ONLY := YES
+
+CXXFLAGS += -fPIC
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/b.cpp b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/b.cpp
new file mode 100644
index 000000000000..6e7b41e00164
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/b.cpp
@@ -0,0 +1,12 @@
+//===-- b.cpp ---------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "foo.h"
+
+Foo::MyClass b_class;
diff --git a/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/b.mk b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/b.mk
new file mode 100644
index 000000000000..8ee2a13b1291
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/b.mk
@@ -0,0 +1,9 @@
+LEVEL := ../../../make
+
+DYLIB_NAME := b
+DYLIB_CXX_SOURCES := b.cpp
+DYLIB_ONLY := YES
+
+CXXFLAGS += -fPIC
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/foo.h b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/foo.h
new file mode 100644
index 000000000000..76b8e70880ec
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/foo.h
@@ -0,0 +1,18 @@
+//===-- foo.h ---------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+class ThingInside;
+
+namespace Foo {
+ class MyClass {
+ ThingInside *thing;
+ public:
+ MyClass() { }
+ };
+}
diff --git a/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/main.cpp
new file mode 100644
index 000000000000..076814eae1de
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/main.cpp
@@ -0,0 +1,16 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+
+int
+main (int argc, char const *argv[])
+{
+ return 0; // Set breakpoint here
+}
diff --git a/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py b/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py
index 97e9e27a6e98..d66d2ac530e5 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py
@@ -2,15 +2,15 @@
Tests imported namespaces in C++.
"""
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestCppNsImport(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureFreeBSD("llvm.org/pr25925")
- @expectedFailureGcc(None, ['>=', '4.9'])
+ @expectedFailureAll(oslist=['freebsd'], bugnumber="llvm.org/pr25925")
def test_with_run_command(self):
"""Tests imported namespaces in C++."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/TestOverloadedFunctions.py b/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/TestOverloadedFunctions.py
index d485dcd0f652..ff00d99d7763 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/TestOverloadedFunctions.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/TestOverloadedFunctions.py
@@ -3,8 +3,9 @@ Tests that functions with the same name are resolved correctly.
"""
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CPPStaticMethodsTestCase(TestBase):
@@ -14,7 +15,7 @@ class CPPStaticMethodsTestCase(TestBase):
TestBase.setUp(self)
self.line = line_number('main.cpp', '// breakpoint')
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows")
def test_with_run_command(self):
"""Test that functions with the same name are resolved correctly"""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/printf/TestPrintf.py b/packages/Python/lldbsuite/test/lang/cpp/printf/TestPrintf.py
new file mode 100644
index 000000000000..2a2c673f8675
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/printf/TestPrintf.py
@@ -0,0 +1,4 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.expectedFailureAll(bugnumber="rdar://problem/24599697")] )
diff --git a/packages/Python/lldbsuite/test/lang/cpp/printf/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/printf/main.cpp
new file mode 100644
index 000000000000..badf1be0b41f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/printf/main.cpp
@@ -0,0 +1,21 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+class PrintfContainer {
+public:
+ int printf() {
+ return 0;
+ }
+};
+
+int main() {
+ PrintfContainer().printf(); //% self.expect("expression -- printf(\"Hello\\n\")", substrs = ['6'])
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/TestRvalueReferences.py b/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/TestRvalueReferences.py
index d02c34ecb0fe..78a2727094a7 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/TestRvalueReferences.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/TestRvalueReferences.py
@@ -3,16 +3,17 @@ Tests that rvalue references are supported in C++
"""
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class RvalueReferencesTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
#rdar://problem/11479676
- @expectedFailureIcc("ICC (13.1, 14-beta) do not emit DW_TAG_rvalue_reference_type.")
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
+ @expectedFailureAll(compiler="icc", bugnumber="ICC (13.1, 14-beta) do not emit DW_TAG_rvalue_reference_type.")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows")
def test_with_run_command(self):
"""Test that rvalues are supported in the C++ expression parser"""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/scope/TestCppScope.py b/packages/Python/lldbsuite/test/lang/cpp/scope/TestCppScope.py
index 66d4a1591575..d075eb65b848 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/scope/TestCppScope.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/scope/TestCppScope.py
@@ -2,15 +2,16 @@
Test scopes in C++.
"""
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestCppScopes(TestBase):
mydir = TestBase.compute_mydir(__file__)
@expectedFailureDarwin
- @expectedFailureWindows("llvm.org/pr24764")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")
def test_with_run_command(self):
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/signed_types/TestSignedTypes.py b/packages/Python/lldbsuite/test/lang/cpp/signed_types/TestSignedTypes.py
index 51e6d4579e28..3158c4c5bcf0 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/signed_types/TestSignedTypes.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/signed_types/TestSignedTypes.py
@@ -12,7 +12,7 @@ import lldb
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
-class UnsignedTypesTestCase(TestBase):
+class SignedTypesTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@@ -48,7 +48,7 @@ class UnsignedTypesTestCase(TestBase):
self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
substrs = [' resolved, hit count = 1'])
- # Execute the assignment statement.
+ # Execute the puts().
self.runCmd("thread step-over")
# Test that signed types display correctly.
diff --git a/packages/Python/lldbsuite/test/lang/cpp/static_members/TestCPPStaticMembers.py b/packages/Python/lldbsuite/test/lang/cpp/static_members/TestCPPStaticMembers.py
index 1c41b1b6f571..dd220d905278 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/static_members/TestCPPStaticMembers.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/static_members/TestCPPStaticMembers.py
@@ -8,15 +8,16 @@ from __future__ import print_function
import unittest2
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CPPStaticMembersTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@unittest2.expectedFailure # llvm.org/pr15401
- @expectedFailureWindows("llvm.org/pr21765")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test_with_run_command(self):
"""Test that member variables have the correct layout, scope and qualifiers when stopped inside and outside C++ methods"""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/static_methods/TestCPPStaticMethods.py b/packages/Python/lldbsuite/test/lang/cpp/static_methods/TestCPPStaticMethods.py
index dba556431e39..9784be189cb4 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/static_methods/TestCPPStaticMethods.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/static_methods/TestCPPStaticMethods.py
@@ -3,8 +3,9 @@ Tests expressions that distinguish between static and non-static methods.
"""
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CPPStaticMethodsTestCase(TestBase):
@@ -14,7 +15,7 @@ class CPPStaticMethodsTestCase(TestBase):
TestBase.setUp(self)
self.line = line_number('main.cpp', '// Break at this line')
- @expectedFailureWindows
+ @expectedFailureAll(oslist=["windows"])
def test_with_run_command(self):
"""Test that static methods are properly distinguished from regular methods"""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/stl/TestSTL.py b/packages/Python/lldbsuite/test/lang/cpp/stl/TestSTL.py
index 6dba1398947e..e25820857025 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/stl/TestSTL.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/stl/TestSTL.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import unittest2
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class STLTestCase(TestBase):
@@ -23,8 +24,7 @@ class STLTestCase(TestBase):
self.source = 'main.cpp'
self.line = line_number(self.source, '// Set break point at this line.')
- # rdar://problem/10400981
- @unittest2.expectedFailure
+ @expectedFailureAll(bugnumber="rdar://problem/10400981")
def test(self):
"""Test some expressions involving STL data types."""
self.build()
@@ -67,7 +67,7 @@ class STLTestCase(TestBase):
self.expect('expr associative_array["hello"]',
substrs = [' = 2'])
- @expectedFailureIcc # icc 13.1 and 14-beta do not emit DW_TAG_template_type_parameter
+ @expectedFailureAll(compiler="icc", bugnumber="ICC (13.1, 14-beta) do not emit DW_TAG_template_type_parameter.")
@add_test_categories(['pyapi'])
def test_SBType_template_aspects(self):
"""Test APIs for getting template arguments from an SBType."""
diff --git a/packages/Python/lldbsuite/test/lang/cpp/stl/TestStdCXXDisassembly.py b/packages/Python/lldbsuite/test/lang/cpp/stl/TestStdCXXDisassembly.py
index d7435c467274..865516de4edc 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/stl/TestStdCXXDisassembly.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/stl/TestStdCXXDisassembly.py
@@ -51,7 +51,8 @@ class StdCXXDisassembleTestCase(TestBase):
# Disassemble the functions on the call stack.
self.runCmd("thread backtrace")
- thread = process.GetThreadAtIndex(0)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
depth = thread.GetNumFrames()
for i in range(depth - 1):
frame = thread.GetFrameAtIndex(i)
diff --git a/packages/Python/lldbsuite/test/lang/cpp/template/Makefile b/packages/Python/lldbsuite/test/lang/cpp/template/Makefile
new file mode 100644
index 000000000000..194af7b32398
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/template/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+CFLAGS_EXTRAS += $(NO_LIMIT_DEBUG_INFO_FLAGS)
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py b/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py
new file mode 100644
index 000000000000..e08d3a10786c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py
@@ -0,0 +1,87 @@
+"""
+Test that C++ template classes that have integer parameters work correctly.
+
+We must reconstruct the types correctly so the template types are correct
+and display correctly, and also make sure the expression parser works and
+is able the find all needed functions when evaluating expressions
+"""
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TemplateArgsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def prepareProcess(self):
+ self.build()
+
+ # Create a target by the debugger.
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Set breakpoints inside and outside methods that take pointers to the containing struct.
+ line = line_number('main.cpp', '// Breakpoint 1')
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", line, num_expected_locations=1, loc_exact=True)
+
+ arguments = None
+ environment = None
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (arguments, environment, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Get the thread of the process
+ self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+
+ # Get frame for current thread
+ return thread.GetSelectedFrame()
+
+ def test_integer_args(self):
+ frame = self.prepareProcess()
+
+ testpos = frame.FindVariable('testpos')
+ self.assertTrue(testpos.IsValid(), 'make sure we find a local variabble named "testpos"')
+ self.assertTrue(testpos.GetType().GetName() == 'TestObj<1>')
+
+ expr_result = frame.EvaluateExpression("testpos.getArg()")
+ self.assertTrue(expr_result.IsValid(), 'got a valid expression result from expression "testpos.getArg()"');
+ self.assertTrue(expr_result.GetValue() == "1", "testpos.getArg() == 1")
+ self.assertTrue(expr_result.GetType().GetName() == "int", 'expr_result.GetType().GetName() == "int"')
+
+ testneg = frame.FindVariable('testneg')
+ self.assertTrue(testneg.IsValid(), 'make sure we find a local variabble named "testneg"')
+ self.assertTrue(testneg.GetType().GetName() == 'TestObj<-1>')
+
+ expr_result = frame.EvaluateExpression("testneg.getArg()")
+ self.assertTrue(expr_result.IsValid(), 'got a valid expression result from expression "testneg.getArg()"');
+ self.assertTrue(expr_result.GetValue() == "-1", "testneg.getArg() == -1")
+ self.assertTrue(expr_result.GetType().GetName() == "int", 'expr_result.GetType().GetName() == "int"')
+
+ # Gcc does not generate the necessary DWARF attribute for enum template parameters.
+ @expectedFailureAll(bugnumber="llvm.org/pr28354", compiler="gcc")
+ def test_enum_args(self):
+ frame = self.prepareProcess()
+
+ # Make sure "member" can be displayed and also used in an expression correctly
+ member = frame.FindVariable('member')
+ self.assertTrue(member.IsValid(), 'make sure we find a local variabble named "member"')
+ self.assertTrue(member.GetType().GetName() == 'EnumTemplate<EnumType::Member>')
+
+ expr_result = frame.EvaluateExpression("member.getMember()")
+ self.assertTrue(expr_result.IsValid(), 'got a valid expression result from expression "member.getMember()"');
+ self.assertTrue(expr_result.GetValue() == "123", "member.getMember() == 123")
+ self.assertTrue(expr_result.GetType().GetName() == "int", 'expr_result.GetType().GetName() == "int"')
+
+ # Make sure "subclass" can be displayed and also used in an expression correctly
+ subclass = frame.FindVariable('subclass')
+ self.assertTrue(subclass.IsValid(), 'make sure we find a local variabble named "subclass"')
+ self.assertTrue(subclass.GetType().GetName() == 'EnumTemplate<EnumType::Subclass>')
+
+ expr_result = frame.EvaluateExpression("subclass.getMember()")
+ self.assertTrue(expr_result.IsValid(), 'got a valid expression result from expression "subclass.getMember()"');
+ self.assertTrue(expr_result.GetValue() == "246", "subclass.getMember() == 246")
+ self.assertTrue(expr_result.GetType().GetName() == "int", 'expr_result.GetType().GetName() == "int"')
diff --git a/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp
new file mode 100644
index 000000000000..9c33a6420912
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp
@@ -0,0 +1,72 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+template <int Arg>
+class TestObj
+{
+public:
+ int getArg()
+ {
+ return Arg;
+ }
+};
+
+//----------------------------------------------------------------------
+// Define a template class that we can specialize with an enumeration
+//----------------------------------------------------------------------
+enum class EnumType
+{
+ Member,
+ Subclass
+};
+
+template <EnumType Arg> class EnumTemplate;
+
+//----------------------------------------------------------------------
+// Specialization for use when "Arg" is "EnumType::Member"
+//----------------------------------------------------------------------
+template <>
+class EnumTemplate<EnumType::Member>
+{
+public:
+ EnumTemplate(int m) :
+ m_member(m)
+ {
+ }
+
+ int getMember() const
+ {
+ return m_member;
+ }
+
+protected:
+ int m_member;
+};
+
+//----------------------------------------------------------------------
+// Specialization for use when "Arg" is "EnumType::Subclass"
+//----------------------------------------------------------------------
+template <>
+class EnumTemplate<EnumType::Subclass> :
+ public EnumTemplate<EnumType::Member>
+{
+public:
+ EnumTemplate(int m) : EnumTemplate<EnumType::Member>(m)
+ {
+ }
+};
+
+int main(int argc, char **argv)
+{
+ TestObj<1> testpos;
+ TestObj<-1> testneg;
+ EnumTemplate<EnumType::Member> member(123);
+ EnumTemplate<EnumType::Subclass> subclass(123*2);
+ return testpos.getArg() - testneg.getArg() + member.getMember()*2 - subclass.getMember(); // Breakpoint 1
+}
diff --git a/packages/Python/lldbsuite/test/lang/cpp/this/TestCPPThis.py b/packages/Python/lldbsuite/test/lang/cpp/this/TestCPPThis.py
index 07cc2e8e9788..5f89371aa85b 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/this/TestCPPThis.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/this/TestCPPThis.py
@@ -2,19 +2,18 @@
Tests that C++ member and static variables are available where they should be.
"""
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CPPThisTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
#rdar://problem/9962849
- @expectedFailureGcc # llvm.org/pr15439 The 'this' pointer isn't available during expression evaluation when stopped in an inlined member function.
- @expectedFailureIcc # ICC doesn't emit correct DWARF inline debug info for inlined member functions
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
- @expectedFailureWindows("llvm.org/pr24490: We shouldn't be using platform-specific names like `getpid` in tests")
- @expectedFlakeyClang(bugnumber='llvm.org/pr23012', compiler_version=['>=','3.6']) # failed with totclang - clang3.7
+ @expectedFailureAll(compiler="gcc", bugnumber="llvm.org/pr15439 The 'this' pointer isn't available during expression evaluation when stopped in an inlined member function")
+ @expectedFailureAll(compiler="icc", bugnumber="ICC doesn't emit correct DWARF inline debug info for inlined member functions.")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows")
def test_with_run_command(self):
"""Test that the appropriate member variables are available when stopped in C++ static, inline, and const methods"""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/rdar12991846/Makefile b/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/Makefile
index 1476447db355..1476447db355 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/rdar12991846/Makefile
+++ b/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/Makefile
diff --git a/packages/Python/lldbsuite/test/lang/cpp/rdar12991846/TestRdar12991846.py b/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/TestUnicodeLiterals.py
index 636a82b425da..1ae133f0b078 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/rdar12991846/TestRdar12991846.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/TestUnicodeLiterals.py
@@ -7,11 +7,11 @@ from __future__ import print_function
-import unittest2
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
# this test case fails because of rdar://12991846
# the expression parser does not deal correctly with Unicode expressions
@@ -26,26 +26,23 @@ import lldbsuite.test.lldbutil as lldbutil
# [5] = e\0\0\0
#}
-class Rdar12991846TestCase(TestBase):
+class UnicodeLiteralsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @unittest2.expectedFailure("rdar://18684408")
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows")
def test_expr1(self):
"""Test that the expression parser returns proper Unicode strings."""
self.build()
self.rdar12991846(expr=1)
- @unittest2.expectedFailure("rdar://18684408")
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows")
def test_expr2(self):
"""Test that the expression parser returns proper Unicode strings."""
self.build()
self.rdar12991846(expr=2)
- @unittest2.expectedFailure("rdar://18684408")
- @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows")
def test_expr3(self):
"""Test that the expression parser returns proper Unicode strings."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/rdar12991846/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/main.cpp
index fda951a78991..fda951a78991 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/rdar12991846/main.cpp
+++ b/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/main.cpp
diff --git a/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/TestUnsignedTypes.py b/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/TestUnsignedTypes.py
index c137592558ed..30aadb389680 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/TestUnsignedTypes.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/TestUnsignedTypes.py
@@ -9,6 +9,7 @@ from __future__ import print_function
import os, time
import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
@@ -22,6 +23,7 @@ class UnsignedTypesTestCase(TestBase):
# Find the line number to break inside main().
self.line = line_number('main.cpp', '// Set break point at this line.')
+ @expectedFailureAll(oslist=["windows"])
def test(self):
"""Test that variables with unsigned types display correctly."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/cpp/virtual/TestVirtual.py b/packages/Python/lldbsuite/test/lang/cpp/virtual/TestVirtual.py
index 1553a43e1a73..bee148773f03 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/virtual/TestVirtual.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/virtual/TestVirtual.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import os, time
import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
def Msg(expr, val):
return "'expression %s' matches the output (from compiled code): %s" % (expr, val)
@@ -21,9 +22,6 @@ class CppVirtualMadness(TestBase):
# printf() stmts (see main.cpp).
pattern = re.compile("^([^=]*) = '([^=]*)'$")
- # Assert message.
- PRINTF_OUTPUT_GROKKED = "The printf output from compiled code is parsed correctly"
-
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@@ -31,7 +29,7 @@ class CppVirtualMadness(TestBase):
self.source = 'main.cpp'
self.line = line_number(self.source, '// Set first breakpoint here.')
- @expectedFailureIcc('llvm.org/pr16808') # lldb does not call the correct virtual function with icc
+ @expectedFailureAll(compiler="icc", bugnumber="llvm.org/pr16808 lldb does not call the correct virtual function with icc.")
@expectedFailureAll(oslist=['windows'])
def test_virtual_madness(self):
"""Test that expression works correctly with virtual inheritance as well as virtual function."""
@@ -57,11 +55,13 @@ class CppVirtualMadness(TestBase):
thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
- # First, capture the golden output from the program itself from the
- # series of printf statements.
- stdout = process.GetSTDOUT(1024)
-
- self.assertIsNotNone(stdout, "Encountered an error reading the process's output")
+ # First, capture the golden output from the program itself.
+ golden = thread.GetFrameAtIndex(0).FindVariable("golden")
+ self.assertTrue(golden.IsValid(), "Encountered an error reading the process's golden variable")
+ error = lldb.SBError()
+ golden_str = process.ReadCStringFromMemory(golden.AddressOf().GetValueAsUnsigned(), 4096, error);
+ self.assertTrue(error.Success())
+ self.assertTrue("c_as_C" in golden_str)
# This golden list contains a list of "my_expr = 'value' pairs extracted
# from the golden output.
@@ -71,7 +71,7 @@ class CppVirtualMadness(TestBase):
#
# my_expr = 'value'
#
- for line in stdout.split(os.linesep):
+ for line in golden_str.split(os.linesep):
match = self.pattern.search(line)
if match:
my_expr, val = match.group(1), match.group(2)
diff --git a/packages/Python/lldbsuite/test/lang/cpp/virtual/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/virtual/main.cpp
index bed1422dcbdd..0adf41577314 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/virtual/main.cpp
+++ b/packages/Python/lldbsuite/test/lang/cpp/virtual/main.cpp
@@ -84,17 +84,20 @@ int main (int argc, char const *argv[], char const *envp[])
C *c_as_C = new C();
A *c_as_A = c_as_C;
- printf ("a_as_A->a() = '%s'\n", a_as_A->a());
- printf ("a_as_A->b() = '%s'\n", a_as_A->b());
- printf ("a_as_A->c() = '%s'\n", a_as_A->c());
- printf ("b_as_A->a() = '%s'\n", b_as_A->a());
- printf ("b_as_A->b() = '%s'\n", b_as_A->b());
- printf ("b_as_A->c() = '%s'\n", b_as_A->c());
- printf ("b_as_B->aa() = '%s'\n", b_as_B->aa());
- printf ("c_as_A->a() = '%s'\n", c_as_A->a());
- printf ("c_as_A->b() = '%s'\n", c_as_A->b());
- printf ("c_as_A->c() = '%s'\n", c_as_A->c());
- printf ("c_as_C->aa() = '%s'\n", c_as_C->aa());
+ char golden[4096];
+ char *p = golden;
+ char *end = p + sizeof golden;
+ p += snprintf(p, end-p, "a_as_A->a() = '%s'\n", a_as_A->a());
+ p += snprintf(p, end-p, "a_as_A->b() = '%s'\n", a_as_A->b());
+ p += snprintf(p, end-p, "a_as_A->c() = '%s'\n", a_as_A->c());
+ p += snprintf(p, end-p, "b_as_A->a() = '%s'\n", b_as_A->a());
+ p += snprintf(p, end-p, "b_as_A->b() = '%s'\n", b_as_A->b());
+ p += snprintf(p, end-p, "b_as_A->c() = '%s'\n", b_as_A->c());
+ p += snprintf(p, end-p, "b_as_B->aa() = '%s'\n", b_as_B->aa());
+ p += snprintf(p, end-p, "c_as_A->a() = '%s'\n", c_as_A->a());
+ p += snprintf(p, end-p, "c_as_A->b() = '%s'\n", c_as_A->b());
+ p += snprintf(p, end-p, "c_as_A->c() = '%s'\n", c_as_A->c());
+ p += snprintf(p, end-p, "c_as_C->aa() = '%s'\n", c_as_C->aa());
puts("");// Set first breakpoint here.
// then evaluate:
// expression a_as_A->a()
diff --git a/packages/Python/lldbsuite/test/lang/go/expressions/TestExpressions.py b/packages/Python/lldbsuite/test/lang/go/expressions/TestExpressions.py
index cbd244a7e056..f2e5613ffd61 100644
--- a/packages/Python/lldbsuite/test/lang/go/expressions/TestExpressions.py
+++ b/packages/Python/lldbsuite/test/lang/go/expressions/TestExpressions.py
@@ -3,8 +3,9 @@
import os, time
import unittest2
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGoUserExpression(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/go/formatters/TestGoFormatters.py b/packages/Python/lldbsuite/test/lang/go/formatters/TestGoFormatters.py
index 8b869df4ef8f..2578742467d9 100644
--- a/packages/Python/lldbsuite/test/lang/go/formatters/TestGoFormatters.py
+++ b/packages/Python/lldbsuite/test/lang/go/formatters/TestGoFormatters.py
@@ -3,8 +3,9 @@
import os, time
import unittest2
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGoLanguage(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/go/goroutines/TestGoroutines.py b/packages/Python/lldbsuite/test/lang/go/goroutines/TestGoroutines.py
index 35961ebd1d92..8aff2e514bb9 100644
--- a/packages/Python/lldbsuite/test/lang/go/goroutines/TestGoroutines.py
+++ b/packages/Python/lldbsuite/test/lang/go/goroutines/TestGoroutines.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGoASTContext(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/go/runtime/TestGoLanguageRuntime b/packages/Python/lldbsuite/test/lang/go/runtime/TestGoLanguageRuntime
index 44797077a641..30381ccd24c0 100644
--- a/packages/Python/lldbsuite/test/lang/go/runtime/TestGoLanguageRuntime
+++ b/packages/Python/lldbsuite/test/lang/go/runtime/TestGoLanguageRuntime
@@ -11,7 +11,7 @@ class TestGoLanguageRuntime(TestBase):
mydir = TestBase.compute_mydir(__file__)
@python_api_test
- @expectedFailureFreeBSD('llvm.org/pr24895')
+ @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr24895')
@skipIfRemote # Not remote test suite ready
@skipUnlessGoInstalled
def test_with_dsym_and_python_api(self):
diff --git a/packages/Python/lldbsuite/test/lang/go/types/TestGoASTContext.py b/packages/Python/lldbsuite/test/lang/go/types/TestGoASTContext.py
index 8da31e9e81f7..bf7bc93a44b4 100644
--- a/packages/Python/lldbsuite/test/lang/go/types/TestGoASTContext.py
+++ b/packages/Python/lldbsuite/test/lang/go/types/TestGoASTContext.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGoASTContext(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/TestBitfieldIvars.py b/packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/TestBitfieldIvars.py
new file mode 100644
index 000000000000..01bf241b0381
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/TestBitfieldIvars.py
@@ -0,0 +1,4 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.skipIfFreeBSD,decorators.skipIfLinux,decorators.skipIfWindows, decorators.expectedFailureAll(bugnumber="rdar://problem/17990991")])
diff --git a/packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/main.m b/packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/main.m
new file mode 100644
index 000000000000..9ee3bbe66770
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/main.m
@@ -0,0 +1,52 @@
+//===-- main.m -------------------------------------------*- Objective-C-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+@interface HasBitfield : NSObject {
+@public
+ unsigned field1 : 1;
+ unsigned field2 : 1;
+};
+
+-(id)init;
+@end
+
+@implementation HasBitfield
+-(id)init {
+ self = [super init];
+ field1 = 0;
+ field2 = 1;
+ return self;
+}
+@end
+
+@interface ContainsAHasBitfield : NSObject {
+@public
+ HasBitfield *hb;
+};
+-(id)init;
+@end
+
+@implementation ContainsAHasBitfield
+-(id)init {
+ self = [super init];
+ hb = [[HasBitfield alloc] init];
+ return self;
+}
+
+@end
+
+int main(int argc, const char * argv[]) {
+ ContainsAHasBitfield *chb = [[ContainsAHasBitfield alloc] init];
+ printf("%d\n", chb->hb->field2); //% self.expect("expression -- chb->hb->field1", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["= 0"])
+ //% self.expect("expression -- chb->hb->field2", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["= 1"]) # this must happen second
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/lang/objc/blocks/TestObjCIvarsInBlocks.py b/packages/Python/lldbsuite/test/lang/objc/blocks/TestObjCIvarsInBlocks.py
index 6a1cde1a3cb3..9fa03071c598 100644
--- a/packages/Python/lldbsuite/test/lang/objc/blocks/TestObjCIvarsInBlocks.py
+++ b/packages/Python/lldbsuite/test/lang/objc/blocks/TestObjCIvarsInBlocks.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestObjCIvarsInBlocks(TestBase):
@@ -23,7 +24,7 @@ class TestObjCIvarsInBlocks(TestBase):
@skipUnlessDarwin
@add_test_categories(['pyapi'])
- @expectedFailurei386 # This test requires the 2.0 runtime, so it will fail on i386.
+ @expectedFailureAll(archs=["i[3-6]86"], bugnumber="This test requires the 2.0 runtime, so it will fail on i386")
def test_with_python_api(self):
"""Test printing the ivars of the self when captured in blocks"""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/objc/forward-decl/TestForwardDecl.py b/packages/Python/lldbsuite/test/lang/objc/forward-decl/TestForwardDecl.py
index 207518abc91b..c153f9856603 100644
--- a/packages/Python/lldbsuite/test/lang/objc/forward-decl/TestForwardDecl.py
+++ b/packages/Python/lldbsuite/test/lang/objc/forward-decl/TestForwardDecl.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ForwardDeclTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/foundation/TestConstStrings.py b/packages/Python/lldbsuite/test/lang/objc/foundation/TestConstStrings.py
index a9298dd81cf8..4a62d6240d98 100644
--- a/packages/Python/lldbsuite/test/lang/objc/foundation/TestConstStrings.py
+++ b/packages/Python/lldbsuite/test/lang/objc/foundation/TestConstStrings.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ConstStringTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/foundation/TestFoundationDisassembly.py b/packages/Python/lldbsuite/test/lang/objc/foundation/TestFoundationDisassembly.py
index 88db12e95931..0867eec62ebe 100644
--- a/packages/Python/lldbsuite/test/lang/objc/foundation/TestFoundationDisassembly.py
+++ b/packages/Python/lldbsuite/test/lang/objc/foundation/TestFoundationDisassembly.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import unittest2
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class FoundationDisassembleTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods.py b/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods.py
index 8358bd5e923f..2a8e80f6d76e 100644
--- a/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods.py
+++ b/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods.py
@@ -10,8 +10,9 @@ from __future__ import print_function
import os, os.path, time
import lldb
import string
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
file_index = 0
@skipUnlessDarwin
diff --git a/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods2.py b/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods2.py
index b61a7702f1fe..1ee01f7f35f6 100644
--- a/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods2.py
+++ b/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods2.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class FoundationTestCase2(TestBase):
@@ -89,6 +90,7 @@ class FoundationTestCase2(TestBase):
patterns = ["\(int\) \$.* = 3"])
self.runCmd("process continue")
+ @expectedFailureAll(oslist=["macosx"], debug_info="gmodules", bugnumber="llvm.org/pr27861")
def test_NSString_expr_commands(self):
"""Test expression commands for NSString."""
self.build()
@@ -134,7 +136,7 @@ class FoundationTestCase2(TestBase):
patterns = ["\(MyString\) \$.* = ", "\(MyBase\)", "\(NSObject\)", "\(Class\)"])
self.runCmd("process continue")
- @expectedFailurei386
+ @expectedFailureAll(archs=["i[3-6]86"])
def test_NSError_po(self):
"""Test that po of the result of an unknown method doesn't require a cast."""
self.build()
diff --git a/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjectDescriptionAPI.py b/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjectDescriptionAPI.py
index a85f0fec9636..13ef44f195bb 100644
--- a/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjectDescriptionAPI.py
+++ b/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjectDescriptionAPI.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ObjectDescriptionAPITestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/foundation/TestRuntimeTypes.py b/packages/Python/lldbsuite/test/lang/objc/foundation/TestRuntimeTypes.py
index 8f191721d89b..8b37f9309ac6 100644
--- a/packages/Python/lldbsuite/test/lang/objc/foundation/TestRuntimeTypes.py
+++ b/packages/Python/lldbsuite/test/lang/objc/foundation/TestRuntimeTypes.py
@@ -8,14 +8,16 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class RuntimeTypesTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
+ @expectedFailureAll(oslist=["macosx"], debug_info="gmodules", bugnumber="llvm.org/pr27862")
def test_break(self):
"""Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'."""
if self.getArchitecture() != 'x86_64':
diff --git a/packages/Python/lldbsuite/test/lang/objc/foundation/TestSymbolTable.py b/packages/Python/lldbsuite/test/lang/objc/foundation/TestSymbolTable.py
index 72952c1878b1..b75a874c8145 100644
--- a/packages/Python/lldbsuite/test/lang/objc/foundation/TestSymbolTable.py
+++ b/packages/Python/lldbsuite/test/lang/objc/foundation/TestSymbolTable.py
@@ -6,9 +6,13 @@ from __future__ import print_function
-import os, time
+import os
+import time
+
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class FoundationSymtabTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/global_ptrs/TestGlobalObjects.py b/packages/Python/lldbsuite/test/lang/objc/global_ptrs/TestGlobalObjects.py
index c4c581b9240f..24ae1a8852b1 100644
--- a/packages/Python/lldbsuite/test/lang/objc/global_ptrs/TestGlobalObjects.py
+++ b/packages/Python/lldbsuite/test/lang/objc/global_ptrs/TestGlobalObjects.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestObjCGlobalVar(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/TestHiddenIvars.py b/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/TestHiddenIvars.py
index e85dd8f48dec..ee5589cb96cb 100644
--- a/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/TestHiddenIvars.py
+++ b/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/TestHiddenIvars.py
@@ -5,11 +5,14 @@ from __future__ import print_function
import unittest2
-import os, time
+import os
+import subprocess
+import time
+
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
-import subprocess
+from lldbsuite.test import lldbutil
class HiddenIvarsTestCase(TestBase):
@@ -26,8 +29,7 @@ class HiddenIvarsTestCase(TestBase):
self.shlib_names = ["InternalDefiner"]
@skipUnlessDarwin
- @skipIfDwarf # This test requires a stripped binary and a dSYM
- @skipIfDWO # This test requires a stripped binary and a dSYM
+ @skipIf(debug_info=no_match("dsym"), bugnumber="This test requires a stripped binary and a dSYM")
def test_expr_stripped(self):
if self.getArchitecture() == 'i386':
self.skipTest("requires modern objc runtime")
@@ -44,8 +46,7 @@ class HiddenIvarsTestCase(TestBase):
self.expr(False)
@skipUnlessDarwin
- @skipIfDwarf # This test requires a stripped binary and a dSYM
- @skipIfDWO # This test requires a stripped binary and a dSYM
+ @skipIf(debug_info=no_match("dsym"), bugnumber="This test requires a stripped binary and a dSYM")
def test_frame_variable_stripped(self):
if self.getArchitecture() == 'i386':
self.skipTest("requires modern objc runtime")
diff --git a/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/TestObjCiVarIMP.py b/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/TestObjCiVarIMP.py
index 9ed2bb98e6e1..b91725d57c60 100644
--- a/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/TestObjCiVarIMP.py
+++ b/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/TestObjCiVarIMP.py
@@ -8,10 +8,12 @@ from __future__ import print_function
import os, time
import re
+
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.support import seven
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.support.seven as seven
+from lldbsuite.test import lldbutil
def execute_command (command):
# print('%% %s' % (command))
diff --git a/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/TestModulesAutoImport.py b/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/TestModulesAutoImport.py
index 2c052aae3ba1..fece47625a84 100644
--- a/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/TestModulesAutoImport.py
+++ b/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/TestModulesAutoImport.py
@@ -4,15 +4,15 @@ from __future__ import print_function
+from distutils.version import StrictVersion
import unittest2
import os, time
import lldb
import platform
-import lldbsuite.test.lldbutil as lldbutil
-
-from distutils.version import StrictVersion
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ObjCModulesAutoImportTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/TestIncompleteModules.py b/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/TestIncompleteModules.py
index 8667e628d464..56fcaa050782 100644
--- a/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/TestIncompleteModules.py
+++ b/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/TestIncompleteModules.py
@@ -5,14 +5,12 @@ from __future__ import print_function
import unittest2
-import os, time
-import lldb
import platform
-import lldbsuite.test.lldbutil as lldbutil
-
from distutils.version import StrictVersion
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class IncompleteModulesTestCase(TestBase):
@@ -27,6 +25,7 @@ class IncompleteModulesTestCase(TestBase):
@skipUnlessDarwin
@unittest2.expectedFailure("rdar://20416388")
@unittest2.skipIf(platform.system() != "Darwin" or StrictVersion('12.0.0') > platform.release(), "Only supported on Darwin 12.0.0+")
+ @skipIfDarwin # llvm.org/pr26267
def test_expr(self):
self.build()
exe = os.path.join(os.getcwd(), "a.out")
diff --git a/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/TestModulesInlineFunctions.py b/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/TestModulesInlineFunctions.py
index d9d94a8cf321..6a9d9b518e1c 100644
--- a/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/TestModulesInlineFunctions.py
+++ b/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/TestModulesInlineFunctions.py
@@ -4,15 +4,16 @@ from __future__ import print_function
+from distutils.version import StrictVersion
+
import unittest2
import os, time
-import lldb
import platform
-import lldbsuite.test.lldbutil as lldbutil
-
-from distutils.version import StrictVersion
+import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ModulesInlineFunctionsTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/modules/TestObjCModules.py b/packages/Python/lldbsuite/test/lang/objc/modules/TestObjCModules.py
index 04fc07281811..0efdb305584b 100644
--- a/packages/Python/lldbsuite/test/lang/objc/modules/TestObjCModules.py
+++ b/packages/Python/lldbsuite/test/lang/objc/modules/TestObjCModules.py
@@ -6,13 +6,13 @@ from __future__ import print_function
import unittest2
import os, time
-import lldb
import platform
-import lldbsuite.test.lldbutil as lldbutil
-
from distutils.version import StrictVersion
+import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ObjCModulesTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc++/TestObjCXX.py b/packages/Python/lldbsuite/test/lang/objc/objc++/TestObjCXX.py
index 38ef853ae112..c702eafa1f22 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc++/TestObjCXX.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc++/TestObjCXX.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ObjCXXTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/TestObjCBaseClassSBType.py b/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/TestObjCBaseClassSBType.py
index 5d2414eed8f5..fa390cb0ad73 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/TestObjCBaseClassSBType.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/TestObjCBaseClassSBType.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ObjCDynamicValueTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py b/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py
index f7ce2809081a..3ff76d4194d2 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestObjCBuiltinTypes(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-checker/TestObjCCheckers.py b/packages/Python/lldbsuite/test/lang/objc/objc-checker/TestObjCCheckers.py
index 533ec2f6b7c4..901d84fb96d9 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-checker/TestObjCCheckers.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-checker/TestObjCCheckers.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ObjCCheckerTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-class-method/TestObjCClassMethod.py b/packages/Python/lldbsuite/test/lang/objc/objc-class-method/TestObjCClassMethod.py
index 2a978bc9c024..a5767562c077 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-class-method/TestObjCClassMethod.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-class-method/TestObjCClassMethod.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestObjCClassMethod(TestBase):
@@ -21,7 +22,7 @@ class TestObjCClassMethod(TestBase):
self.break_line = line_number(self.main_source, '// Set breakpoint here.')
@skipUnlessDarwin
- @expectedFailurei386
+ @expectedFailureAll(archs=["i[3-6]86"])
@add_test_categories(['pyapi'])
#rdar://problem/9745789 "expression" can't call functions in class methods
def test_with_python_api(self):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py b/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py
index b9e84541e2df..fc8a8129fa3c 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class ObjCDynamicSBTypeTestCase(TestBase):
@@ -25,7 +26,7 @@ class ObjCDynamicSBTypeTestCase(TestBase):
self.main_source = "main.m"
self.line = line_number(self.main_source, '// Set breakpoint here.')
- @skipIfi386
+ @skipIf(archs="i[3-6]86")
def test_dyn(self):
"""Test that we are able to properly report a usable dynamic type."""
d = {'EXE': self.exe_name}
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py b/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py
index acddfb8bd647..8720ede04cbf 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ObjCDynamicValueTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/TestObjCIvarOffsets.py b/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/TestObjCIvarOffsets.py
index 6be1d379c8eb..049b41e08d08 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/TestObjCIvarOffsets.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/TestObjCIvarOffsets.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestObjCIvarOffsets(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-ivar-protocols/TestIvarProtocols.py b/packages/Python/lldbsuite/test/lang/objc/objc-ivar-protocols/TestIvarProtocols.py
index 80305e303d03..791ce27dad00 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-ivar-protocols/TestIvarProtocols.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-ivar-protocols/TestIvarProtocols.py
@@ -1,4 +1,4 @@
-import lldbsuite.test.lldbinline as lldbinline
-import lldbsuite.test.lldbtest as lldbtest
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
-lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.skipIfFreeBSD,lldbtest.skipIfLinux,lldbtest.skipIfWindows])
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.skipIfFreeBSD,decorators.skipIfLinux,decorators.skipIfWindows])
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/TestObjCIvarStripped.py b/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/TestObjCIvarStripped.py
index 78c7123eefca..d9007c57bfb4 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/TestObjCIvarStripped.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/TestObjCIvarStripped.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestObjCIvarStripped(TestBase):
@@ -21,8 +22,7 @@ class TestObjCIvarStripped(TestBase):
self.stop_line = line_number(self.main_source, '// Set breakpoint here.')
@skipUnlessDarwin
- @skipIfDwarf # This test requires a stripped binary and a dSYM
- @skipIfDWO # This test requires a stripped binary and a dSYM
+ @skipIf(debug_info=no_match("dsym"), bugnumber="This test requires a stripped binary and a dSYM")
@add_test_categories(['pyapi'])
def test_with_python_api(self):
"""Test that we can find stripped Objective-C ivars in the runtime"""
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py b/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py
index ca77de261829..a0cf6a7a055d 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py
@@ -6,13 +6,14 @@ from __future__ import print_function
import unittest2
import os, time
-import lldb
import platform
-import lldbsuite.test.lldbutil as lldbutil
from distutils.version import StrictVersion
+import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ObjCNewSyntaxTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-optimized/TestObjcOptimized.py b/packages/Python/lldbsuite/test/lang/objc/objc-optimized/TestObjcOptimized.py
index a4a202e3f940..2c3ac27d418f 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-optimized/TestObjcOptimized.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-optimized/TestObjcOptimized.py
@@ -13,10 +13,12 @@ from __future__ import print_function
import os, time
import lldb
-from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
import re
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
# rdar://problem/9087739
# test failure: objc_optimized does not work for "-C clang -A i386"
@skipUnlessDarwin
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-property/TestObjCProperty.py b/packages/Python/lldbsuite/test/lang/objc/objc-property/TestObjCProperty.py
index c22a1f1ad532..22fe3136a511 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-property/TestObjCProperty.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-property/TestObjCProperty.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ObjCPropertyTestCase(TestBase):
@@ -112,3 +113,17 @@ class ObjCPropertyTestCase(TestBase):
idWithProtocol_error = idWithProtocol_value.GetError()
self.assertTrue (idWithProtocol_error.Success())
self.assertTrue (idWithProtocol_value.GetTypeName() == "id")
+
+ # Make sure that class property getter works as expected
+ value = frame.EvaluateExpression("BaseClass.classInt", False)
+ self.assertTrue (value.GetError().Success())
+ self.assertTrue (value.GetValueAsUnsigned (11111) == 123)
+
+ # Make sure that class property setter works as expected
+ value = frame.EvaluateExpression("BaseClass.classInt = 234", False)
+ self.assertTrue (value.GetError().Success())
+
+ # Verify that setter above actually worked
+ value = frame.EvaluateExpression("BaseClass.classInt", False)
+ self.assertTrue (value.GetError().Success())
+ self.assertTrue (value.GetValueAsUnsigned (11111) == 234)
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-property/main.m b/packages/Python/lldbsuite/test/lang/objc/objc-property/main.m
index 2ef142be9b00..8d14759fb384 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-property/main.m
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-property/main.m
@@ -6,6 +6,8 @@
@end
+static int _class_int = 123;
+
@interface BaseClass : NSObject
{
int _backedInt;
@@ -25,6 +27,7 @@
@property(getter=myGetUnbackedInt,setter=mySetUnbackedInt:) int unbackedInt;
@property int backedInt;
@property (nonatomic, assign) id <MyProtocol> idWithProtocol;
+@property(class) int classInt;
@end
@implementation BaseClass
@@ -68,6 +71,16 @@
_access_count++;
}
++ (int) classInt
+{
+ return _class_int;
+}
+
++ (void) setClassInt:(int) n
+{
+ _class_int = n;
+}
+
- (int) getAccessCount
{
return _access_count;
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/TestRuntimeIvars.py b/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/TestRuntimeIvars.py
index 80305e303d03..791ce27dad00 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/TestRuntimeIvars.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/TestRuntimeIvars.py
@@ -1,4 +1,4 @@
-import lldbsuite.test.lldbinline as lldbinline
-import lldbsuite.test.lldbtest as lldbtest
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
-lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.skipIfFreeBSD,lldbtest.skipIfLinux,lldbtest.skipIfWindows])
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.skipIfFreeBSD,decorators.skipIfLinux,decorators.skipIfWindows])
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/Makefile b/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/Makefile
index 81e7f12dea2b..6c5492dade11 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/Makefile
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/Makefile
@@ -7,9 +7,10 @@ default: a.out.stripped
a.out.stripped: a.out.dSYM
strip -o a.out.stripped a.out
+ ln -sf a.out.dSYM a.out.stripped.dSYM
clean::
rm -f a.out.stripped
- rm -rf a.out.stripped.dSYM
+ rm -rf $(wildcard *.dSYM)
include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/TestObjCStaticMethodStripped.py b/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/TestObjCStaticMethodStripped.py
index 4bcc10b8b882..7d88292a051c 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/TestObjCStaticMethodStripped.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/TestObjCStaticMethodStripped.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestObjCStaticMethodStripped(TestBase):
@@ -22,15 +23,14 @@ class TestObjCStaticMethodStripped(TestBase):
@skipUnlessDarwin
@add_test_categories(['pyapi'])
- @skipIfDwarf # This test requires a stripped binary and a dSYM
- @skipIfDWO # This test requires a stripped binary and a dSYM
+ @skipIf(debug_info=no_match("dsym"), bugnumber="This test requires a stripped binary and a dSYM")
#<rdar://problem/12042992>
def test_with_python_api(self):
"""Test calling functions in static methods with a stripped binary."""
if self.getArchitecture() == 'i386':
self.skipTest("requires modern objc runtime")
self.build()
- exe = os.path.join(os.getcwd(), "a.out.stripped")
+ exe = os.path.join(os.getcwd(), "a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-static-method/TestObjCStaticMethod.py b/packages/Python/lldbsuite/test/lang/objc/objc-static-method/TestObjCStaticMethod.py
index 89ef1e7b6898..ccba42db4ebe 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-static-method/TestObjCStaticMethod.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-static-method/TestObjCStaticMethod.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestObjCStaticMethod(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-stepping/TestObjCStepping.py b/packages/Python/lldbsuite/test/lang/objc/objc-stepping/TestObjCStepping.py
index 1df416d45133..d035287cfa00 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-stepping/TestObjCStepping.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-stepping/TestObjCStepping.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestObjCStepping(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/TestObjCStructArgument.py b/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/TestObjCStructArgument.py
index 36cde21c9d66..b2f2af766325 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/TestObjCStructArgument.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/TestObjCStructArgument.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestObjCStructArgument(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/TestObjCStructReturn.py b/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/TestObjCStructReturn.py
index 010de2180825..5a8722e71a45 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/TestObjCStructReturn.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/TestObjCStructReturn.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestObjCClassMethod(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-super/TestObjCSuper.py b/packages/Python/lldbsuite/test/lang/objc/objc-super/TestObjCSuper.py
index 84d147f632da..39a0fb716abe 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-super/TestObjCSuper.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-super/TestObjCSuper.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestObjCSuperMethod(TestBase):
@@ -21,7 +22,7 @@ class TestObjCSuperMethod(TestBase):
self.break_line = line_number(self.main_source, '// Set breakpoint here.')
@skipUnlessDarwin
- @expectedFailurei386
+ @expectedFailureAll(archs=["i[3-6]86"])
@add_test_categories(['pyapi'])
def test_with_python_api(self):
"""Test calling methods on super."""
diff --git a/packages/Python/lldbsuite/test/lang/objc/print-obj/TestPrintObj.py b/packages/Python/lldbsuite/test/lang/objc/print-obj/TestPrintObj.py
index 5c52cc0e0697..33f7a0519fa8 100644
--- a/packages/Python/lldbsuite/test/lang/objc/print-obj/TestPrintObj.py
+++ b/packages/Python/lldbsuite/test/lang/objc/print-obj/TestPrintObj.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class PrintObjTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/radar-9691614/TestObjCMethodReturningBOOL.py b/packages/Python/lldbsuite/test/lang/objc/radar-9691614/TestObjCMethodReturningBOOL.py
index 38551f671a92..32f2e7c8d6dc 100644
--- a/packages/Python/lldbsuite/test/lang/objc/radar-9691614/TestObjCMethodReturningBOOL.py
+++ b/packages/Python/lldbsuite/test/lang/objc/radar-9691614/TestObjCMethodReturningBOOL.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class MethodReturningBOOLTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/TestRdar10967107.py b/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/TestRdar10967107.py
index 0902527d424c..a4654d4bd1b4 100644
--- a/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/TestRdar10967107.py
+++ b/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/TestRdar10967107.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class Rdar10967107TestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/TestRdar11355592.py b/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/TestRdar11355592.py
index 42120a57834c..f1d38f8b7d32 100644
--- a/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/TestRdar11355592.py
+++ b/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/TestRdar11355592.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class Rdar10967107TestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/TestRdar12408181.py b/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/TestRdar12408181.py
index b95d95106032..7bc92595ef38 100644
--- a/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/TestRdar12408181.py
+++ b/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/TestRdar12408181.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class Rdar12408181TestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/real-definition/TestRealDefinition.py b/packages/Python/lldbsuite/test/lang/objc/real-definition/TestRealDefinition.py
index 30fd2a5b0f6d..c8f9a9c82c61 100644
--- a/packages/Python/lldbsuite/test/lang/objc/real-definition/TestRealDefinition.py
+++ b/packages/Python/lldbsuite/test/lang/objc/real-definition/TestRealDefinition.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestRealDefinition(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/self/TestObjCSelf.py b/packages/Python/lldbsuite/test/lang/objc/self/TestObjCSelf.py
index 37db151f9ae3..004563c55be2 100644
--- a/packages/Python/lldbsuite/test/lang/objc/self/TestObjCSelf.py
+++ b/packages/Python/lldbsuite/test/lang/objc/self/TestObjCSelf.py
@@ -2,8 +2,9 @@
Tests that ObjC member variables are available where they should be.
"""
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ObjCSelfTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/Makefile b/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/Makefile
new file mode 100644
index 000000000000..ad3cb3fadcde
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
diff --git a/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/TestObjCSingleEntryDictionary.py b/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/TestObjCSingleEntryDictionary.py
new file mode 100644
index 000000000000..7c294ef8cc64
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/TestObjCSingleEntryDictionary.py
@@ -0,0 +1,68 @@
+"""Test that we properly vend children for a single entry NSDictionary"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+import os, time
+import platform
+
+from distutils.version import StrictVersion
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class ObjCSingleEntryDictionaryTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.m', '// break here')
+
+ @skipUnlessDarwin
+ def test_single_entry_dict(self):
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break inside the foo function which takes a bar_ptr argument.
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
+
+ d1 = self.frame().FindVariable("d1")
+ d1.SetPreferSyntheticValue(True)
+ d1.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
+
+ self.assertTrue(d1.GetNumChildren() == 1, "dictionary has != 1 child elements")
+ pair = d1.GetChildAtIndex(0)
+ pair.SetPreferSyntheticValue(True)
+ pair.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
+
+ self.assertTrue(pair.GetNumChildren() == 2, "pair has != 2 child elements")
+
+ key = pair.GetChildMemberWithName("key")
+ value = pair.GetChildMemberWithName("value")
+
+ key.SetPreferSyntheticValue(True)
+ key.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
+ value.SetPreferSyntheticValue(True)
+ value.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
+
+ self.assertTrue(key.GetSummary() == '@"key"', "key doesn't contain key")
+ self.assertTrue(value.GetSummary() == '@"value"', "value doesn't contain value")
diff --git a/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/main.m b/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/main.m
new file mode 100644
index 000000000000..be472fd43c3d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/main.m
@@ -0,0 +1,7 @@
+#import <Foundation/Foundation.h>
+
+int main() {
+ NSDictionary *d1 = @{@"key" : @"value"};
+ NSLog(@"%@\n", d1); // break here
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/lang/objc/variadic_methods/TestVariadicMethods.py b/packages/Python/lldbsuite/test/lang/objc/variadic_methods/TestVariadicMethods.py
new file mode 100644
index 000000000000..791ce27dad00
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/objc/variadic_methods/TestVariadicMethods.py
@@ -0,0 +1,4 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.skipIfFreeBSD,decorators.skipIfLinux,decorators.skipIfWindows])
diff --git a/packages/Python/lldbsuite/test/lang/objc/variadic_methods/main.m b/packages/Python/lldbsuite/test/lang/objc/variadic_methods/main.m
new file mode 100644
index 000000000000..f48710e880f3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/objc/variadic_methods/main.m
@@ -0,0 +1,31 @@
+//===-- main.m -------------------------------------------*- Objective-C-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+@interface VarClass : NSObject
+- (id) lottaArgs: (id) first, ...;
+@end
+
+@implementation VarClass
+- (id) lottaArgs: (id) first, ...
+{
+ return first;
+}
+@end
+
+int
+main()
+{
+ VarClass *my_var = [[VarClass alloc] init];
+ id something = [my_var lottaArgs: @"111", @"222", nil];
+ NSLog (@"%@ - %@", my_var, something); //% self.expect("expression -O -- [my_var lottaArgs:@\"111\", @\"222\", nil]", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["111"])
+ return 0;
+}
+
diff --git a/packages/Python/lldbsuite/test/lang/objcxx/objcxx-ivar-vector/TestIvarVector.py b/packages/Python/lldbsuite/test/lang/objcxx/objcxx-ivar-vector/TestIvarVector.py
index 80305e303d03..49bc148dd579 100644
--- a/packages/Python/lldbsuite/test/lang/objcxx/objcxx-ivar-vector/TestIvarVector.py
+++ b/packages/Python/lldbsuite/test/lang/objcxx/objcxx-ivar-vector/TestIvarVector.py
@@ -1,4 +1,4 @@
-import lldbsuite.test.lldbinline as lldbinline
-import lldbsuite.test.lldbtest as lldbtest
+from lldbsuite.test import decorators
+from lldbsuite.test import lldbinline
-lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.skipIfFreeBSD,lldbtest.skipIfLinux,lldbtest.skipIfWindows])
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.skipIfFreeBSD,decorators.skipIfLinux,decorators.skipIfWindows])
diff --git a/packages/Python/lldbsuite/test/linux/builtin_trap/TestBuiltinTrap.py b/packages/Python/lldbsuite/test/linux/builtin_trap/TestBuiltinTrap.py
index ea742341512c..483697789c3d 100644
--- a/packages/Python/lldbsuite/test/linux/builtin_trap/TestBuiltinTrap.py
+++ b/packages/Python/lldbsuite/test/linux/builtin_trap/TestBuiltinTrap.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class BuiltinTrapTestCase(TestBase):
@@ -24,6 +25,7 @@ class BuiltinTrapTestCase(TestBase):
@expectedFailureAll("llvm.org/pr15936", compiler="gcc", compiler_version=["<=","4.6"])
@expectedFailureAll(archs="arm", compiler="gcc", triple=".*-android") # gcc generates incorrect linetable
+ @expectedFailureAll(oslist=['linux'], archs=['arm'])
@skipIfWindows
def test_with_run_command(self):
"""Test that LLDB handles a function with __builtin_trap correctly."""
diff --git a/packages/Python/lldbsuite/test/linux/thread/create_during_instruction_step/TestCreateDuringInstructionStep.py b/packages/Python/lldbsuite/test/linux/thread/create_during_instruction_step/TestCreateDuringInstructionStep.py
index c6d9afb02003..8421a8d473e1 100644
--- a/packages/Python/lldbsuite/test/linux/thread/create_during_instruction_step/TestCreateDuringInstructionStep.py
+++ b/packages/Python/lldbsuite/test/linux/thread/create_during_instruction_step/TestCreateDuringInstructionStep.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class CreateDuringInstructionStepTestCase(TestBase):
@@ -22,6 +23,7 @@ class CreateDuringInstructionStepTestCase(TestBase):
@skipUnlessPlatform(['linux'])
@expectedFailureAndroid('llvm.org/pr24737', archs=['arm'])
+ @expectedFailureAll(oslist=["linux"], archs=["arm"], bugnumber="llvm.org/pr24737")
def test_step_inst(self):
self.build(dictionary=self.getBuildFlags())
exe = os.path.join(os.getcwd(), "a.out")
diff --git a/packages/Python/lldbsuite/test/lldbinline.py b/packages/Python/lldbsuite/test/lldbinline.py
index abde6e790ded..6a61b2eaf557 100644
--- a/packages/Python/lldbsuite/test/lldbinline.py
+++ b/packages/Python/lldbsuite/test/lldbinline.py
@@ -9,7 +9,9 @@ import os
# LLDB modules
import lldb
from .lldbtest import *
+from . import configuration
from . import lldbutil
+from .decorators import *
def source_type(filename):
_, extension = os.path.splitext(filename)
@@ -116,8 +118,8 @@ class InlineTest(TestBase):
if ('CXX_SOURCES' in list(categories.keys())):
makefile.write("CXXFLAGS += -std=c++11\n")
- makefile.write("\ncleanup:\n\trm -f Makefile *.d\n\n")
makefile.write("include $(LEVEL)/Makefile.rules\n")
+ makefile.write("\ncleanup:\n\trm -f Makefile *.d\n\n")
makefile.flush()
makefile.close()
@@ -140,6 +142,12 @@ class InlineTest(TestBase):
self.buildDwo()
self.do_test()
+ def __test_with_gmodules(self):
+ self.using_dsym = False
+ self.BuildMakefile()
+ self.buildGModules()
+ self.do_test()
+
def execute_user_command(self, __command):
exec(__command, globals(), locals())
@@ -185,26 +193,39 @@ def ApplyDecoratorsToFunction(func, decorators):
elif hasattr(decorators, '__call__'):
tmp = decorators(tmp)
return tmp
-
+
def MakeInlineTest(__file, __globals, decorators=None):
+ # Adjust the filename if it ends in .pyc. We want filenames to
+ # reflect the source python file, not the compiled variant.
+ if __file is not None and __file.endswith(".pyc"):
+ # Strip the trailing "c"
+ __file = __file[0:-1]
+
# Derive the test name from the current file name
file_basename = os.path.basename(__file)
InlineTest.mydir = TestBase.compute_mydir(__file)
test_name, _ = os.path.splitext(file_basename)
- # Build the test case
+ # Build the test case
test = type(test_name, (InlineTest,), {'using_dsym': None})
test.name = test_name
- test.test_with_dsym = ApplyDecoratorsToFunction(test._InlineTest__test_with_dsym, decorators)
- test.test_with_dwarf = ApplyDecoratorsToFunction(test._InlineTest__test_with_dwarf, decorators)
- test.test_with_dwo = ApplyDecoratorsToFunction(test._InlineTest__test_with_dwo, decorators)
+ target_platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
+ if test_categories.is_supported_on_platform("dsym", target_platform, configuration.compilers):
+ test.test_with_dsym = ApplyDecoratorsToFunction(test._InlineTest__test_with_dsym, decorators)
+ if test_categories.is_supported_on_platform("dwarf", target_platform, configuration.compilers):
+ test.test_with_dwarf = ApplyDecoratorsToFunction(test._InlineTest__test_with_dwarf, decorators)
+ if test_categories.is_supported_on_platform("dwo", target_platform, configuration.compilers):
+ test.test_with_dwo = ApplyDecoratorsToFunction(test._InlineTest__test_with_dwo, decorators)
+ if test_categories.is_supported_on_platform("gmodules", target_platform, configuration.compilers):
+ test.test_with_gmodules = ApplyDecoratorsToFunction(test._InlineTest__test_with_gmodules, decorators)
# Add the test case to the globals, and hide InlineTest
__globals.update({test_name : test})
- # Store the name of the originating file.o
+ # Keep track of the original test filename so we report it
+ # correctly in test results.
test.test_filename = __file
return test
diff --git a/packages/Python/lldbsuite/test/lldbpexpect.py b/packages/Python/lldbsuite/test/lldbpexpect.py
index 55b958a55972..d37d6fa4f8cb 100644
--- a/packages/Python/lldbsuite/test/lldbpexpect.py
+++ b/packages/Python/lldbsuite/test/lldbpexpect.py
@@ -6,58 +6,64 @@ import os
import sys
# Third-party modules
-import pexpect
+import six
# LLDB Modules
import lldb
from .lldbtest import *
from . import lldbutil
-class PExpectTest(TestBase):
+if sys.platform.startswith('win32'):
+ class PExpectTest(TestBase):
+ pass
+else:
+ import pexpect
+
+ class PExpectTest(TestBase):
- mydir = TestBase.compute_mydir(__file__)
+ mydir = TestBase.compute_mydir(__file__)
- def setUp(self):
- TestBase.setUp(self)
+ def setUp(self):
+ TestBase.setUp(self)
- def launchArgs(self):
- pass
+ def launchArgs(self):
+ pass
+
+ def launch(self, timeout=None):
+ if timeout is None: timeout = 30
+ logfile = sys.stdout if self.TraceOn() else None
+ self.child = pexpect.spawn('%s --no-use-colors %s' % (lldbtest_config.lldbExec, self.launchArgs()), logfile=logfile)
+ self.child.timeout = timeout
+ self.timeout = timeout
+
+ def expect(self, patterns=None, timeout=None, exact=None):
+ if patterns is None: return None
+ if timeout is None: timeout = self.timeout
+ if exact is None: exact = False
+ if exact:
+ return self.child.expect_exact(patterns, timeout=timeout)
+ else:
+ return self.child.expect(patterns, timeout=timeout)
+
+ def expectall(self, patterns=None, timeout=None, exact=None):
+ if patterns is None: return None
+ if timeout is None: timeout = self.timeout
+ if exact is None: exact = False
+ for pattern in patterns:
+ self.expect(pattern, timeout=timeout, exact=exact)
+
+ def sendimpl(self, sender, command, patterns=None, timeout=None, exact=None):
+ sender(command)
+ return self.expect(patterns=patterns, timeout=timeout, exact=exact)
+
+ def send(self, command, patterns=None, timeout=None, exact=None):
+ return self.sendimpl(self.child.send, command, patterns, timeout, exact)
+
+ def sendline(self, command, patterns=None, timeout=None, exact=None):
+ return self.sendimpl(self.child.sendline, command, patterns, timeout, exact)
- def launch(self, timeout=None):
- if timeout is None: timeout = 30
- logfile = sys.stdout if self.TraceOn() else None
- self.child = pexpect.spawn('%s %s' % (lldbtest_config.lldbExec, self.launchArgs()), logfile=logfile)
- self.child.timeout = timeout
- self.timeout = timeout
-
- def expect(self, patterns=None, timeout=None, exact=None):
- if patterns is None: return None
- if timeout is None: timeout = self.timeout
- if exact is None: exact = False
- if exact:
- return self.child.expect_exact(patterns, timeout=timeout)
- else:
- return self.child.expect(patterns, timeout=timeout)
-
- def expectall(self, patterns=None, timeout=None, exact=None):
- if patterns is None: return None
- if timeout is None: timeout = self.timeout
- if exact is None: exact = False
- for pattern in patterns:
- self.expect(pattern, timeout=timeout, exact=exact)
-
- def sendimpl(self, sender, command, patterns=None, timeout=None, exact=None):
- sender(command)
- return self.expect(patterns=patterns, timeout=timeout, exact=exact)
-
- def send(self, command, patterns=None, timeout=None, exact=None):
- return self.sendimpl(self.child.send, command, patterns, timeout, exact)
-
- def sendline(self, command, patterns=None, timeout=None, exact=None):
- return self.sendimpl(self.child.sendline, command, patterns, timeout, exact)
-
- def quit(self, gracefully=None):
- if gracefully is None: gracefully = True
- self.child.sendeof()
- self.child.close(force=not gracefully)
- self.child = None
+ def quit(self, gracefully=None):
+ if gracefully is None: gracefully = True
+ self.child.sendeof()
+ self.child.close(force=not gracefully)
+ self.child = None
diff --git a/packages/Python/lldbsuite/test/lldbplatform.py b/packages/Python/lldbsuite/test/lldbplatform.py
new file mode 100644
index 000000000000..33927df6c0f1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lldbplatform.py
@@ -0,0 +1,44 @@
+""" This module represents an abstraction of an lldb target / host platform. """
+
+from __future__ import absolute_import
+
+# System modules
+import itertools
+
+# Third-party modules
+import six
+
+# LLDB modules
+import use_lldb_suite
+import lldb
+
+windows, linux, macosx, darwin, ios, darwin_all, freebsd, netbsd, bsd_all, android = range(10)
+
+__name_lookup = {
+ windows : ["windows"],
+ linux : ["linux"],
+ macosx : ["macosx"],
+ darwin : ["darwin"],
+ ios : ["ios"],
+ darwin_all : ["macosx", "darwin", "ios"],
+ freebsd : ["freebsd"],
+ netbsd : ["netbsd"],
+ bsd_all : ["freebsd", "netbsd"],
+ android : ["android"]
+}
+
+
+def translate(values):
+
+ if isinstance(values, six.integer_types):
+ # This is a value from the platform enumeration, translate it.
+ return __name_lookup[values]
+ elif isinstance(values, six.string_types):
+ # This is a raw string, return it.
+ return [values]
+ elif hasattr(values, "__iter__"):
+ # This is an iterable, convert each item.
+ result = [translate(x) for x in values]
+ result = list(itertools.chain(*result))
+ return result
+ return values
diff --git a/packages/Python/lldbsuite/test/lldbplatformutil.py b/packages/Python/lldbsuite/test/lldbplatformutil.py
index f51c016c13c2..e04a5404407f 100644
--- a/packages/Python/lldbsuite/test/lldbplatformutil.py
+++ b/packages/Python/lldbsuite/test/lldbplatformutil.py
@@ -4,12 +4,19 @@ architecture and/or the platform dependent nature of the tests. """
from __future__ import absolute_import
# System modules
+import itertools
+import re
+import subprocess
+import sys
# Third-party modules
+import six
+from six.moves.urllib import parse as urlparse
# LLDB modules
-
-import re
+from . import configuration
+import use_lldb_suite
+import lldb
def check_first_register_readable(test_case):
arch = test_case.getArchitecture()
@@ -22,6 +29,120 @@ def check_first_register_readable(test_case):
test_case.expect("register read x0", substrs = ['x0 = 0x'])
elif re.match("mips",arch):
test_case.expect("register read zero", substrs = ['zero = 0x'])
+ elif arch in ['s390x']:
+ test_case.expect("register read r0", substrs = ['r0 = 0x'])
else:
# TODO: Add check for other architectures
test_case.fail("Unsupported architecture for test case (arch: %s)" % test_case.getArchitecture())
+
+def _run_adb_command(cmd, device_id):
+ device_id_args = []
+ if device_id:
+ device_id_args = ["-s", device_id]
+ full_cmd = ["adb"] + device_id_args + cmd
+ p = subprocess.Popen(full_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ return p.returncode, stdout, stderr
+
+def _target_is_android():
+ if not hasattr(_target_is_android, 'result'):
+ triple = lldb.DBG.GetSelectedPlatform().GetTriple()
+ match = re.match(".*-.*-.*-android", triple)
+ _target_is_android.result = match is not None
+ return _target_is_android.result
+
+def android_device_api():
+ if not hasattr(android_device_api, 'result'):
+ assert configuration.lldb_platform_url is not None
+ device_id = None
+ parsed_url = urlparse.urlparse(configuration.lldb_platform_url)
+ host_name = parsed_url.netloc.split(":")[0]
+ if host_name != 'localhost':
+ device_id = host_name
+ if device_id.startswith('[') and device_id.endswith(']'):
+ device_id = device_id[1:-1]
+ retcode, stdout, stderr = _run_adb_command(
+ ["shell", "getprop", "ro.build.version.sdk"], device_id)
+ if retcode == 0:
+ android_device_api.result = int(stdout)
+ else:
+ raise LookupError(
+ ">>> Unable to determine the API level of the Android device.\n"
+ ">>> stdout:\n%s\n"
+ ">>> stderr:\n%s\n" % (stdout, stderr))
+ return android_device_api.result
+
+def match_android_device(device_arch, valid_archs=None, valid_api_levels=None):
+ if not _target_is_android():
+ return False
+ if valid_archs is not None and device_arch not in valid_archs:
+ return False
+ if valid_api_levels is not None and android_device_api() not in valid_api_levels:
+ return False
+
+ return True
+
+def finalize_build_dictionary(dictionary):
+ if _target_is_android():
+ if dictionary is None:
+ dictionary = {}
+ dictionary["OS"] = "Android"
+ if android_device_api() >= 16:
+ dictionary["PIE"] = 1
+ return dictionary
+
+def getHostPlatform():
+ """Returns the host platform running the test suite."""
+ # Attempts to return a platform name matching a target Triple platform.
+ if sys.platform.startswith('linux'):
+ return 'linux'
+ elif sys.platform.startswith('win32'):
+ return 'windows'
+ elif sys.platform.startswith('darwin'):
+ return 'darwin'
+ elif sys.platform.startswith('freebsd'):
+ return 'freebsd'
+ elif sys.platform.startswith('netbsd'):
+ return 'netbsd'
+ else:
+ return sys.platform
+
+
+def getDarwinOSTriples():
+ return ['darwin', 'macosx', 'ios']
+
+def getPlatform():
+ """Returns the target platform which the tests are running on."""
+ platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
+ if platform.startswith('freebsd'):
+ platform = 'freebsd'
+ elif platform.startswith('netbsd'):
+ platform = 'netbsd'
+ return platform
+
+def platformIsDarwin():
+ """Returns true if the OS triple for the selected platform is any valid apple OS"""
+ return getPlatform() in getDarwinOSTriples()
+
+class _PlatformContext(object):
+ """Value object class which contains platform-specific options."""
+
+ def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
+ self.shlib_environment_var = shlib_environment_var
+ self.shlib_prefix = shlib_prefix
+ self.shlib_extension = shlib_extension
+
+def createPlatformContext():
+ if platformIsDarwin():
+ return _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
+ elif getPlatform() in ("freebsd", "linux", "netbsd"):
+ return _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
+ else:
+ return None
+
+def hasChattyStderr(test_case):
+ """Some targets produce garbage on the standard error output. This utility function
+ determines whether the tests can be strict about the expected stderr contents."""
+ if match_android_device(test_case.getArchitecture(), ['aarch64'], [22]):
+ return True # The dynamic linker on the device will complain about unknown DT entries
+ return False
diff --git a/packages/Python/lldbsuite/test/lldbtest.py b/packages/Python/lldbsuite/test/lldbtest.py
index de8f57f63706..ee876bd11169 100644
--- a/packages/Python/lldbsuite/test/lldbtest.py
+++ b/packages/Python/lldbsuite/test/lldbtest.py
@@ -31,39 +31,43 @@ OK
$
"""
-from __future__ import print_function
from __future__ import absolute_import
+from __future__ import print_function
# System modules
import abc
import collections
-from distutils.version import LooseVersion
+from functools import wraps
import gc
import glob
import inspect
-import os, sys, traceback
+import io
import os.path
import re
import signal
from subprocess import *
+import sys
import time
+import traceback
import types
# Third-party modules
import unittest2
from six import add_metaclass
from six import StringIO as SixStringIO
-from six.moves.urllib import parse as urlparse
import six
# LLDB modules
+import use_lldb_suite
import lldb
from . import configuration
+from . import decorators
+from . import lldbplatformutil
from . import lldbtest_config
from . import lldbutil
from . import test_categories
-
-from .result_formatter import EventBuilder
+from lldbsuite.support import encoded_file
+from lldbsuite.support import funcutils
# dosep.py starts lots and lots of dotest instances
# This option helps you find if two (or more) dotest instances are using the same
@@ -186,10 +190,11 @@ def COMPLETION_MSG(str_before, str_after):
'''A generic message generator for the completion mechanism.'''
return "'%s' successfully completes to '%s'" % (str_before, str_after)
-def EXP_MSG(str, exe):
+def EXP_MSG(str, actual, exe):
'''A generic "'%s' returns expected result" message generator if exe.
Otherwise, it generates "'%s' matches expected result" message.'''
- return "'%s' %s expected result" % (str, 'returns' if exe else 'matches')
+
+ return "'%s' %s expected result, got '%s'" % (str, 'returns' if exe else 'matches', actual.strip())
def SETTING_MSG(setting):
'''A generic "Value of setting '%s' is correct" message generator.'''
@@ -201,7 +206,7 @@ def EnvArray():
def line_number(filename, string_to_match):
"""Helper function to return the line number of the first matched string."""
- with open(filename, 'r') as f:
+ with io.open(filename, mode='r', encoding="utf-8") as f:
for i, line in enumerate(f):
if line.find(string_to_match) != -1:
# Found our match.
@@ -414,7 +419,14 @@ def system(commands, **kwargs):
cmd = kwargs.get("args")
if cmd is None:
cmd = shellCommand
- raise CalledProcessError(retcode, cmd)
+ cpe = CalledProcessError(retcode, cmd)
+ # Ensure caller can access the stdout/stderr.
+ cpe.lldb_extensions = {
+ "stdout_content": this_output,
+ "stderr_content": this_error,
+ "command": shellCommand
+ }
+ raise cpe
output = output + this_output
error = error + this_error
return (output, error)
@@ -435,804 +447,12 @@ def builder_module():
return __import__("builder_freebsd")
if sys.platform.startswith("netbsd"):
return __import__("builder_netbsd")
+ if sys.platform.startswith("linux"):
+ # sys.platform with Python-3.x returns 'linux', but with
+ # Python-2.x it returns 'linux2'.
+ return __import__("builder_linux")
return __import__("builder_" + sys.platform)
-def run_adb_command(cmd, device_id):
- device_id_args = []
- if device_id:
- device_id_args = ["-s", device_id]
- full_cmd = ["adb"] + device_id_args + cmd
- p = Popen(full_cmd, stdout=PIPE, stderr=PIPE)
- stdout, stderr = p.communicate()
- return p.returncode, stdout, stderr
-
-def append_android_envs(dictionary):
- if dictionary is None:
- dictionary = {}
- dictionary["OS"] = "Android"
- if android_device_api() >= 16:
- dictionary["PIE"] = 1
- return dictionary
-
-def target_is_android():
- if not hasattr(target_is_android, 'result'):
- triple = lldb.DBG.GetSelectedPlatform().GetTriple()
- match = re.match(".*-.*-.*-android", triple)
- target_is_android.result = match is not None
- return target_is_android.result
-
-def android_device_api():
- if not hasattr(android_device_api, 'result'):
- assert configuration.lldb_platform_url is not None
- device_id = None
- parsed_url = urlparse.urlparse(configuration.lldb_platform_url)
- host_name = parsed_url.netloc.split(":")[0]
- if host_name != 'localhost':
- device_id = host_name
- if device_id.startswith('[') and device_id.endswith(']'):
- device_id = device_id[1:-1]
- retcode, stdout, stderr = run_adb_command(
- ["shell", "getprop", "ro.build.version.sdk"], device_id)
- if retcode == 0:
- android_device_api.result = int(stdout)
- else:
- raise LookupError(
- ">>> Unable to determine the API level of the Android device.\n"
- ">>> stdout:\n%s\n"
- ">>> stderr:\n%s\n" % (stdout, stderr))
- return android_device_api.result
-
-def check_expected_version(comparison, expected, actual):
- def fn_leq(x,y): return x <= y
- def fn_less(x,y): return x < y
- def fn_geq(x,y): return x >= y
- def fn_greater(x,y): return x > y
- def fn_eq(x,y): return x == y
- def fn_neq(x,y): return x != y
-
- op_lookup = {
- "==": fn_eq,
- "=": fn_eq,
- "!=": fn_neq,
- "<>": fn_neq,
- ">": fn_greater,
- "<": fn_less,
- ">=": fn_geq,
- "<=": fn_leq
- }
- expected_str = '.'.join([str(x) for x in expected])
- actual_str = '.'.join([str(x) for x in actual])
-
- return op_lookup[comparison](LooseVersion(actual_str), LooseVersion(expected_str))
-
-#
-# Decorators for categorizing test cases.
-#
-from functools import wraps
-
-def add_test_categories(cat):
- """Add test categories to a TestCase method"""
- cat = test_categories.validate(cat, True)
- def impl(func):
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@add_test_categories can only be used to decorate a test method")
- if hasattr(func, "categories"):
- cat.extend(func.categories)
- func.categories = cat
- return func
-
- return impl
-
-def benchmarks_test(func):
- """Decorate the item as a benchmarks test."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@benchmarks_test can only be used to decorate a test method")
- @wraps(func)
- def wrapper(self, *args, **kwargs):
- self.skipTest("benchmarks test")
- return func(self, *args, **kwargs)
-
- # Mark this function as such to separate them from the regular tests.
- wrapper.__benchmarks_test__ = True
- return wrapper
-
-def no_debug_info_test(func):
- """Decorate the item as a test what don't use any debug info. If this annotation is specified
- then the test runner won't generate a separate test for each debug info format. """
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@no_debug_info_test can only be used to decorate a test method")
- @wraps(func)
- def wrapper(self, *args, **kwargs):
- return func(self, *args, **kwargs)
-
- # Mark this function as such to separate them from the regular tests.
- wrapper.__no_debug_info_test__ = True
- return wrapper
-
-def debugserver_test(func):
- """Decorate the item as a debugserver test."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@debugserver_test can only be used to decorate a test method")
- @wraps(func)
- def wrapper(self, *args, **kwargs):
- if configuration.dont_do_debugserver_test:
- self.skipTest("debugserver tests")
- return func(self, *args, **kwargs)
-
- # Mark this function as such to separate them from the regular tests.
- wrapper.__debugserver_test__ = True
- return wrapper
-
-def llgs_test(func):
- """Decorate the item as a lldb-server test."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@llgs_test can only be used to decorate a test method")
- @wraps(func)
- def wrapper(self, *args, **kwargs):
- if configuration.dont_do_llgs_test:
- self.skipTest("llgs tests")
- return func(self, *args, **kwargs)
-
- # Mark this function as such to separate them from the regular tests.
- wrapper.__llgs_test__ = True
- return wrapper
-
-def not_remote_testsuite_ready(func):
- """Decorate the item as a test which is not ready yet for remote testsuite."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@not_remote_testsuite_ready can only be used to decorate a test method")
- @wraps(func)
- def wrapper(self, *args, **kwargs):
- if lldb.remote_platform:
- self.skipTest("not ready for remote testsuite")
- return func(self, *args, **kwargs)
-
- # Mark this function as such to separate them from the regular tests.
- wrapper.__not_ready_for_remote_testsuite_test__ = True
- return wrapper
-
-def expectedFailure(expected_fn, bugnumber=None):
- def expectedFailure_impl(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- self = args[0]
- if expected_fn(self):
- if configuration.results_formatter_object is not None:
- # Mark this test as expected to fail.
- configuration.results_formatter_object.handle_event(
- EventBuilder.event_for_mark_test_expected_failure(self))
- xfail_func = unittest2.expectedFailure(func)
- xfail_func(*args, **kwargs)
- else:
- func(*args, **kwargs)
- return wrapper
- # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
- # return decorator in this case, so it will be used to decorating original method
- if six.callable(bugnumber):
- return expectedFailure_impl(bugnumber)
- else:
- return expectedFailure_impl
-
-# You can also pass not_in(list) to reverse the sense of the test for the arguments that
-# are simple lists, namely oslist, compiler, and debug_info.
-
-def not_in(iterable):
- return lambda x : x not in iterable
-
-def check_list_or_lambda(list_or_lambda, value):
- if six.callable(list_or_lambda):
- return list_or_lambda(value)
- elif isinstance(list_or_lambda, list):
- for item in list_or_lambda:
- if value in item:
- return True
- return False
- elif isinstance(list_or_lambda, str):
- return value is None or value in list_or_lambda
- else:
- return list_or_lambda is None or value is None or list_or_lambda == value
-
-def matchArchitectures(archs, actual_arch):
- retype = type(re.compile('hello, world'))
- list_passes = isinstance(archs, list) and actual_arch in archs
- basestring_passes = isinstance(archs, six.string_types) and actual_arch == archs
- regex_passes = isinstance(archs, retype) and re.match(archs, actual_arch)
-
- return (list_passes or basestring_passes or regex_passes)
-
-# provide a function to xfail on defined oslist, compiler version, and archs
-# if none is specified for any argument, that argument won't be checked and thus means for all
-# for example,
-# @expectedFailureAll, xfail for all platform/compiler/arch,
-# @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture
-# @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386
-def expectedFailureAll(bugnumber=None, oslist=None, hostoslist=None, compiler=None, compiler_version=None, archs=None, triple=None, debug_info=None, swig_version=None, py_version=None):
- def fn(self):
- oslist_passes = check_list_or_lambda(oslist, self.getPlatform())
- hostoslist_passes = check_list_or_lambda(hostoslist, getHostPlatform())
- compiler_passes = check_list_or_lambda(self.getCompiler(), compiler) and self.expectedCompilerVersion(compiler_version)
- arch_passes = check_list_or_lambda(archs, self.getArchitecture())
- triple_passes = triple is None or re.match(triple, lldb.DBG.GetSelectedPlatform().GetTriple())
- debug_info_passes = check_list_or_lambda(debug_info, self.debug_info)
- swig_version_passes = (swig_version is None) or (not hasattr(lldb, 'swig_version')) or (check_expected_version(swig_version[0], swig_version[1], lldb.swig_version))
- py_version_passes = (py_version is None) or check_expected_version(py_version[0], py_version[1], sys.version_info)
-
- return (oslist_passes and
- hostoslist_passes and
- compiler_passes and
- arch_passes and
- triple_passes and
- debug_info_passes and
- swig_version_passes and
- py_version_passes)
- return expectedFailure(fn, bugnumber)
-
-def expectedFailureDwarf(bugnumber=None):
- return expectedFailureAll(bugnumber=bugnumber, debug_info="dwarf")
-
-def expectedFailureDwo(bugnumber=None):
- return expectedFailureAll(bugnumber=bugnumber, debug_info="dwo")
-
-def expectedFailureDsym(bugnumber=None):
- return expectedFailureAll(bugnumber=bugnumber, debug_info="dsym")
-
-def expectedFailureCompiler(compiler, compiler_version=None, bugnumber=None):
- if compiler_version is None:
- compiler_version=['=', None]
- return expectedFailureAll(bugnumber=bugnumber, compiler=compiler, compiler_version=compiler_version)
-
-# to XFAIL a specific clang versions, try this
-# @expectedFailureClang('bugnumber', ['<=', '3.4'])
-def expectedFailureClang(bugnumber=None, compiler_version=None):
- return expectedFailureCompiler('clang', compiler_version, bugnumber)
-
-def expectedFailureGcc(bugnumber=None, compiler_version=None):
- return expectedFailureCompiler('gcc', compiler_version, bugnumber)
-
-def expectedFailureIcc(bugnumber=None):
- return expectedFailureCompiler('icc', None, bugnumber)
-
-def expectedFailureArch(arch, bugnumber=None):
- def fn(self):
- return arch in self.getArchitecture()
- return expectedFailure(fn, bugnumber)
-
-def expectedFailurei386(bugnumber=None):
- return expectedFailureArch('i386', bugnumber)
-
-def expectedFailurex86_64(bugnumber=None):
- return expectedFailureArch('x86_64', bugnumber)
-
-def expectedFailureOS(oslist, bugnumber=None, compilers=None, debug_info=None, archs=None):
- def fn(self):
- return (self.getPlatform() in oslist and
- self.expectedCompiler(compilers) and
- (archs is None or self.getArchitecture() in archs) and
- (debug_info is None or self.debug_info in debug_info))
- return expectedFailure(fn, bugnumber)
-
-def expectedFailureHostOS(oslist, bugnumber=None, compilers=None):
- def fn(self):
- return (getHostPlatform() in oslist and
- self.expectedCompiler(compilers))
- return expectedFailure(fn, bugnumber)
-
-def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None):
- # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
- return expectedFailureOS(getDarwinOSTriples(), bugnumber, compilers, debug_info=debug_info)
-
-def expectedFailureFreeBSD(bugnumber=None, compilers=None, debug_info=None):
- return expectedFailureOS(['freebsd'], bugnumber, compilers, debug_info=debug_info)
-
-def expectedFailureLinux(bugnumber=None, compilers=None, debug_info=None, archs=None):
- return expectedFailureOS(['linux'], bugnumber, compilers, debug_info=debug_info, archs=archs)
-
-def expectedFailureNetBSD(bugnumber=None, compilers=None, debug_info=None):
- return expectedFailureOS(['netbsd'], bugnumber, compilers, debug_info=debug_info)
-
-def expectedFailureWindows(bugnumber=None, compilers=None, debug_info=None):
- return expectedFailureOS(['windows'], bugnumber, compilers, debug_info=debug_info)
-
-def expectedFailureHostWindows(bugnumber=None, compilers=None):
- return expectedFailureHostOS(['windows'], bugnumber, compilers)
-
-def matchAndroid(api_levels=None, archs=None):
- def match(self):
- if not target_is_android():
- return False
- if archs is not None and self.getArchitecture() not in archs:
- return False
- if api_levels is not None and android_device_api() not in api_levels:
- return False
- return True
- return match
-
-
-def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
- """ Mark a test as xfail for Android.
-
- Arguments:
- bugnumber - The LLVM pr associated with the problem.
- api_levels - A sequence of numbers specifying the Android API levels
- for which a test is expected to fail. None means all API level.
- arch - A sequence of architecture names specifying the architectures
- for which a test is expected to fail. None means all architectures.
- """
- return expectedFailure(matchAndroid(api_levels, archs), bugnumber)
-
-# Flakey tests get two chances to run. If they fail the first time round, the result formatter
-# makes sure it is run one more time.
-def expectedFlakey(expected_fn, bugnumber=None):
- def expectedFailure_impl(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- self = args[0]
- if expected_fn(self):
- # Send event marking test as explicitly eligible for rerunning.
- if configuration.results_formatter_object is not None:
- # Mark this test as rerunnable.
- configuration.results_formatter_object.handle_event(
- EventBuilder.event_for_mark_test_rerun_eligible(self))
- func(*args, **kwargs)
- return wrapper
- # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
- # return decorator in this case, so it will be used to decorating original method
- if six.callable(bugnumber):
- return expectedFailure_impl(bugnumber)
- else:
- return expectedFailure_impl
-
-def expectedFlakeyDwarf(bugnumber=None):
- def fn(self):
- return self.debug_info == "dwarf"
- return expectedFlakey(fn, bugnumber)
-
-def expectedFlakeyDsym(bugnumber=None):
- def fn(self):
- return self.debug_info == "dwarf"
- return expectedFlakey(fn, bugnumber)
-
-def expectedFlakeyOS(oslist, bugnumber=None, compilers=None):
- def fn(self):
- return (self.getPlatform() in oslist and
- self.expectedCompiler(compilers))
- return expectedFlakey(fn, bugnumber)
-
-def expectedFlakeyDarwin(bugnumber=None, compilers=None):
- # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
- return expectedFlakeyOS(getDarwinOSTriples(), bugnumber, compilers)
-
-def expectedFlakeyFreeBSD(bugnumber=None, compilers=None):
- return expectedFlakeyOS(['freebsd'], bugnumber, compilers)
-
-def expectedFlakeyLinux(bugnumber=None, compilers=None):
- return expectedFlakeyOS(['linux'], bugnumber, compilers)
-
-def expectedFlakeyNetBSD(bugnumber=None, compilers=None):
- return expectedFlakeyOS(['netbsd'], bugnumber, compilers)
-
-def expectedFlakeyCompiler(compiler, compiler_version=None, bugnumber=None):
- if compiler_version is None:
- compiler_version=['=', None]
- def fn(self):
- return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
- return expectedFlakey(fn, bugnumber)
-
-# @expectedFlakeyClang('bugnumber', ['<=', '3.4'])
-def expectedFlakeyClang(bugnumber=None, compiler_version=None):
- return expectedFlakeyCompiler('clang', compiler_version, bugnumber)
-
-# @expectedFlakeyGcc('bugnumber', ['<=', '3.4'])
-def expectedFlakeyGcc(bugnumber=None, compiler_version=None):
- return expectedFlakeyCompiler('gcc', compiler_version, bugnumber)
-
-def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None):
- return expectedFlakey(matchAndroid(api_levels, archs), bugnumber)
-
-def skipIfRemote(func):
- """Decorate the item to skip tests if testing remotely."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipIfRemote can only be used to decorate a test method")
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- if lldb.remote_platform:
- self = args[0]
- self.skipTest("skip on remote platform")
- else:
- func(*args, **kwargs)
- return wrapper
-
-def skipUnlessListedRemote(remote_list=None):
- def myImpl(func):
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipIfRemote can only be used to decorate a "
- "test method")
-
- @wraps(func)
- def wrapper(*args, **kwargs):
- if remote_list and lldb.remote_platform:
- self = args[0]
- triple = self.dbg.GetSelectedPlatform().GetTriple()
- for r in remote_list:
- if r in triple:
- func(*args, **kwargs)
- return
- self.skipTest("skip on remote platform %s" % str(triple))
- else:
- func(*args, **kwargs)
- return wrapper
-
- return myImpl
-
-def skipIfRemoteDueToDeadlock(func):
- """Decorate the item to skip tests if testing remotely due to the test deadlocking."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipIfRemote can only be used to decorate a test method")
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- if lldb.remote_platform:
- self = args[0]
- self.skipTest("skip on remote platform (deadlocks)")
- else:
- func(*args, **kwargs)
- return wrapper
-
-def skipIfNoSBHeaders(func):
- """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipIfNoSBHeaders can only be used to decorate a test method")
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- self = args[0]
- if sys.platform.startswith("darwin"):
- header = os.path.join(os.environ["LLDB_LIB_DIR"], 'LLDB.framework', 'Versions','Current','Headers','LLDB.h')
- else:
- header = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h")
- platform = sys.platform
- if not os.path.exists(header):
- self.skipTest("skip because LLDB.h header not found")
- else:
- func(*args, **kwargs)
- return wrapper
-
-def skipIfiOSSimulator(func):
- """Decorate the item to skip tests that should be skipped on the iOS Simulator."""
- return unittest2.skipIf(configuration.lldb_platform_name == 'ios-simulator', 'skip on the iOS Simulator')(func)
-
-def skipIfFreeBSD(func):
- """Decorate the item to skip tests that should be skipped on FreeBSD."""
- return skipIfPlatform(["freebsd"])(func)
-
-def skipIfNetBSD(func):
- """Decorate the item to skip tests that should be skipped on NetBSD."""
- return skipIfPlatform(["netbsd"])(func)
-
-def getDarwinOSTriples():
- return ['darwin', 'macosx', 'ios']
-
-def skipIfDarwin(func):
- """Decorate the item to skip tests that should be skipped on Darwin."""
- return skipIfPlatform(getDarwinOSTriples())(func)
-
-def skipIfLinux(func):
- """Decorate the item to skip tests that should be skipped on Linux."""
- return skipIfPlatform(["linux"])(func)
-
-def skipUnlessHostLinux(func):
- """Decorate the item to skip tests that should be skipped on any non Linux host."""
- return skipUnlessHostPlatform(["linux"])(func)
-
-def skipIfWindows(func):
- """Decorate the item to skip tests that should be skipped on Windows."""
- return skipIfPlatform(["windows"])(func)
-
-def skipIfHostWindows(func):
- """Decorate the item to skip tests that should be skipped on Windows."""
- return skipIfHostPlatform(["windows"])(func)
-
-def skipUnlessWindows(func):
- """Decorate the item to skip tests that should be skipped on any non-Windows platform."""
- return skipUnlessPlatform(["windows"])(func)
-
-def skipUnlessDarwin(func):
- """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
- return skipUnlessPlatform(getDarwinOSTriples())(func)
-
-def skipUnlessGoInstalled(func):
- """Decorate the item to skip tests when no Go compiler is available."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipIfGcc can only be used to decorate a test method")
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- self = args[0]
- compiler = self.getGoCompilerVersion()
- if not compiler:
- self.skipTest("skipping because go compiler not found")
- else:
- # Ensure the version is the minimum version supported by
- # the LLDB go support.
- match_version = re.search(r"(\d+\.\d+(\.\d+)?)", compiler)
- if not match_version:
- # Couldn't determine version.
- self.skipTest(
- "skipping because go version could not be parsed "
- "out of {}".format(compiler))
- else:
- from distutils.version import StrictVersion
- min_strict_version = StrictVersion("1.4.0")
- compiler_strict_version = StrictVersion(match_version.group(1))
- if compiler_strict_version < min_strict_version:
- self.skipTest(
- "skipping because available go version ({}) does "
- "not meet minimum required go version ({})".format(
- compiler_strict_version,
- min_strict_version))
- func(*args, **kwargs)
- return wrapper
-
-def getPlatform():
- """Returns the target platform which the tests are running on."""
- platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
- if platform.startswith('freebsd'):
- platform = 'freebsd'
- elif platform.startswith('netbsd'):
- platform = 'netbsd'
- return platform
-
-def getHostPlatform():
- """Returns the host platform running the test suite."""
- # Attempts to return a platform name matching a target Triple platform.
- if sys.platform.startswith('linux'):
- return 'linux'
- elif sys.platform.startswith('win32'):
- return 'windows'
- elif sys.platform.startswith('darwin'):
- return 'darwin'
- elif sys.platform.startswith('freebsd'):
- return 'freebsd'
- elif sys.platform.startswith('netbsd'):
- return 'netbsd'
- else:
- return sys.platform
-
-def platformIsDarwin():
- """Returns true if the OS triple for the selected platform is any valid apple OS"""
- return getPlatform() in getDarwinOSTriples()
-
-def skipIfHostIncompatibleWithRemote(func):
- """Decorate the item to skip tests if binaries built on this host are incompatible."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipIfHostIncompatibleWithRemote can only be used to decorate a test method")
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- self = args[0]
- host_arch = self.getLldbArchitecture()
- host_platform = getHostPlatform()
- target_arch = self.getArchitecture()
- target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform()
- if not (target_arch == 'x86_64' and host_arch == 'i386') and host_arch != target_arch:
- self.skipTest("skipping because target %s is not compatible with host architecture %s" % (target_arch, host_arch))
- elif target_platform != host_platform:
- self.skipTest("skipping because target is %s but host is %s" % (target_platform, host_platform))
- else:
- func(*args, **kwargs)
- return wrapper
-
-def skipIfHostPlatform(oslist):
- """Decorate the item to skip tests if running on one of the listed host platforms."""
- return unittest2.skipIf(getHostPlatform() in oslist,
- "skip on %s" % (", ".join(oslist)))
-
-def skipUnlessHostPlatform(oslist):
- """Decorate the item to skip tests unless running on one of the listed host platforms."""
- return unittest2.skipUnless(getHostPlatform() in oslist,
- "requires on of %s" % (", ".join(oslist)))
-
-def skipUnlessArch(archs):
- """Decorate the item to skip tests unless running on one of the listed architectures."""
- def myImpl(func):
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipUnlessArch can only be used to decorate a test method")
-
- @wraps(func)
- def wrapper(*args, **kwargs):
- self = args[0]
- if not matchArchitectures(archs, self.getArchitecture()):
- self.skipTest("skipping for architecture %s" % (self.getArchitecture()))
- else:
- func(*args, **kwargs)
- return wrapper
-
- return myImpl
-
-def skipIfPlatform(oslist):
- """Decorate the item to skip tests if running on one of the listed platforms."""
- return unittest2.skipIf(getPlatform() in oslist,
- "skip on %s" % (", ".join(oslist)))
-
-def skipUnlessPlatform(oslist):
- """Decorate the item to skip tests unless running on one of the listed platforms."""
- return unittest2.skipUnless(getPlatform() in oslist,
- "requires on of %s" % (", ".join(oslist)))
-
-def skipIfLinuxClang(func):
- """Decorate the item to skip tests that should be skipped if building on
- Linux with clang.
- """
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipIfLinuxClang can only be used to decorate a test method")
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- self = args[0]
- compiler = self.getCompiler()
- platform = self.getPlatform()
- if "clang" in compiler and platform == "linux":
- self.skipTest("skipping because Clang is used on Linux")
- else:
- func(*args, **kwargs)
- return wrapper
-
-# provide a function to skip on defined oslist, compiler version, and archs
-# if none is specified for any argument, that argument won't be checked and thus means for all
-# for example,
-# @skipIf, skip for all platform/compiler/arch,
-# @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
-# @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
-
-# TODO: refactor current code, to make skipIfxxx functions to call this function
-def skipIf(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None, debug_info=None, swig_version=None, py_version=None, remote=None):
- def fn(self):
- oslist_passes = check_list_or_lambda(oslist, self.getPlatform())
- compiler_passes = check_list_or_lambda(self.getCompiler(), compiler) and self.expectedCompilerVersion(compiler_version)
- arch_passes = check_list_or_lambda(archs, self.getArchitecture())
- debug_info_passes = check_list_or_lambda(debug_info, self.debug_info)
- swig_version_passes = (swig_version is None) or (not hasattr(lldb, 'swig_version')) or (check_expected_version(swig_version[0], swig_version[1], lldb.swig_version))
- py_version_passes = (py_version is None) or check_expected_version(py_version[0], py_version[1], sys.version_info)
- remote_passes = (remote is None) or (remote == (lldb.remote_platform is not None))
-
- return (oslist_passes and
- compiler_passes and
- arch_passes and
- debug_info_passes and
- swig_version_passes and
- py_version_passes and
- remote_passes)
-
- local_vars = locals()
- args = [x for x in inspect.getargspec(skipIf).args]
- arg_vals = [eval(x, globals(), local_vars) for x in args]
- args = [x for x in zip(args, arg_vals) if x[1] is not None]
- reasons = ['%s=%s' % (x, str(y)) for (x,y) in args]
- return skipTestIfFn(fn, bugnumber, skipReason='skipping because ' + ' && '.join(reasons))
-
-def skipIfDebugInfo(bugnumber=None, debug_info=None):
- return skipIf(bugnumber=bugnumber, debug_info=debug_info)
-
-def skipIfDWO(bugnumber=None):
- return skipIfDebugInfo(bugnumber, ["dwo"])
-
-def skipIfDwarf(bugnumber=None):
- return skipIfDebugInfo(bugnumber, ["dwarf"])
-
-def skipIfDsym(bugnumber=None):
- return skipIfDebugInfo(bugnumber, ["dsym"])
-
-def skipTestIfFn(expected_fn, bugnumber=None, skipReason=None):
- def skipTestIfFn_impl(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- self = args[0]
- if expected_fn(self):
- self.skipTest(skipReason)
- else:
- func(*args, **kwargs)
- return wrapper
- if six.callable(bugnumber):
- return skipTestIfFn_impl(bugnumber)
- else:
- return skipTestIfFn_impl
-
-def skipIfGcc(func):
- """Decorate the item to skip tests that should be skipped if building with gcc ."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipIfGcc can only be used to decorate a test method")
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- self = args[0]
- compiler = self.getCompiler()
- if "gcc" in compiler:
- self.skipTest("skipping because gcc is the test compiler")
- else:
- func(*args, **kwargs)
- return wrapper
-
-def skipIfIcc(func):
- """Decorate the item to skip tests that should be skipped if building with icc ."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipIfIcc can only be used to decorate a test method")
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- self = args[0]
- compiler = self.getCompiler()
- if "icc" in compiler:
- self.skipTest("skipping because icc is the test compiler")
- else:
- func(*args, **kwargs)
- return wrapper
-
-def skipIfi386(func):
- """Decorate the item to skip tests that should be skipped if building 32-bit."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipIfi386 can only be used to decorate a test method")
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- self = args[0]
- if "i386" == self.getArchitecture():
- self.skipTest("skipping because i386 is not a supported architecture")
- else:
- func(*args, **kwargs)
- return wrapper
-
-def skipIfTargetAndroid(api_levels=None, archs=None):
- """Decorator to skip tests when the target is Android.
-
- Arguments:
- api_levels - The API levels for which the test should be skipped. If
- it is None, then the test will be skipped for all API levels.
- arch - A sequence of architecture names specifying the architectures
- for which a test is skipped. None means all architectures.
- """
- def myImpl(func):
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipIfTargetAndroid can only be used to "
- "decorate a test method")
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- self = args[0]
- if matchAndroid(api_levels, archs)(self):
- self.skipTest("skiped on Android target with API %d and architecture %s" %
- (android_device_api(), self.getArchitecture()))
- func(*args, **kwargs)
- return wrapper
- return myImpl
-
-def skipUnlessCompilerRt(func):
- """Decorate the item to skip tests if testing remotely."""
- if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipUnless can only be used to decorate a test method")
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- import os.path
- compilerRtPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", "llvm","projects","compiler-rt")
- print(compilerRtPath)
- if not os.path.exists(compilerRtPath):
- self = args[0]
- self.skipTest("skip if compiler-rt not found")
- else:
- func(*args, **kwargs)
- return wrapper
-
-class _PlatformContext(object):
- """Value object class which contains platform-specific options."""
-
- def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
- self.shlib_environment_var = shlib_environment_var
- self.shlib_prefix = shlib_prefix
- self.shlib_extension = shlib_extension
-
class Base(unittest2.TestCase):
"""
@@ -1298,12 +518,7 @@ class Base(unittest2.TestCase):
raise ioerror
# Set platform context.
- if platformIsDarwin():
- cls.platformContext = _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
- elif getPlatform() in ("freebsd", "linux", "netbsd"):
- cls.platformContext = _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
- else:
- cls.platformContext = None
+ cls.platformContext = lldbplatformutil.createPlatformContext()
@classmethod
def tearDownClass(cls):
@@ -1368,7 +583,7 @@ class Base(unittest2.TestCase):
else:
categories = "default"
- if channel == "gdb-remote":
+ if channel == "gdb-remote" and lldb.remote_platform is None:
# communicate gdb-remote categories to debugserver
os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories
@@ -1377,15 +592,17 @@ class Base(unittest2.TestCase):
raise Exception('log enable failed (check LLDB_LOG_OPTION env variable)')
# Communicate log path name to debugserver & lldb-server
- server_log_path = "{}-server.log".format(log_basename)
- open(server_log_path, 'w').close()
- os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
+ # For remote debugging, these variables need to be set when starting the platform
+ # instance.
+ if lldb.remote_platform is None:
+ server_log_path = "{}-server.log".format(log_basename)
+ open(server_log_path, 'w').close()
+ os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
- # Communicate channels to lldb-server
- os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(lldbtest_config.channels)
+ # Communicate channels to lldb-server
+ os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(lldbtest_config.channels)
- if len(lldbtest_config.channels) == 0:
- return
+ self.addTearDownHook(self.disableLogChannelsForCurrentTest)
def disableLogChannelsForCurrentTest(self):
# close all log files that we opened
@@ -1396,6 +613,42 @@ class Base(unittest2.TestCase):
if not self.res.Succeeded():
raise Exception('log disable failed (check LLDB_LOG_OPTION env variable)')
+ # Retrieve the server log (if any) from the remote system. It is assumed the server log
+ # is writing to the "server.log" file in the current test directory. This can be
+ # achieved by setting LLDB_DEBUGSERVER_LOG_FILE="server.log" when starting remote
+ # platform. If the remote logging is not enabled, then just let the Get() command silently
+ # fail.
+ if lldb.remote_platform:
+ lldb.remote_platform.Get(lldb.SBFileSpec("server.log"),
+ lldb.SBFileSpec(self.getLogBasenameForCurrentTest()+"-server.log"))
+
+ def setPlatformWorkingDir(self):
+ if not lldb.remote_platform or not configuration.lldb_platform_working_dir:
+ return
+
+ remote_test_dir = lldbutil.join_remote_paths(
+ configuration.lldb_platform_working_dir,
+ self.getArchitecture(),
+ str(self.test_number),
+ self.mydir)
+ error = lldb.remote_platform.MakeDirectory(remote_test_dir, 448) # 448 = 0o700
+ if error.Success():
+ lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
+
+ # This function removes all files from the current working directory while leaving
+ # the directories in place. The cleaup is required to reduce the disk space required
+ # by the test suit while leaving the directories untached is neccessary because
+ # sub-directories might belong to an other test
+ def clean_working_directory():
+ # TODO: Make it working on Windows when we need it for remote debugging support
+ # TODO: Replace the heuristic to remove the files with a logic what collects the
+ # list of files we have to remove during test runs.
+ shell_cmd = lldb.SBPlatformShellCommand("rm %s/*" % remote_test_dir)
+ lldb.remote_platform.Run(shell_cmd)
+ self.addTearDownHook(clean_working_directory)
+ else:
+ print("error: making remote directory '%s': %s" % (remote_test_dir, error))
+
def setUp(self):
"""Fixture for unittest test case setup.
@@ -1458,7 +711,7 @@ class Base(unittest2.TestCase):
session_file = "{}.log".format(self.log_basename)
# Python 3 doesn't support unbuffered I/O in text mode. Open buffered.
- self.session = open(session_file, "w")
+ self.session = encoded_file.open(session_file, "utf-8", mode="w")
# Optimistically set __errored__, __failed__, __expected__ to False
# initially. If the test errored/failed, the session info
@@ -1501,6 +754,7 @@ class Base(unittest2.TestCase):
# And the result object.
self.res = lldb.SBCommandReturnObject()
+ self.setPlatformWorkingDir()
self.enableLogChannelsForCurrentTest()
#Initialize debug_info
@@ -1652,11 +906,7 @@ class Base(unittest2.TestCase):
for hook in reversed(self.hooks):
with recording(self, traceAlways) as sbuf:
print("Executing tearDown hook:", getsource_if_available(hook), file=sbuf)
- import inspect
- hook_argc = len(inspect.getargspec(hook).args)
- if hook_argc == 0 or getattr(hook,'im_self',None):
- hook()
- elif hook_argc == 1:
+ if funcutils.requires_self(hook):
hook(self)
else:
hook() # try the plain call and hope it works
@@ -1673,8 +923,6 @@ class Base(unittest2.TestCase):
for dict in reversed(self.dicts):
self.cleanup(dictionary=dict)
- self.disableLogChannelsForCurrentTest()
-
# =========================================================
# Various callbacks to allow introspection of test progress
# =========================================================
@@ -1751,19 +999,27 @@ class Base(unittest2.TestCase):
if not os.path.isdir(dname):
os.mkdir(dname)
- compiler = self.getCompiler()
-
- if compiler[1] == ':':
- compiler = compiler[2:]
- if os.path.altsep is not None:
- compiler = compiler.replace(os.path.altsep, os.path.sep)
-
- fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), "_".join(compiler.split(os.path.sep)))
- if len(fname) > 200:
- fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), compiler.split(os.path.sep)[-1])
-
+ components = []
if prefix is not None:
- fname = "{}-{}".format(prefix, fname)
+ components.append(prefix)
+ for c in configuration.session_file_format:
+ if c == 'f':
+ components.append(self.__class__.__module__)
+ elif c == 'n':
+ components.append(self.__class__.__name__)
+ elif c == 'c':
+ compiler = self.getCompiler()
+
+ if compiler[1] == ':':
+ compiler = compiler[2:]
+ if os.path.altsep is not None:
+ compiler = compiler.replace(os.path.altsep, os.path.sep)
+ components.extend([x for x in compiler.split(os.path.sep) if x != ""])
+ elif c == 'a':
+ components.append(self.getArchitecture())
+ elif c == 'm':
+ components.append(self.testMethodName)
+ fname = "-".join(components)
return os.path.join(dname, fname)
@@ -1844,23 +1100,13 @@ class Base(unittest2.TestCase):
# it silently replaces the destination. Ultimately this means that atomic renames are not
# guaranteed to be possible on Windows, but we need this to work anyway, so just remove the
# destination first if it already exists.
- os.remove(dst)
+ remove_file(dst)
os.rename(src, dst)
else:
# success! (and we don't want log files) delete log files
for log_file in log_files_for_this_test:
- try:
- os.unlink(log_file)
- except:
- # We've seen consistent unlink failures on Windows, perhaps because the
- # just-created log file is being scanned by anti-virus. Empirically, this
- # sleep-and-retry approach allows tests to succeed much more reliably.
- # Attempts to figure out exactly what process was still holding a file handle
- # have failed because running instrumentation like Process Monitor seems to
- # slow things down enough that the problem becomes much less consistent.
- time.sleep(0.5)
- os.unlink(log_file)
+ remove_file(log_file)
# ====================================================
# Config. methods supported through a plugin interface
@@ -1912,11 +1158,10 @@ class Base(unittest2.TestCase):
""" Returns a string that represents the compiler version.
Supports: llvm, clang.
"""
- from .lldbutil import which
version = 'unknown'
compiler = self.getCompilerBinary()
- version_output = system([[which(compiler), "-v"]])[1]
+ version_output = system([[compiler, "-v"]])[1]
for line in version_output.split(os.linesep):
m = re.search('version ([0-9\.]+)', line)
if m:
@@ -1937,11 +1182,11 @@ class Base(unittest2.TestCase):
def platformIsDarwin(self):
"""Returns true if the OS triple for the selected platform is any valid apple OS"""
- return platformIsDarwin()
+ return lldbplatformutil.platformIsDarwin()
def getPlatform(self):
"""Returns the target platform the test suite is running on."""
- return getPlatform()
+ return lldbplatformutil.getPlatform()
def isIntelCompiler(self):
""" Returns true if using an Intel (ICC) compiler, false otherwise. """
@@ -2097,8 +1342,7 @@ class Base(unittest2.TestCase):
def buildDefault(self, architecture=None, compiler=None, dictionary=None, clean=True):
"""Platform specific way to build the default binaries."""
module = builder_module()
- if target_is_android():
- dictionary = append_android_envs(dictionary)
+ dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
if not module.buildDefault(self, architecture, compiler, dictionary, clean):
raise Exception("Don't know how to build default binary")
@@ -2111,19 +1355,23 @@ class Base(unittest2.TestCase):
def buildDwarf(self, architecture=None, compiler=None, dictionary=None, clean=True):
"""Platform specific way to build binaries with dwarf maps."""
module = builder_module()
- if target_is_android():
- dictionary = append_android_envs(dictionary)
+ dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
raise Exception("Don't know how to build binary with dwarf")
def buildDwo(self, architecture=None, compiler=None, dictionary=None, clean=True):
"""Platform specific way to build binaries with dwarf maps."""
module = builder_module()
- if target_is_android():
- dictionary = append_android_envs(dictionary)
+ dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
if not module.buildDwo(self, architecture, compiler, dictionary, clean):
raise Exception("Don't know how to build binary with dwo")
+ def buildGModules(self, architecture=None, compiler=None, dictionary=None, clean=True):
+ """Platform specific way to build binaries with gmodules info."""
+ module = builder_module()
+ if not module.buildGModules(self, architecture, compiler, dictionary, clean):
+ raise Exception("Don't know how to build binary with gmodules")
+
def buildGo(self):
"""Build the default go binary.
"""
@@ -2221,9 +1469,15 @@ class Base(unittest2.TestCase):
# Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
# We change the test methods to create a new test method for each test for each debug info we are
# testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
-# the new test method we remove the old method at the same time.
+# the new test method we remove the old method at the same time. This functionality can be
+# supressed by at test case level setting the class attribute NO_DEBUG_INFO_TESTCASE or at test
+# level by using the decorator @no_debug_info_test.
class LLDBTestCaseFactory(type):
def __new__(cls, name, bases, attrs):
+ original_testcase = super(LLDBTestCaseFactory, cls).__new__(cls, name, bases, attrs)
+ if original_testcase.NO_DEBUG_INFO_TESTCASE:
+ return original_testcase
+
newattrs = {}
for attrname, attrvalue in attrs.items():
if attrname.startswith("test") and not getattr(attrvalue, "__no_debug_info_test__", False):
@@ -2236,10 +1490,11 @@ class LLDBTestCaseFactory(type):
if not categories:
categories = all_dbginfo_categories
- supported_categories = [x for x in categories
- if test_categories.is_supported_on_platform(x, target_platform)]
+ supported_categories = [x for x in categories
+ if test_categories.is_supported_on_platform(
+ x, target_platform, configuration.compilers)]
if "dsym" in supported_categories:
- @add_test_categories(["dsym"])
+ @decorators.add_test_categories(["dsym"])
@wraps(attrvalue)
def dsym_test_method(self, attrvalue=attrvalue):
self.debug_info = "dsym"
@@ -2249,7 +1504,7 @@ class LLDBTestCaseFactory(type):
newattrs[dsym_method_name] = dsym_test_method
if "dwarf" in supported_categories:
- @add_test_categories(["dwarf"])
+ @decorators.add_test_categories(["dwarf"])
@wraps(attrvalue)
def dwarf_test_method(self, attrvalue=attrvalue):
self.debug_info = "dwarf"
@@ -2259,7 +1514,7 @@ class LLDBTestCaseFactory(type):
newattrs[dwarf_method_name] = dwarf_test_method
if "dwo" in supported_categories:
- @add_test_categories(["dwo"])
+ @decorators.add_test_categories(["dwo"])
@wraps(attrvalue)
def dwo_test_method(self, attrvalue=attrvalue):
self.debug_info = "dwo"
@@ -2267,6 +1522,17 @@ class LLDBTestCaseFactory(type):
dwo_method_name = attrname + "_dwo"
dwo_test_method.__name__ = dwo_method_name
newattrs[dwo_method_name] = dwo_test_method
+
+ if "gmodules" in supported_categories:
+ @decorators.add_test_categories(["gmodules"])
+ @wraps(attrvalue)
+ def gmodules_test_method(self, attrvalue=attrvalue):
+ self.debug_info = "gmodules"
+ return attrvalue(self)
+ gmodules_method_name = attrname + "_gmodules"
+ gmodules_test_method.__name__ = gmodules_method_name
+ newattrs[gmodules_method_name] = gmodules_test_method
+
else:
newattrs[attrname] = attrvalue
return super(LLDBTestCaseFactory, cls).__new__(cls, name, bases, newattrs)
@@ -2325,6 +1591,10 @@ class TestBase(Base):
Mac OS X implementation is located in plugins/darwin.py.
"""
+ # Subclasses can set this to true (if they don't depend on debug info) to avoid running the
+ # test multiple times with various debug info types.
+ NO_DEBUG_INFO_TESTCASE = False
+
# Maximum allowed attempts when launching the inferior process.
# Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
maxLaunchCount = 3;
@@ -2381,30 +1651,6 @@ class TestBase(Base):
# And the result object.
self.res = lldb.SBCommandReturnObject()
- if lldb.remote_platform and configuration.lldb_platform_working_dir:
- remote_test_dir = lldbutil.join_remote_paths(
- configuration.lldb_platform_working_dir,
- self.getArchitecture(),
- str(self.test_number),
- self.mydir)
- error = lldb.remote_platform.MakeDirectory(remote_test_dir, 448) # 448 = 0o700
- if error.Success():
- lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
-
- # This function removes all files from the current working directory while leaving
- # the directories in place. The cleaup is required to reduce the disk space required
- # by the test suit while leaving the directories untached is neccessary because
- # sub-directories might belong to an other test
- def clean_working_directory():
- # TODO: Make it working on Windows when we need it for remote debugging support
- # TODO: Replace the heuristic to remove the files with a logic what collects the
- # list of files we have to remove during test runs.
- shell_cmd = lldb.SBPlatformShellCommand("rm %s/*" % remote_test_dir)
- lldb.remote_platform.Run(shell_cmd)
- self.addTearDownHook(clean_working_directory)
- else:
- print("error: making remote directory '%s': %s" % (remote_test_dir, error))
-
def registerSharedLibrariesWithTarget(self, target, shlibs):
'''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
@@ -2608,7 +1854,7 @@ class TestBase(Base):
break
self.assertTrue(matched if matching else not matched,
- msg if msg else EXP_MSG(str, exe))
+ msg if msg else EXP_MSG(str, output, exe))
return match_object
@@ -2682,10 +1928,10 @@ class TestBase(Base):
# Look for sub strings, if specified.
keepgoing = matched if matching else not matched
if substrs and keepgoing:
- for str in substrs:
- matched = output.find(str) != -1
+ for substr in substrs:
+ matched = output.find(substr) != -1
with recording(self, trace) as sbuf:
- print("%s sub string: %s" % (heading, str), file=sbuf)
+ print("%s sub string: %s" % (heading, substr), file=sbuf)
print("Matched" if matched else "Not matched", file=sbuf)
keepgoing = matched if matching else not matched
if not keepgoing:
@@ -2705,7 +1951,7 @@ class TestBase(Base):
break
self.assertTrue(matched if matching else not matched,
- msg if msg else EXP_MSG(str, exe))
+ msg if msg else EXP_MSG(str, output, exe))
def invoke(self, obj, name, trace=False):
"""Use reflection to call a method dynamically with no argument."""
@@ -2723,8 +1969,7 @@ class TestBase(Base):
def build(self, architecture=None, compiler=None, dictionary=None, clean=True):
"""Platform specific way to build the default binaries."""
module = builder_module()
- if target_is_android():
- dictionary = append_android_envs(dictionary)
+ dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
if self.debug_info is None:
return self.buildDefault(architecture, compiler, dictionary, clean)
elif self.debug_info == "dsym":
@@ -2733,9 +1978,17 @@ class TestBase(Base):
return self.buildDwarf(architecture, compiler, dictionary, clean)
elif self.debug_info == "dwo":
return self.buildDwo(architecture, compiler, dictionary, clean)
+ elif self.debug_info == "gmodules":
+ return self.buildGModules(architecture, compiler, dictionary, clean)
else:
self.fail("Can't build for debug info: %s" % self.debug_info)
+ def run_platform_command(self, cmd):
+ platform = self.dbg.GetSelectedPlatform()
+ shell_command = lldb.SBPlatformShellCommand(cmd)
+ err = platform.Run(shell_command)
+ return (err, shell_command.GetStatus(), shell_command.GetOutput())
+
# =================================================
# Misc. helper methods for debugging test execution
# =================================================
@@ -2780,4 +2033,17 @@ class TestBase(Base):
@classmethod
def RemoveTempFile(cls, file):
if os.path.exists(file):
+ remove_file(file)
+
+# On Windows, the first attempt to delete a recently-touched file can fail
+# because of a race with antimalware scanners. This function will detect a
+# failure and retry.
+def remove_file(file, num_retries = 1, sleep_duration = 0.5):
+ for i in range(num_retries+1):
+ try:
os.remove(file)
+ return True
+ except:
+ time.sleep(sleep_duration)
+ continue
+ return False
diff --git a/packages/Python/lldbsuite/test/lldbutil.py b/packages/Python/lldbsuite/test/lldbutil.py
index 339619dc4f74..45e9bb407d15 100644
--- a/packages/Python/lldbsuite/test/lldbutil.py
+++ b/packages/Python/lldbsuite/test/lldbutil.py
@@ -12,6 +12,7 @@ import collections
import os
import re
import sys
+import time
# Third-party modules
from six import StringIO as SixStringIO
@@ -84,7 +85,7 @@ def int_to_bytearray(val, bytesize):
return None
packed = struct.pack(fmt, val)
- return bytearray(list(map(ord, packed)))
+ return bytearray(packed)
def bytearray_to_int(bytes, bytesize):
"""Utility function to convert a bytearray into an integer.
@@ -108,7 +109,7 @@ def bytearray_to_int(bytes, bytesize):
else:
return None
- unpacked = struct.unpack(fmt, str(bytes))
+ unpacked = struct.unpack_from(fmt, bytes)
return unpacked[0]
@@ -548,7 +549,7 @@ def get_stopped_thread(process, reason):
return None
return threads[0]
-def get_threads_stopped_at_breakpoint (process, bkpt):
+def get_threads_stopped_at_breakpoint_id(process, bpid):
""" For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
stopped_threads = []
threads = []
@@ -561,11 +562,26 @@ def get_threads_stopped_at_breakpoint (process, bkpt):
for thread in stopped_threads:
# Make sure we've hit our breakpoint...
break_id = thread.GetStopReasonDataAtIndex (0)
- if break_id == bkpt.GetID():
+ if break_id == bpid:
threads.append(thread)
return threads
+def get_threads_stopped_at_breakpoint (process, bkpt):
+ return get_threads_stopped_at_breakpoint_id(process, bkpt.GetID())
+
+def get_one_thread_stopped_at_breakpoint_id(process, bpid, require_exactly_one = True):
+ threads = get_threads_stopped_at_breakpoint_id(process, bpid)
+ if len(threads) == 0:
+ return None
+ if require_exactly_one and len(threads) != 1:
+ return None
+
+ return threads[0]
+
+def get_one_thread_stopped_at_breakpoint(process, bkpt, require_exactly_one = True):
+ return get_one_thread_stopped_at_breakpoint_id(process, bkpt.GetID(), require_exactly_one)
+
def is_thread_crashed (test, thread):
"""In the test suite we dereference a null pointer to simulate a crash. The way this is
reported depends on the platform."""
@@ -734,14 +750,15 @@ def print_stacktraces(process, string_buffer = False):
if string_buffer:
return output.getvalue()
-def expect_state_changes(test, listener, states, timeout = 5):
+def expect_state_changes(test, listener, process, states, timeout = 5):
"""Listens for state changed events on the listener and makes sure they match what we
expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored."""
for expected_state in states:
def get_next_event():
event = lldb.SBEvent()
- if not listener.WaitForEvent(timeout, event):
+ if not listener.WaitForEventForBroadcasterWithType(timeout, process.GetBroadcaster(),
+ lldb.SBProcess.eBroadcastBitStateChanged, event):
test.fail("Timed out while waiting for a transition to state %s" %
lldb.SBDebugger.StateAsCString(expected_state))
return event
@@ -1014,3 +1031,21 @@ def skip_if_library_missing(test, target, library):
def find_library_callable(test):
return find_library(target, library)
return skip_if_callable(test, find_library_callable, "could not find library matching '%s' in target %s" % (library, target))
+
+def wait_for_file_on_target(testcase, file_path, max_attempts = 6):
+ for i in range(max_attempts):
+ err, retcode, msg = testcase.run_platform_command("ls %s" % file_path)
+ if err.Success() and retcode == 0:
+ break
+ if i < max_attempts:
+ # Exponential backoff!
+ import time
+ time.sleep(pow(2, i) * 0.25)
+ else:
+ testcase.fail("File %s not found even after %d attempts." % (file_path, max_attempts))
+
+ err, retcode, data = testcase.run_platform_command("cat %s" % (file_path))
+
+ testcase.assertTrue(err.Success() and retcode == 0,
+ "Failed to read file %s: %s, retcode: %d" % (file_path, err.GetCString(), retcode))
+ return data
diff --git a/packages/Python/lldbsuite/test/logging/TestLogging.py b/packages/Python/lldbsuite/test/logging/TestLogging.py
index f8558a758ee9..cba587e5d8a0 100644
--- a/packages/Python/lldbsuite/test/logging/TestLogging.py
+++ b/packages/Python/lldbsuite/test/logging/TestLogging.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import os, time, string
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class LogTestCase(TestBase):
@@ -61,7 +63,7 @@ class LogTestCase(TestBase):
f.close ()
os.remove (log_file)
- self.assertTrue(log_lines > 0, "Something was written to the log file.")
+ self.assertGreater(len(log_lines), 0, "Something was written to the log file.")
# Check that lldb truncates its log files
@no_debug_info_test
@@ -83,7 +85,7 @@ class LogTestCase(TestBase):
contents = f.read ()
# check that it got removed
- self.assertTrue(string.find(contents, "bacon") == -1)
+ self.assertEquals(contents.find("bacon"), -1)
# Check that lldb can append to a log file
@no_debug_info_test
@@ -104,4 +106,4 @@ class LogTestCase(TestBase):
contents = f.read ()
# check that it is still there
- self.assertTrue(string.find(contents, "bacon") == 0)
+ self.assertEquals(contents.find("bacon"), 0)
diff --git a/packages/Python/lldbsuite/test/macosx/add-dsym/TestAddDsymMidExecutionCommand.py b/packages/Python/lldbsuite/test/macosx/add-dsym/TestAddDsymMidExecutionCommand.py
index 497f695d7cc7..f4f6e313a1f4 100644
--- a/packages/Python/lldbsuite/test/macosx/add-dsym/TestAddDsymMidExecutionCommand.py
+++ b/packages/Python/lldbsuite/test/macosx/add-dsym/TestAddDsymMidExecutionCommand.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import os, time
import lldb
import sys
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class AddDsymMidExecutionCommandCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/macosx/debug-info/apple_types/TestAppleTypesIsProduced.py b/packages/Python/lldbsuite/test/macosx/debug-info/apple_types/TestAppleTypesIsProduced.py
index fad14db41003..afd933dc211f 100644
--- a/packages/Python/lldbsuite/test/macosx/debug-info/apple_types/TestAppleTypesIsProduced.py
+++ b/packages/Python/lldbsuite/test/macosx/debug-info/apple_types/TestAppleTypesIsProduced.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
from lldbsuite.test.lldbutil import symbol_type_to_str
class AppleTypesTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/macosx/indirect_symbol/TestIndirectSymbols.py b/packages/Python/lldbsuite/test/macosx/indirect_symbol/TestIndirectSymbols.py
index 4f98865ca5a2..f8b884003ad2 100644
--- a/packages/Python/lldbsuite/test/macosx/indirect_symbol/TestIndirectSymbols.py
+++ b/packages/Python/lldbsuite/test/macosx/indirect_symbol/TestIndirectSymbols.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestIndirectFunctions(TestBase):
diff --git a/packages/Python/lldbsuite/test/macosx/nslog/Makefile b/packages/Python/lldbsuite/test/macosx/nslog/Makefile
new file mode 100644
index 000000000000..de2b618b3d70
--- /dev/null
+++ b/packages/Python/lldbsuite/test/macosx/nslog/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+OBJC_SOURCES := main.m
+LD_EXTRAS = -framework Foundation
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/macosx/nslog/TestDarwinNSLogOutput.py b/packages/Python/lldbsuite/test/macosx/nslog/TestDarwinNSLogOutput.py
new file mode 100644
index 000000000000..15d25bb713a5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/macosx/nslog/TestDarwinNSLogOutput.py
@@ -0,0 +1,148 @@
+"""
+Test DarwinLog "source include debug-level" functionality provided by the
+StructuredDataDarwinLog plugin.
+
+These tests are currently only supported when running against Darwin
+targets.
+"""
+
+from __future__ import print_function
+
+import lldb
+import os
+import platform
+import re
+import sys
+
+from lldbsuite.test import decorators
+from lldbsuite.test import lldbtest
+from lldbsuite.test import lldbtest_config
+
+@decorators.skipUnlessDarwin
+class DarwinNSLogOutputTestCase(lldbtest.TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ mydir = lldbtest.TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ super(DarwinNSLogOutputTestCase, self).setUp()
+ self.child = None
+ self.child_prompt = '(lldb) '
+ self.strict_sources = False
+
+ # Source filename.
+ self.source = 'main.m'
+
+ # Output filename.
+ self.exe_name = 'a.out'
+ self.d = {'OBJC_SOURCES': self.source, 'EXE': self.exe_name}
+
+ # Locate breakpoint.
+ self.line = lldbtest.line_number(self.source, '// break here')
+
+ def tearDown(self):
+ # Shut down the process if it's still running.
+ if self.child:
+ self.runCmd('process kill')
+ self.expect_prompt()
+ self.runCmd('quit')
+
+ # Let parent clean up
+ super(DarwinNSLogOutputTestCase, self).tearDown()
+
+ def run_lldb_to_breakpoint(self, exe, source_file, line,
+ settings_commands=None):
+ # Set self.child_prompt, which is "(lldb) ".
+ prompt = self.child_prompt
+
+ # So that the child gets torn down after the test.
+ import pexpect
+ self.child = pexpect.spawn('%s %s %s' % (lldbtest_config.lldbExec,
+ self.lldbOption, exe))
+ child = self.child
+
+ # Turn on logging for what the child sends back.
+ if self.TraceOn():
+ child.logfile_read = sys.stdout
+
+ # Disable showing of source lines at our breakpoint.
+ # This is necessary for the logging tests, because the very
+ # text we want to match for output from the running inferior
+ # will show up in the source as well. We don't want the source
+ # output to erroneously make a match with our expected output.
+ self.runCmd("settings set stop-line-count-before 0")
+ self.expect_prompt()
+ self.runCmd("settings set stop-line-count-after 0")
+ self.expect_prompt()
+
+ # Run any test-specific settings commands now.
+ if settings_commands is not None:
+ for setting_command in settings_commands:
+ self.runCmd(setting_command)
+ self.expect_prompt()
+
+ # Set the breakpoint, and run to it.
+ child.sendline('breakpoint set -f %s -l %d' % (source_file, line))
+ child.expect_exact(prompt)
+ child.sendline('run')
+ child.expect_exact(prompt)
+
+ # Ensure we stopped at a breakpoint.
+ self.runCmd("thread list")
+ self.expect(re.compile(r"stop reason = breakpoint"))
+
+ def runCmd(self, cmd):
+ self.child.sendline(cmd)
+
+ def expect_prompt(self, exactly=True):
+ self.expect(self.child_prompt, exactly=exactly)
+
+ def expect(self, pattern, exactly=False, *args, **kwargs):
+ if exactly:
+ return self.child.expect_exact(pattern, *args, **kwargs)
+ return self.child.expect(pattern, *args, **kwargs)
+
+ def do_test(self, expect_regexes=None, settings_commands=None):
+ """ Run a test. """
+ self.build(dictionary=self.d)
+ self.setTearDownCleanup(dictionary=self.d)
+
+ exe = os.path.join(os.getcwd(), self.exe_name)
+ self.run_lldb_to_breakpoint(exe, self.source, self.line,
+ settings_commands=settings_commands)
+ self.expect_prompt()
+
+ # Now go.
+ self.runCmd("process continue")
+ self.expect(expect_regexes)
+
+ def test_nslog_output_is_displayed(self):
+ """Test that NSLog() output shows up in the command-line debugger."""
+ self.do_test(expect_regexes=[
+ re.compile(r"(This is a message from NSLog)"),
+ re.compile(r"Process \d+ exited with status")
+ ])
+ self.assertIsNotNone(self.child.match)
+ self.assertGreater(len(self.child.match.groups()), 0)
+ self.assertEqual("This is a message from NSLog", self.child.match.group(1))
+
+ def test_nslog_output_is_suppressed_with_env_var(self):
+ """Test that NSLog() output does not show up with the ignore env var."""
+ # This test will only work properly on macOS 10.12+. Skip it on earlier versions.
+ # This will require some tweaking on iOS.
+ match = re.match(r"^\d+\.(\d+)", platform.mac_ver()[0])
+ if match is None or int(match.group(1)) < 12:
+ self.skipTest("requires macOS 10.12 or higher")
+
+ self.do_test(
+ expect_regexes=[
+ re.compile(r"(This is a message from NSLog)"),
+ re.compile(r"Process \d+ exited with status")
+ ],
+ settings_commands=[
+ "settings set target.env-vars "
+ "\"IDE_DISABLED_OS_ACTIVITY_DT_MODE=1\""
+ ])
+ self.assertIsNotNone(self.child.match)
+ self.assertEqual(len(self.child.match.groups()), 0)
diff --git a/packages/Python/lldbsuite/test/macosx/nslog/main.m b/packages/Python/lldbsuite/test/macosx/nslog/main.m
new file mode 100644
index 000000000000..dab4089e9273
--- /dev/null
+++ b/packages/Python/lldbsuite/test/macosx/nslog/main.m
@@ -0,0 +1,18 @@
+//===-- main.m --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <Foundation/Foundation.h>
+
+int main(int argc, char** argv)
+{
+ printf("About to log\n"); // break here
+ NSLog(@"This is a message from NSLog");
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/macosx/order/TestOrderFile.py b/packages/Python/lldbsuite/test/macosx/order/TestOrderFile.py
index 6541169798ae..db2e071914c5 100644
--- a/packages/Python/lldbsuite/test/macosx/order/TestOrderFile.py
+++ b/packages/Python/lldbsuite/test/macosx/order/TestOrderFile.py
@@ -9,7 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class OrderFileTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/macosx/queues/TestQueues.py b/packages/Python/lldbsuite/test/macosx/queues/TestQueues.py
index 492d1d3bda3a..b403db2f275d 100644
--- a/packages/Python/lldbsuite/test/macosx/queues/TestQueues.py
+++ b/packages/Python/lldbsuite/test/macosx/queues/TestQueues.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import unittest2
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestQueues(TestBase):
diff --git a/packages/Python/lldbsuite/test/macosx/safe-to-func-call/TestSafeFuncCalls.py b/packages/Python/lldbsuite/test/macosx/safe-to-func-call/TestSafeFuncCalls.py
index 297223c3e84e..4e2dfb0eeb68 100644
--- a/packages/Python/lldbsuite/test/macosx/safe-to-func-call/TestSafeFuncCalls.py
+++ b/packages/Python/lldbsuite/test/macosx/safe-to-func-call/TestSafeFuncCalls.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestSafeFuncCalls(TestBase):
diff --git a/packages/Python/lldbsuite/test/macosx/universal/TestUniversal.py b/packages/Python/lldbsuite/test/macosx/universal/TestUniversal.py
index 4b722b0c1d8e..70a83ea90792 100644
--- a/packages/Python/lldbsuite/test/macosx/universal/TestUniversal.py
+++ b/packages/Python/lldbsuite/test/macosx/universal/TestUniversal.py
@@ -7,8 +7,9 @@ from __future__ import print_function
import unittest2
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class UniversalTestCase(TestBase):
@@ -18,7 +19,7 @@ class UniversalTestCase(TestBase):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
- self.line = line_number('main.c', '// Set break point at this line.')
+ self.line = line_number('main.c', '// Set break point at this line.')
@add_test_categories(['pyapi'])
@skipUnlessDarwin
@@ -105,3 +106,51 @@ class UniversalTestCase(TestBase):
substrs = ['Name: eax'])
self.runCmd("continue")
+
+
+ @skipUnlessDarwin
+ @unittest2.skipUnless(hasattr(os, "uname") and os.uname()[4] in ['i386', 'x86_64'],
+ "requires i386 or x86_64")
+ def test_process_attach_with_wrong_arch(self):
+ """Test that when we attach to a binary from the wrong fork of a universal binary, we fix up the ABI correctly."""
+ # Now keep the architecture at 32 bit, but switch the binary we launch to
+ # 64 bit, and make sure on attach we switch to the correct architecture.
+
+ # Invoke the default build rule.
+ self.build()
+
+ # Note that "testit" is a universal binary.
+ exe = os.path.join(os.getcwd(), "testit")
+
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTargetWithFileAndTargetTriple(exe, "i386-apple-macosx")
+ self.assertTrue(target, VALID_TARGET)
+ pointer_size = target.GetAddressByteSize()
+ self.assertTrue(pointer_size == 4, "Initially we were 32 bit.")
+
+ bkpt = target.BreakpointCreateBySourceRegex("sleep", lldb.SBFileSpec("main.c"))
+ self.assertTrue (bkpt.IsValid(), "Valid breakpoint")
+ self.assertTrue(bkpt.GetNumLocations() >= 1, "Our main breakpoint has locations.")
+
+ popen = self.spawnSubprocess(exe, ["keep_waiting"])
+ self.addTearDownHook(self.cleanupSubprocesses)
+
+ error = lldb.SBError()
+ empty_listener = lldb.SBListener()
+ process = target.AttachToProcessWithID(empty_listener, popen.pid, error)
+ self.assertTrue(error.Success(), "Attached to process.")
+
+ pointer_size = target.GetAddressByteSize()
+ self.assertTrue(pointer_size == 8, "We switched to 64 bit.")
+
+ # It may seem odd that I am checking the number of frames, but the bug that
+ # motivated this test was that we eventually fixed the architecture, but we
+ # left the ABI set to the original value. In that case, if you asked the
+ # process for its architecture, it would look right, but since the ABI was
+ # wrong, backtracing failed.
+
+ threads = lldbutil.continue_to_breakpoint(process, bkpt)
+ self.assertTrue(len(threads) == 1)
+ thread = threads[0]
+ self.assertTrue(thread.GetNumFrames() > 1, "We were able to backtrace.")
diff --git a/packages/Python/lldbsuite/test/macosx/universal/main.c b/packages/Python/lldbsuite/test/macosx/universal/main.c
index 9351c77f7146..3edab51b1f6a 100644
--- a/packages/Python/lldbsuite/test/macosx/universal/main.c
+++ b/packages/Python/lldbsuite/test/macosx/universal/main.c
@@ -1,7 +1,21 @@
#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+void
+call_me()
+{
+ sleep(1);
+}
+
int
main (int argc, char **argv)
{
printf ("Hello there!\n"); // Set break point at this line.
+ if (argc == 2 && strcmp(argv[1], "keep_waiting") == 0)
+ while (1)
+ {
+ call_me();
+ }
return 0;
}
diff --git a/packages/Python/lldbsuite/test/make/Makefile.rules b/packages/Python/lldbsuite/test/make/Makefile.rules
index e753317e9398..c37ef745e8b4 100644
--- a/packages/Python/lldbsuite/test/make/Makefile.rules
+++ b/packages/Python/lldbsuite/test/make/Makefile.rules
@@ -168,6 +168,10 @@ else
override ARCH :=
override ARCHFLAG :=
endif
+ ifeq "$(ARCH)" "s390x"
+ override ARCH :=
+ override ARCHFLAG :=
+ endif
ifeq "$(findstring mips,$(ARCH))" "mips"
override ARCHFLAG := -
endif
@@ -179,9 +183,11 @@ endif
LIMIT_DEBUG_INFO_FLAGS =
NO_LIMIT_DEBUG_INFO_FLAGS =
+MODULE_DEBUG_INFO_FLAGS =
ifneq (,$(findstring clang,$(CC)))
LIMIT_DEBUG_INFO_FLAGS += -flimit-debug-info
NO_LIMIT_DEBUG_INFO_FLAGS += -fno-limit-debug-info
+ MODULE_DEBUG_INFO_FLAGS += -gmodules
endif
DEBUG_INFO_FLAG ?= -g
@@ -206,8 +212,13 @@ ifeq "$(MAKE_DWO)" "YES"
CFLAGS += -gsplit-dwarf
endif
+ifeq "$(MAKE_GMODULES)" "YES"
+ CFLAGS += -fmodules -gmodules
+endif
+
CXXFLAGS += -std=c++11
-CXXFLAGS += $(CFLAGS)
+# FIXME: C++ modules aren't supported on all platforms.
+CXXFLAGS += $(subst -fmodules,, $(CFLAGS))
LD = $(CC)
LDFLAGS ?= $(CFLAGS)
LDFLAGS += $(LD_EXTRAS)
@@ -300,7 +311,7 @@ endif
ifeq (1,$(USE_LIBSTDCPP))
# Clang requires an extra flag: -stdlib=libstdc++
ifneq (,$(findstring clang,$(CC)))
- CXXFLAGS += -stdlib=libstdc++
+ CXXFLAGS += -stdlib=libstdc++ -DLLDB_USING_LIBSTDCPP
LDFLAGS += -stdlib=libstdc++
endif
endif
@@ -340,6 +351,14 @@ ifneq "$(strip $(DYLIB_CXX_SOURCES))" ""
endif
#----------------------------------------------------------------------
+# Check if we have a precompiled header
+#----------------------------------------------------------------------
+ifneq "$(strip $(PCH_CXX_SOURCE))" ""
+ PCH_OUTPUT = $(PCH_CXX_SOURCE:.h=.h.pch)
+ PCHFLAGS = -include $(PCH_CXX_SOURCE)
+endif
+
+#----------------------------------------------------------------------
# Check if we have any C source files
#----------------------------------------------------------------------
ifneq "$(strip $(C_SOURCES))" ""
@@ -498,6 +517,17 @@ endif
endif
#----------------------------------------------------------------------
+# Make the precompiled header and compile C++ sources against it
+#----------------------------------------------------------------------
+
+#ifneq "$(PCH_OUTPUT)" ""
+$(PCH_OUTPUT) : $(PCH_CXX_SOURCE)
+ $(CXX) $(CXXFLAGS) -x c++-header -o $(PCH_OUTPUT) $(PCH_CXX_SOURCE)
+%.o : %.cpp $(PCH_OUTPUT)
+ $(CXX) $(PCHFLAGS) $(CXXFLAGS) -c -o $@ $<
+#endif
+
+#----------------------------------------------------------------------
# Automatic variables based on items already entered. Below we create
# an object's lists from the list of sources by replacing all entries
# that end with .c with .o, and we also create a list of prerequisite
@@ -570,6 +600,9 @@ ifneq "$(DYLIB_NAME)" ""
$(RM) -r $(DYLIB_FILENAME).dSYM
$(RM) $(DYLIB_OBJECTS) $(DYLIB_PREREQS) $(DYLIB_PREREQS:.d=.d.tmp) $(DYLIB_DWOS) $(DYLIB_FILENAME) $(DYLIB_FILENAME).debug
endif
+ifneq "$(PCH_OUTPUT)" ""
+ $(RM) $(PCH_OUTPUT)
+endif
ifneq "$(DSYM)" ""
$(RM) -r "$(DSYM)"
endif
diff --git a/packages/Python/lldbsuite/test/make/test_common.h b/packages/Python/lldbsuite/test/make/test_common.h
index a1ed364574e3..b0151afb892e 100644
--- a/packages/Python/lldbsuite/test/make/test_common.h
+++ b/packages/Python/lldbsuite/test/make/test_common.h
@@ -26,7 +26,14 @@
#if defined(__linux__)
#include <sys/prctl.h>
-#if defined(PR_SET_PTRACER) && defined(PR_SET_PTRACER_ANY)
+// Android API <= 16 does not have these defined.
+#ifndef PR_SET_PTRACER
+#define PR_SET_PTRACER 0x59616d61
+#endif
+#ifndef PR_SET_PTRACER_ANY
+#define PR_SET_PTRACER_ANY ((unsigned long)-1)
+#endif
+
// For now we execute on best effort basis. If this fails for some reason, so be it.
#define lldb_enable_attach() \
do \
@@ -35,10 +42,39 @@
(void)prctl_result; \
} while (0)
-#endif
-
#else // not linux
#define lldb_enable_attach()
#endif
+
+#if defined(__APPLE__) && defined(LLDB_USING_LIBSTDCPP)
+
+// on Darwin, libstdc++ is missing <atomic>, so this would cause any test to fail building
+// since this header file is being included in every C-family test case, we need to not include it
+// on Darwin, most tests use libc++ by default, so this will only affect tests that explicitly require libstdc++
+
+#else
+#ifdef __cplusplus
+#include <atomic>
+
+// Note that although hogging the CPU while waiting for a variable to change
+// would be terrible in production code, it's great for testing since it
+// avoids a lot of messy context switching to get multiple threads synchronized.
+
+typedef std::atomic<int> pseudo_barrier_t;
+#define pseudo_barrier_wait(barrier) \
+ do \
+ { \
+ --(barrier); \
+ while ((barrier).load() > 0) \
+ ; \
+ } while (0)
+
+#define pseudo_barrier_init(barrier, count) \
+ do \
+ { \
+ (barrier) = (count); \
+ } while (0)
+#endif // __cplusplus
+#endif // defined(__APPLE__) && defined(LLDB_USING_LIBSTDCPP)
diff --git a/packages/Python/lldbsuite/test/plugins/builder_base.py b/packages/Python/lldbsuite/test/plugins/builder_base.py
index c4e3dff5301c..a467a458d5de 100644
--- a/packages/Python/lldbsuite/test/plugins/builder_base.py
+++ b/packages/Python/lldbsuite/test/plugins/builder_base.py
@@ -12,9 +12,16 @@ Same idea holds for LLDB_ARCH environment variable, which maps to the ARCH make
variable.
"""
-import os, sys
+# System imports
+import os
import platform
+import subprocess
+import sys
+
+# Our imports
import lldbsuite.test.lldbtest as lldbtest
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test_event import build_exception
def getArchitecture():
"""Returns the architecture in effect the test suite is running with."""
@@ -22,7 +29,9 @@ def getArchitecture():
def getCompiler():
"""Returns the compiler in effect the test suite is running with."""
- return os.environ["CC"] if "CC" in os.environ else "clang"
+ compiler = os.environ.get("CC", "clang")
+ compiler = lldbutil.which(compiler)
+ return os.path.realpath(compiler)
def getArchFlag():
"""Returns the flag required to specify the arch"""
@@ -90,6 +99,16 @@ def getCmdLine(d):
return cmdline
+def runBuildCommands(commands, sender):
+ try:
+ lldbtest.system(commands, sender=sender)
+ except subprocess.CalledProcessError as called_process_error:
+ # Convert to a build-specific error.
+ # We don't do that in lldbtest.system() since that
+ # is more general purpose.
+ raise build_exception.BuildError(called_process_error)
+
+
def buildDefault(sender=None, architecture=None, compiler=None, dictionary=None, clean=True):
"""Build the binaries the default way."""
commands = []
@@ -97,7 +116,7 @@ def buildDefault(sender=None, architecture=None, compiler=None, dictionary=None,
commands.append([getMake(), "clean", getCmdLine(dictionary)])
commands.append([getMake(), getArchSpec(architecture), getCCSpec(compiler), getCmdLine(dictionary)])
- lldbtest.system(commands, sender=sender)
+ runBuildCommands(commands, sender=sender)
# True signifies that we can handle building default.
return True
@@ -109,7 +128,7 @@ def buildDwarf(sender=None, architecture=None, compiler=None, dictionary=None, c
commands.append([getMake(), "clean", getCmdLine(dictionary)])
commands.append([getMake(), "MAKE_DSYM=NO", getArchSpec(architecture), getCCSpec(compiler), getCmdLine(dictionary)])
- lldbtest.system(commands, sender=sender)
+ runBuildCommands(commands, sender=sender)
# True signifies that we can handle building dwarf.
return True
@@ -120,10 +139,21 @@ def buildDwo(sender=None, architecture=None, compiler=None, dictionary=None, cle
commands.append([getMake(), "clean", getCmdLine(dictionary)])
commands.append([getMake(), "MAKE_DSYM=NO", "MAKE_DWO=YES", getArchSpec(architecture), getCCSpec(compiler), getCmdLine(dictionary)])
- lldbtest.system(commands, sender=sender)
+ runBuildCommands(commands, sender=sender)
# True signifies that we can handle building dwo.
return True
+def buildGModules(sender=None, architecture=None, compiler=None, dictionary=None, clean=True):
+ """Build the binaries with dwarf debug info."""
+ commands = []
+ if clean:
+ commands.append([getMake(), "clean", getCmdLine(dictionary)])
+ commands.append([getMake(), "MAKE_DSYM=NO", "MAKE_GMODULES=YES", getArchSpec(architecture), getCCSpec(compiler), getCmdLine(dictionary)])
+
+ lldbtest.system(commands, sender=sender)
+ # True signifies that we can handle building with gmodules.
+ return True
+
def cleanup(sender=None, dictionary=None):
"""Perform a platform-specific cleanup after the test."""
#import traceback
@@ -132,6 +162,6 @@ def cleanup(sender=None, dictionary=None):
if os.path.isfile("Makefile"):
commands.append([getMake(), "clean", getCmdLine(dictionary)])
- lldbtest.system(commands, sender=sender)
+ runBuildCommands(commands, sender=sender)
# True signifies that we can handle cleanup.
return True
diff --git a/packages/Python/lldbsuite/test/plugins/builder_darwin.py b/packages/Python/lldbsuite/test/plugins/builder_darwin.py
index dd07206e323b..8a907ccec2da 100644
--- a/packages/Python/lldbsuite/test/plugins/builder_darwin.py
+++ b/packages/Python/lldbsuite/test/plugins/builder_darwin.py
@@ -5,8 +5,6 @@ import lldbsuite.test.lldbtest as lldbtest
from builder_base import *
-#print("Hello, darwin plugin!")
-
def buildDsym(sender=None, architecture=None, compiler=None, dictionary=None, clean=True):
"""Build the binaries with dsym debug info."""
commands = []
@@ -15,7 +13,7 @@ def buildDsym(sender=None, architecture=None, compiler=None, dictionary=None, cl
commands.append(["make", "clean", getCmdLine(dictionary)])
commands.append(["make", "MAKE_DSYM=YES", getArchSpec(architecture), getCCSpec(compiler), getCmdLine(dictionary)])
- lldbtest.system(commands, sender=sender)
+ runBuildCommands(commands, sender=sender)
# True signifies that we can handle building dsym.
return True
diff --git a/packages/Python/lldbsuite/test/plugins/builder_linux2.py b/packages/Python/lldbsuite/test/plugins/builder_linux.py
index e56be429823e..e56be429823e 100644
--- a/packages/Python/lldbsuite/test/plugins/builder_linux2.py
+++ b/packages/Python/lldbsuite/test/plugins/builder_linux.py
diff --git a/packages/Python/lldbsuite/test/python_api/breakpoint/TestBreakpointAPI.py b/packages/Python/lldbsuite/test/python_api/breakpoint/TestBreakpointAPI.py
index 1f4fa20b8304..a3dd91fe8802 100644
--- a/packages/Python/lldbsuite/test/python_api/breakpoint/TestBreakpointAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/breakpoint/TestBreakpointAPI.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class BreakpointAPITestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/class_members/TestSBTypeClassMembers.py b/packages/Python/lldbsuite/test/python_api/class_members/TestSBTypeClassMembers.py
index e1d5520bcc3d..3d9309e26cec 100644
--- a/packages/Python/lldbsuite/test/python_api/class_members/TestSBTypeClassMembers.py
+++ b/packages/Python/lldbsuite/test/python_api/class_members/TestSBTypeClassMembers.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class SBTypeMemberFunctionsTest(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/debugger/TestDebuggerAPI.py b/packages/Python/lldbsuite/test/python_api/debugger/TestDebuggerAPI.py
index 98feda859ae9..d8ac342f4754 100644
--- a/packages/Python/lldbsuite/test/python_api/debugger/TestDebuggerAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/debugger/TestDebuggerAPI.py
@@ -4,7 +4,10 @@ Test Debugger APIs.
import os
import lldb
+
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class DebuggerAPITestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py b/packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py
index aa3a6141326a..3e2ff2ffa9dd 100644
--- a/packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py
+++ b/packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py
@@ -18,8 +18,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class APIDefaultConstructorTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassembleRawData.py b/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassembleRawData.py
index 31ba44928794..311791cca014 100644
--- a/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassembleRawData.py
+++ b/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassembleRawData.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class DisassembleRawDataTestCase(TestBase):
@@ -18,6 +19,7 @@ class DisassembleRawDataTestCase(TestBase):
@add_test_categories(['pyapi'])
@no_debug_info_test
+ @skipIfRemote
def test_disassemble_raw_data(self):
"""Test disassembling raw bytes with the API."""
# Create a target from the debugger.
diff --git a/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassemble_VST1_64.py b/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassemble_VST1_64.py
index e24b2ee5613a..f991ab329a89 100644
--- a/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassemble_VST1_64.py
+++ b/packages/Python/lldbsuite/test/python_api/disassemble-raw-data/TestDisassemble_VST1_64.py
@@ -9,14 +9,15 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class Disassemble_VST1_64(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipIf(True) # llvm.org/pr24575: all tests get ERRORs in dotest.py after this
+ @skipTestIfFn(lambda : True, "llvm.org/pr24575: all tests get ERRORs in dotest.py after this")
@add_test_categories(['pyapi'])
@no_debug_info_test
def test_disassemble_invalid_vst_1_64_raw_data(self):
diff --git a/packages/Python/lldbsuite/test/python_api/event/TestEvents.py b/packages/Python/lldbsuite/test/python_api/event/TestEvents.py
index 51c924b2aff1..1c23f50e9d4d 100644
--- a/packages/Python/lldbsuite/test/python_api/event/TestEvents.py
+++ b/packages/Python/lldbsuite/test/python_api/event/TestEvents.py
@@ -9,10 +9,10 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
-@skipIfDarwin # llvm.org/pr25924, sometimes generating SIGSEGV
@skipIfLinux # llvm.org/pr25924, sometimes generating SIGSEGV
class EventAPITestCase(TestBase):
@@ -25,7 +25,7 @@ class EventAPITestCase(TestBase):
self.line = line_number('main.c', '// Find the line number of function "c" here.')
@add_test_categories(['pyapi'])
- @expectedFailureLinux("llvm.org/pr23730") # Flaky, fails ~1/10 cases
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr23730 Flaky, fails ~1/10 cases")
def test_listen_for_and_print_event(self):
"""Exercise SBEvent API."""
self.build()
@@ -85,6 +85,7 @@ class EventAPITestCase(TestBase):
if traceOn:
print("timeout occurred waiting for event...")
count = count + 1
+ listener.Clear()
return
# Let's start the listening thread to retrieve the events.
@@ -102,8 +103,11 @@ class EventAPITestCase(TestBase):
# Wait until the 'MyListeningThread' terminates.
my_thread.join()
+ # Shouldn't we be testing against some kind of expectation here?
+
@add_test_categories(['pyapi'])
@expectedFlakeyLinux("llvm.org/pr23730") # Flaky, fails ~1/100 cases
+ @expectedFlakeyOS(oslist=["windows"])
def test_wait_for_event(self):
"""Exercise SBListener.WaitForEvent() API."""
self.build()
@@ -154,10 +158,11 @@ class EventAPITestCase(TestBase):
#print("Got a valid event:", event)
#print("Event data flavor:", event.GetDataFlavor())
#print("Event type:", lldbutil.state_type_to_str(event.GetType()))
+ listener.Clear()
return
count = count + 1
print("Timeout: listener.WaitForEvent")
-
+ listener.Clear()
return
# Use Python API to kill the process. The listening thread should be
@@ -176,8 +181,8 @@ class EventAPITestCase(TestBase):
@skipIfFreeBSD # llvm.org/pr21325
@add_test_categories(['pyapi'])
- @expectedFailureLinux("llvm.org/pr23617") # Flaky, fails ~1/10 cases
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr23617 Flaky, fails ~1/10 cases")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_add_listener_to_broadcaster(self):
"""Exercise some SBBroadcaster APIs."""
self.build()
@@ -265,7 +270,7 @@ class EventAPITestCase(TestBase):
count = count + 1
if count > 6:
break
-
+ listener.Clear()
return
# Use Python API to continue the process. The listening thread should be
diff --git a/packages/Python/lldbsuite/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py b/packages/Python/lldbsuite/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py
index 80305e303d03..49bc148dd579 100644
--- a/packages/Python/lldbsuite/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py
+++ b/packages/Python/lldbsuite/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py
@@ -1,4 +1,4 @@
-import lldbsuite.test.lldbinline as lldbinline
-import lldbsuite.test.lldbtest as lldbtest
+from lldbsuite.test import decorators
+from lldbsuite.test import lldbinline
-lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.skipIfFreeBSD,lldbtest.skipIfLinux,lldbtest.skipIfWindows])
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.skipIfFreeBSD,decorators.skipIfLinux,decorators.skipIfWindows])
diff --git a/packages/Python/lldbsuite/test/python_api/findvalue_duplist/TestSBFrameFindValue.py b/packages/Python/lldbsuite/test/python_api/findvalue_duplist/TestSBFrameFindValue.py
index 96d4f51fd097..9c1fd1e7bef7 100644
--- a/packages/Python/lldbsuite/test/python_api/findvalue_duplist/TestSBFrameFindValue.py
+++ b/packages/Python/lldbsuite/test/python_api/findvalue_duplist/TestSBFrameFindValue.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, sys, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SBFrameFindValueTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/formatters/TestFormattersSBAPI.py b/packages/Python/lldbsuite/test/python_api/formatters/TestFormattersSBAPI.py
index de7f15f76faf..babae237b8ce 100644
--- a/packages/Python/lldbsuite/test/python_api/formatters/TestFormattersSBAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/formatters/TestFormattersSBAPI.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, sys, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SBFormattersAPITestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/frame/TestFrames.py b/packages/Python/lldbsuite/test/python_api/frame/TestFrames.py
index 7cc976fc6aa3..0b1e12b08fcb 100644
--- a/packages/Python/lldbsuite/test/python_api/frame/TestFrames.py
+++ b/packages/Python/lldbsuite/test/python_api/frame/TestFrames.py
@@ -10,15 +10,16 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class FrameAPITestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@add_test_categories(['pyapi'])
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_get_arg_vals_for_call_stack(self):
"""Exercise SBFrame.GetVariables() API to get argument vals."""
self.build()
@@ -49,7 +50,8 @@ class FrameAPITestCase(TestBase):
from six import StringIO as SixStringIO
session = SixStringIO()
while process.GetState() == lldb.eStateStopped:
- thread = process.GetThreadAtIndex(0)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
# Inspect at most 3 frames.
numFrames = min(3, thread.GetNumFrames())
for i in range(numFrames):
@@ -134,7 +136,8 @@ class FrameAPITestCase(TestBase):
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
- thread = process.GetThreadAtIndex(0)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
frame = thread.GetFrameAtIndex(0)
if self.TraceOn():
print("frame:", frame)
@@ -173,8 +176,8 @@ class FrameAPITestCase(TestBase):
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
- thread = process.GetThreadAtIndex(0)
- self.assertTrue(thread)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
frameEntered = thread.GetFrameAtIndex(0)
if self.TraceOn():
diff --git a/packages/Python/lldbsuite/test/python_api/frame/get-variables/Makefile b/packages/Python/lldbsuite/test/python_api/frame/get-variables/Makefile
new file mode 100644
index 000000000000..b09a579159d4
--- /dev/null
+++ b/packages/Python/lldbsuite/test/python_api/frame/get-variables/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/python_api/frame/get-variables/TestGetVariables.py b/packages/Python/lldbsuite/test/python_api/frame/get-variables/TestGetVariables.py
new file mode 100644
index 000000000000..914c3d25fd5d
--- /dev/null
+++ b/packages/Python/lldbsuite/test/python_api/frame/get-variables/TestGetVariables.py
@@ -0,0 +1,190 @@
+"""
+Test that SBFrame::GetVariables() calls work correctly.
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbplatform
+from lldbsuite.test import lldbutil
+
+def get_names_from_value_list(value_list):
+ names = list()
+ for value in value_list:
+ names.append(value.GetName())
+ return names
+
+class TestGetVariables(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ self.source = 'main.c'
+
+ def verify_variable_names(self, description, value_list, names):
+ copy_names = list(names)
+ actual_names = get_names_from_value_list(value_list)
+ for name in actual_names:
+ if name in copy_names:
+ copy_names.remove(name)
+ else:
+ self.assertTrue(False, "didn't find '%s' in %s" % (name, copy_names))
+ self.assertEqual(len(copy_names), 0, "%s: we didn't find variables: %s in value list (%s)" % (description, copy_names, actual_names))
+
+ def test (self):
+ self.build ()
+
+ # Set debugger into synchronous mode
+ self.dbg.SetAsync(False)
+
+ # Create a target by the debugger.
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ line1 = line_number(self.source, '// breakpoint 1')
+ line2 = line_number(self.source, '// breakpoint 2')
+ line3 = line_number(self.source, '// breakpoint 3')
+
+ breakpoint1 = target.BreakpointCreateByLocation (self.source, line1);
+ breakpoint2 = target.BreakpointCreateByLocation (self.source, line2);
+ breakpoint3 = target.BreakpointCreateByLocation (self.source, line3);
+
+ self.assertTrue(breakpoint1.GetNumLocations() >= 1, PROCESS_IS_VALID)
+ self.assertTrue(breakpoint2.GetNumLocations() >= 1, PROCESS_IS_VALID)
+ self.assertTrue(breakpoint3.GetNumLocations() >= 1, PROCESS_IS_VALID)
+
+ # Register our shared libraries for remote targets so they get automatically uploaded
+ arguments = None
+ environment = None
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (arguments, environment, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint1)
+ self.assertEqual(len(threads), 1, "There should be a thread stopped at breakpoint 1")
+
+ thread = threads[0]
+ self.assertTrue(thread.IsValid(), "Thread must be valid")
+ frame = thread.GetFrameAtIndex(0)
+ self.assertTrue(frame.IsValid(), "Frame must be valid")
+
+ arg_names = ['argc', 'argv']
+ local_names = ['i', 'j', 'k']
+ static_names = ['static_var', 'g_global_var', 'g_static_var']
+ breakpoint1_locals = ['i']
+ breakpoint1_statics = ['static_var']
+ num_args = len(arg_names)
+ num_locals = len(local_names)
+ num_statics = len(static_names)
+ args_yes = True
+ args_no = False
+ locals_yes = True
+ locals_no = False
+ statics_yes = True
+ statics_no = False
+ in_scopy_only = True
+ ignore_scope = False
+
+ # Verify if we ask for only arguments that we got what we expect
+ vars = frame.GetVariables(args_yes, locals_no, statics_no, ignore_scope)
+ self.assertEqual(vars.GetSize(), num_args, "There should be %i arguments, but we are reporting %i" % (num_args, vars.GetSize()))
+ self.verify_variable_names("check names of arguments", vars, arg_names)
+ self.assertEqual(len(arg_names), num_args, "make sure verify_variable_names() didn't mutate list")
+
+ # Verify if we ask for only locals that we got what we expect
+ vars = frame.GetVariables(args_no, locals_yes, statics_no, ignore_scope)
+ self.assertEqual(vars.GetSize(), num_locals, "There should be %i local variables, but we are reporting %i" % (num_locals, vars.GetSize()))
+ self.verify_variable_names("check names of locals", vars, local_names)
+
+ # Verify if we ask for only statics that we got what we expect
+ vars = frame.GetVariables(args_no, locals_no, statics_yes, ignore_scope)
+ print('statics: ', str(vars))
+ self.assertEqual(vars.GetSize(), num_statics, "There should be %i static variables, but we are reporting %i" % (num_statics, vars.GetSize()))
+ self.verify_variable_names("check names of statics", vars, static_names)
+
+ # Verify if we ask for arguments and locals that we got what we expect
+ vars = frame.GetVariables(args_yes, locals_yes, statics_no, ignore_scope)
+ desc = 'arguments + locals'
+ names = arg_names + local_names
+ count = len(names)
+ self.assertEqual(vars.GetSize(), count, "There should be %i %s (%s) but we are reporting %i (%s)" % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)))
+ self.verify_variable_names("check names of %s" % (desc), vars, names)
+
+ # Verify if we ask for arguments and statics that we got what we expect
+ vars = frame.GetVariables(args_yes, locals_no, statics_yes, ignore_scope)
+ desc = 'arguments + statics'
+ names = arg_names + static_names
+ count = len(names)
+ self.assertEqual(vars.GetSize(), count, "There should be %i %s (%s) but we are reporting %i (%s)" % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)))
+ self.verify_variable_names("check names of %s" % (desc), vars, names)
+
+ # Verify if we ask for locals and statics that we got what we expect
+ vars = frame.GetVariables(args_no, locals_yes, statics_yes, ignore_scope)
+ desc = 'locals + statics'
+ names = local_names + static_names
+ count = len(names)
+ self.assertEqual(vars.GetSize(), count, "There should be %i %s (%s) but we are reporting %i (%s)" % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)))
+ self.verify_variable_names("check names of %s" % (desc), vars, names)
+
+ # Verify if we ask for arguments, locals and statics that we got what we expect
+ vars = frame.GetVariables(args_yes, locals_yes, statics_yes, ignore_scope)
+ desc = 'arguments + locals + statics'
+ names = arg_names + local_names + static_names
+ count = len(names)
+ self.assertEqual(vars.GetSize(), count, "There should be %i %s (%s) but we are reporting %i (%s)" % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)))
+ self.verify_variable_names("check names of %s" % (desc), vars, names)
+
+ # Verify if we ask for in scope locals that we got what we expect
+ vars = frame.GetVariables(args_no, locals_yes, statics_no, in_scopy_only)
+ desc = 'in scope locals at breakpoint 1'
+ names = ['i']
+ count = len(names)
+ self.assertEqual(vars.GetSize(), count, "There should be %i %s (%s) but we are reporting %i (%s)" % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)))
+ self.verify_variable_names("check names of %s" % (desc), vars, names)
+
+ # Continue to breakpoint 2
+ process.Continue()
+
+ threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint2)
+ self.assertEqual(len(threads), 1, "There should be a thread stopped at breakpoint 2")
+
+ thread = threads[0]
+ self.assertTrue(thread.IsValid(), "Thread must be valid")
+ frame = thread.GetFrameAtIndex(0)
+ self.assertTrue(frame.IsValid(), "Frame must be valid")
+
+ # Verify if we ask for in scope locals that we got what we expect
+ vars = frame.GetVariables(args_no, locals_yes, statics_no, in_scopy_only)
+ desc = 'in scope locals at breakpoint 2'
+ names = ['i', 'j']
+ count = len(names)
+ self.assertEqual(vars.GetSize(), count, "There should be %i %s (%s) but we are reporting %i (%s)" % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)))
+ self.verify_variable_names("check names of %s" % (desc), vars, names)
+
+ # Continue to breakpoint 3
+ process.Continue()
+
+ threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint3)
+ self.assertEqual(len(threads), 1, "There should be a thread stopped at breakpoint 3")
+
+ thread = threads[0]
+ self.assertTrue(thread.IsValid(), "Thread must be valid")
+ frame = thread.GetFrameAtIndex(0)
+ self.assertTrue(frame.IsValid(), "Frame must be valid")
+
+ # Verify if we ask for in scope locals that we got what we expect
+ vars = frame.GetVariables(args_no, locals_yes, statics_no, in_scopy_only)
+ desc = 'in scope locals at breakpoint 3'
+ names = ['i', 'j', 'k']
+ count = len(names)
+ self.assertEqual(vars.GetSize(), count, "There should be %i %s (%s) but we are reporting %i (%s)" % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)))
+ self.verify_variable_names("check names of %s" % (desc), vars, names)
diff --git a/packages/Python/lldbsuite/test/python_api/frame/get-variables/main.c b/packages/Python/lldbsuite/test/python_api/frame/get-variables/main.c
new file mode 100644
index 000000000000..7fecfc0293c3
--- /dev/null
+++ b/packages/Python/lldbsuite/test/python_api/frame/get-variables/main.c
@@ -0,0 +1,29 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+int g_global_var = 123;
+static int g_static_var = 123;
+
+int main (int argc, char const *argv[])
+{
+ static int static_var = 123;
+ g_static_var = 123; // clang bug. Need to touch this variable, otherwise it disappears.
+ int i = 0; // breakpoint 1
+ for (i=0; i<1; ++i)
+ {
+ int j = i*2;
+ printf("i = %i, j = %i\n", i, j); // breakpoint 2
+ {
+ int k = i*j*3;
+ printf("i = %i, j = %i\n", i, j); // breakpoint 3
+ }
+ }
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/python_api/frame/inlines/TestInlinedFrame.py b/packages/Python/lldbsuite/test/python_api/frame/inlines/TestInlinedFrame.py
index d4cf8fe30ccd..ee6c33f54314 100644
--- a/packages/Python/lldbsuite/test/python_api/frame/inlines/TestInlinedFrame.py
+++ b/packages/Python/lldbsuite/test/python_api/frame/inlines/TestInlinedFrame.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class InlinedFrameAPITestCase(TestBase):
@@ -60,7 +61,10 @@ class InlinedFrameAPITestCase(TestBase):
#
# outer_inline (argc);
#
- frame0 = process.GetThreadAtIndex(0).GetFrameAtIndex(0)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
+
+ frame0 = thread.GetFrameAtIndex(0)
if frame0.IsInlined():
filename = frame0.GetLineEntry().GetFileSpec().GetFilename()
self.assertTrue(filename == self.source)
diff --git a/packages/Python/lldbsuite/test/python_api/function_symbol/TestDisasmAPI.py b/packages/Python/lldbsuite/test/python_api/function_symbol/TestDisasmAPI.py
index c9876a8c8954..9a763b89c27f 100644
--- a/packages/Python/lldbsuite/test/python_api/function_symbol/TestDisasmAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/function_symbol/TestDisasmAPI.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class DisasmAPITestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/function_symbol/TestSymbolAPI.py b/packages/Python/lldbsuite/test/python_api/function_symbol/TestSymbolAPI.py
index 187ba69def0e..35d73e494270 100644
--- a/packages/Python/lldbsuite/test/python_api/function_symbol/TestSymbolAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/function_symbol/TestSymbolAPI.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class SymbolAPITestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/hello_world/TestHelloWorld.py b/packages/Python/lldbsuite/test/python_api/hello_world/TestHelloWorld.py
index 47c3ba146cef..a8beaa903293 100644
--- a/packages/Python/lldbsuite/test/python_api/hello_world/TestHelloWorld.py
+++ b/packages/Python/lldbsuite/test/python_api/hello_world/TestHelloWorld.py
@@ -4,10 +4,14 @@ from __future__ import print_function
-import os, sys, time
-import lldb
+import os
+import sys
import time
+
+import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class HelloWorldTestCase(TestBase):
@@ -64,18 +68,14 @@ class HelloWorldTestCase(TestBase):
process = target.GetProcess()
self.assertTrue(process, PROCESS_IS_VALID)
- thread = process.GetThreadAtIndex(0)
- if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
- from lldbsuite.test.lldbutil import stop_reason_to_str
- self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
- stop_reason_to_str(thread.GetStopReason()))
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
# The breakpoint should have a hit count of 1.
- self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE)
+ self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE)
@add_test_categories(['pyapi'])
- @expectedFailureWindows("llvm.org/pr24600")
- @expectedFailurei386("llvm.org/pr25338")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24600")
@skipIfiOSSimulator
def test_with_attach_to_process_with_id_api(self):
"""Create target, spawn a process, and attach to it with process id."""
@@ -104,8 +104,7 @@ class HelloWorldTestCase(TestBase):
'(int)argc=3'])
@add_test_categories(['pyapi'])
- @expectedFailureWindows("llvm.org/pr24600")
- @expectedFailurei386("llvm.org/pr25338")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24600")
@skipIfiOSSimulator
def test_with_attach_to_process_with_name_api(self):
"""Create target, spawn a process, and attach to it with process name."""
diff --git a/packages/Python/lldbsuite/test/python_api/interpreter/TestCommandInterpreterAPI.py b/packages/Python/lldbsuite/test/python_api/interpreter/TestCommandInterpreterAPI.py
index faff11818da7..d39984adb732 100644
--- a/packages/Python/lldbsuite/test/python_api/interpreter/TestCommandInterpreterAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/interpreter/TestCommandInterpreterAPI.py
@@ -6,7 +6,9 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class CommandInterpreterAPICase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/lldbutil/frame/TestFrameUtils.py b/packages/Python/lldbsuite/test/python_api/lldbutil/frame/TestFrameUtils.py
index 2cde05af0c39..09a5bc126571 100644
--- a/packages/Python/lldbsuite/test/python_api/lldbutil/frame/TestFrameUtils.py
+++ b/packages/Python/lldbsuite/test/python_api/lldbutil/frame/TestFrameUtils.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class FrameUtilsTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestLLDBIterator.py b/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestLLDBIterator.py
index 07177c1fae4a..90f879d37610 100644
--- a/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestLLDBIterator.py
+++ b/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestLLDBIterator.py
@@ -9,7 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class LLDBIteratorTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py b/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py
index 1645ae1f2a5d..84ef44d2dd73 100644
--- a/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py
+++ b/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py
@@ -9,7 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class RegistersIteratorTestCase(TestBase):
@@ -22,7 +24,7 @@ class RegistersIteratorTestCase(TestBase):
self.line1 = line_number('main.cpp', '// Set break point at this line.')
@add_test_categories(['pyapi'])
- @expectedFailureWindows # Test crashes
+ @expectedFailureAll(oslist=["windows"])
def test_iter_registers(self):
"""Test iterator works correctly for lldbutil.iter_registers()."""
self.build()
diff --git a/packages/Python/lldbsuite/test/python_api/lldbutil/process/TestPrintStackTraces.py b/packages/Python/lldbsuite/test/python_api/lldbutil/process/TestPrintStackTraces.py
index 97bfa3956f6c..fafd05fd92c8 100644
--- a/packages/Python/lldbsuite/test/python_api/lldbutil/process/TestPrintStackTraces.py
+++ b/packages/Python/lldbsuite/test/python_api/lldbutil/process/TestPrintStackTraces.py
@@ -9,7 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ThreadsStackTracesTestCase(TestBase):
@@ -26,7 +28,9 @@ class ThreadsStackTracesTestCase(TestBase):
#The __thread_start function in libc doesn't contain any epilogue and prologue instructions
#hence unwinding fail when we are stopped in __thread_start
@expectedFailureAll(triple = 'mips*')
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
+ @expectedFlakeyAndroid("llvm.org/26492", archs=["arm"])
+ @expectedFlakeyLinux("llvm.org/pr27687")
@add_test_categories(['pyapi'])
def test_stack_traces(self):
"""Test SBprocess and SBThread APIs with printing of the stack traces."""
diff --git a/packages/Python/lldbsuite/test/python_api/module_section/TestModuleAndSection.py b/packages/Python/lldbsuite/test/python_api/module_section/TestModuleAndSection.py
index 2de026c54eef..859edd80ee83 100644
--- a/packages/Python/lldbsuite/test/python_api/module_section/TestModuleAndSection.py
+++ b/packages/Python/lldbsuite/test/python_api/module_section/TestModuleAndSection.py
@@ -9,7 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
from lldbsuite.test.lldbutil import symbol_type_to_str
class ModuleAndSectionAPIsTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/objc_type/TestObjCType.py b/packages/Python/lldbsuite/test/python_api/objc_type/TestObjCType.py
index e9b29b90e1a6..b81c422863cb 100644
--- a/packages/Python/lldbsuite/test/python_api/objc_type/TestObjCType.py
+++ b/packages/Python/lldbsuite/test/python_api/objc_type/TestObjCType.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ObjCSBTypeTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/process/TestProcessAPI.py b/packages/Python/lldbsuite/test/python_api/process/TestProcessAPI.py
index f312bc8a9247..d5f407155b29 100644
--- a/packages/Python/lldbsuite/test/python_api/process/TestProcessAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/process/TestProcessAPI.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
-from lldbsuite.test.lldbutil import get_stopped_thread, state_type_to_str
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test.lldbutil import get_stopped_thread, state_type_to_str
class ProcessAPITestCase(TestBase):
@@ -56,7 +57,7 @@ class ProcessAPITestCase(TestBase):
self.expect(content, "Result from SBProcess.ReadMemory() matches our expected output: 'x'",
exe=False,
- startstr = 'x')
+ startstr = b'x')
# Read (char *)my_char_ptr.
val = frame.FindValue("my_char_ptr", lldb.eValueTypeVariableGlobal)
@@ -154,7 +155,7 @@ class ProcessAPITestCase(TestBase):
self.expect(content, "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
exe=False,
- startstr = 'a')
+ startstr = b'a')
@add_test_categories(['pyapi'])
def test_access_my_int(self):
@@ -206,9 +207,8 @@ class ProcessAPITestCase(TestBase):
# But we want to use the WriteMemory() API to assign 256 to the variable.
# Now use WriteMemory() API to write 256 into the global variable.
- new_value = str(bytes)
error = lldb.SBError()
- result = process.WriteMemory(location, new_value, error)
+ result = process.WriteMemory(location, bytes, error)
if not error.Success() or result != byteSize:
self.fail("SBProcess.WriteMemory() failed")
@@ -230,20 +230,18 @@ class ProcessAPITestCase(TestBase):
if not error.Success():
self.fail("SBProcess.ReadMemory() failed")
- # Use "ascii" as the encoding because each element of 'content' is in the range [0..255].
- new_bytes = bytearray(content, "ascii")
-
# The bytearray_to_int utility function expects a little endian bytearray.
if byteOrder == lldb.eByteOrderBig:
- new_bytes.reverse()
+ content = bytearray(content, 'ascii')
+ content.reverse()
- new_value = bytearray_to_int(new_bytes, byteSize)
+ new_value = bytearray_to_int(content, byteSize)
if new_value != 256:
self.fail("Memory content read from 'my_int' does not match (int)256")
# Dump the memory content....
if self.TraceOn():
- for i in new_bytes:
+ for i in content:
print("byte:", i)
@add_test_categories(['pyapi'])
diff --git a/packages/Python/lldbsuite/test/python_api/process/io/TestProcessIO.py b/packages/Python/lldbsuite/test/python_api/process/io/TestProcessIO.py
index 2944ee78acf1..1a194035f4de 100644
--- a/packages/Python/lldbsuite/test/python_api/process/io/TestProcessIO.py
+++ b/packages/Python/lldbsuite/test/python_api/process/io/TestProcessIO.py
@@ -6,8 +6,9 @@ from __future__ import print_function
import os, sys, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class ProcessIOTestCase(TestBase):
@@ -29,6 +30,7 @@ class ProcessIOTestCase(TestBase):
@skipIfWindows # stdio manipulation unsupported on Windows
@add_test_categories(['pyapi'])
+ @expectedFlakeyLinux(bugnumber="llvm.org/pr26437")
def test_stdin_by_api(self):
"""Exercise SBProcess.PutSTDIN()."""
self.build()
@@ -39,6 +41,7 @@ class ProcessIOTestCase(TestBase):
@skipIfWindows # stdio manipulation unsupported on Windows
@add_test_categories(['pyapi'])
+ @expectedFlakeyLinux(bugnumber="llvm.org/pr26437")
def test_stdin_redirection(self):
"""Exercise SBLaunchInfo::AddOpenFileAction() for STDIN without specifying STDOUT or STDERR."""
self.build()
@@ -50,6 +53,7 @@ class ProcessIOTestCase(TestBase):
@skipIfWindows # stdio manipulation unsupported on Windows
@add_test_categories(['pyapi'])
+ @expectedFlakeyLinux(bugnumber="llvm.org/pr26437")
def test_stdout_redirection(self):
"""Exercise SBLaunchInfo::AddOpenFileAction() for STDOUT without specifying STDIN or STDERR."""
self.build()
@@ -62,6 +66,7 @@ class ProcessIOTestCase(TestBase):
@skipIfWindows # stdio manipulation unsupported on Windows
@add_test_categories(['pyapi'])
+ @expectedFlakeyLinux(bugnumber="llvm.org/pr26437")
def test_stderr_redirection(self):
"""Exercise SBLaunchInfo::AddOpenFileAction() for STDERR without specifying STDIN or STDOUT."""
self.build()
@@ -74,6 +79,7 @@ class ProcessIOTestCase(TestBase):
@skipIfWindows # stdio manipulation unsupported on Windows
@add_test_categories(['pyapi'])
+ @expectedFlakeyLinux(bugnumber="llvm.org/pr26437")
def test_stdout_stderr_redirection(self):
"""Exercise SBLaunchInfo::AddOpenFileAction() for STDOUT and STDERR without redirecting STDIN."""
self.build()
diff --git a/packages/Python/lldbsuite/test/python_api/sbdata/TestSBData.py b/packages/Python/lldbsuite/test/python_api/sbdata/TestSBData.py
index 2ff516e10d8e..d8e9515973f7 100644
--- a/packages/Python/lldbsuite/test/python_api/sbdata/TestSBData.py
+++ b/packages/Python/lldbsuite/test/python_api/sbdata/TestSBData.py
@@ -4,11 +4,12 @@ from __future__ import print_function
+from math import fabs
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from math import fabs
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SBDataAPICase(TestBase):
@@ -38,8 +39,9 @@ class SBDataAPICase(TestBase):
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
-
- thread = process.GetThreadAtIndex(0)
+
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertIsNotNone(thread)
frame = thread.GetSelectedFrame()
if self.TraceOn():
@@ -184,7 +186,10 @@ class SBDataAPICase(TestBase):
self.assertTrue(new_object.GetValue() == "1", 'new_object == 1')
- data.SetData(error, 'A\0\0\0', data.GetByteOrder(), data.GetAddressByteSize())
+ if data.GetByteOrder() == lldb.eByteOrderBig:
+ data.SetData(error, '\0\0\0A', data.GetByteOrder(), data.GetAddressByteSize())
+ else:
+ data.SetData(error, 'A\0\0\0', data.GetByteOrder(), data.GetAddressByteSize())
self.assertTrue(error.Success())
data2 = lldb.SBData()
@@ -309,8 +314,8 @@ class SBDataAPICase(TestBase):
self.assert_data(data2.GetSignedInt32, 4, -2)
data2.SetDataFromSInt64Array([2, -2])
- self.assert_data(data2.GetSignedInt32, 0, 2)
- self.assert_data(data2.GetSignedInt32, 8, -2)
+ self.assert_data(data2.GetSignedInt64, 0, 2)
+ self.assert_data(data2.GetSignedInt64, 8, -2)
data2.SetDataFromUInt32Array([1,2,3,4,5])
self.assert_data(data2.GetUnsignedInt32, 0, 1)
diff --git a/packages/Python/lldbsuite/test/python_api/sbtype_typeclass/TestSBTypeTypeClass.py b/packages/Python/lldbsuite/test/python_api/sbtype_typeclass/TestSBTypeTypeClass.py
index 80305e303d03..49bc148dd579 100644
--- a/packages/Python/lldbsuite/test/python_api/sbtype_typeclass/TestSBTypeTypeClass.py
+++ b/packages/Python/lldbsuite/test/python_api/sbtype_typeclass/TestSBTypeTypeClass.py
@@ -1,4 +1,4 @@
-import lldbsuite.test.lldbinline as lldbinline
-import lldbsuite.test.lldbtest as lldbtest
+from lldbsuite.test import decorators
+from lldbsuite.test import lldbinline
-lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.skipIfFreeBSD,lldbtest.skipIfLinux,lldbtest.skipIfWindows])
+lldbinline.MakeInlineTest(__file__, globals(), [decorators.skipIfFreeBSD,decorators.skipIfLinux,decorators.skipIfWindows])
diff --git a/packages/Python/lldbsuite/test/python_api/sbvalue_persist/TestSBValuePersist.py b/packages/Python/lldbsuite/test/python_api/sbvalue_persist/TestSBValuePersist.py
index 6edbbda4c112..e726db7c2d08 100644
--- a/packages/Python/lldbsuite/test/python_api/sbvalue_persist/TestSBValuePersist.py
+++ b/packages/Python/lldbsuite/test/python_api/sbvalue_persist/TestSBValuePersist.py
@@ -6,15 +6,16 @@ from __future__ import print_function
import os, sys, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SBValuePersistTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@add_test_categories(['pyapi'])
- @expectedFailureWindows("llvm.org/pr24772")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24772")
def test(self):
"""Test SBValue::Persist"""
self.build()
diff --git a/packages/Python/lldbsuite/test/python_api/section/TestSectionAPI.py b/packages/Python/lldbsuite/test/python_api/section/TestSectionAPI.py
index 587216468f06..29e089f6b84d 100644
--- a/packages/Python/lldbsuite/test/python_api/section/TestSectionAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/section/TestSectionAPI.py
@@ -5,8 +5,9 @@ Test SBSection APIs.
from __future__ import print_function
-
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class SectionAPITestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/signals/TestSignalsAPI.py b/packages/Python/lldbsuite/test/python_api/signals/TestSignalsAPI.py
index 9825c553cce9..733b0c9d6764 100644
--- a/packages/Python/lldbsuite/test/python_api/signals/TestSignalsAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/signals/TestSignalsAPI.py
@@ -8,14 +8,15 @@ from __future__ import print_function
import os, time
import lldb
-from lldbsuite.test.lldbutil import get_stopped_thread, state_type_to_str
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.lldbutil import get_stopped_thread, state_type_to_str
class SignalsAPITestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@add_test_categories(['pyapi'])
- @expectedFlakeyLinux # this test fails 1/100 dosep runs
@skipIfWindows # Windows doesn't have signals
def test_ignore_signal(self):
"""Test Python SBUnixSignals.Suppress/Stop/Notify() API."""
diff --git a/packages/Python/lldbsuite/test/python_api/symbol-context/TestSymbolContext.py b/packages/Python/lldbsuite/test/python_api/symbol-context/TestSymbolContext.py
index 2fec8dba0365..5d0d01d7a2b6 100644
--- a/packages/Python/lldbsuite/test/python_api/symbol-context/TestSymbolContext.py
+++ b/packages/Python/lldbsuite/test/python_api/symbol-context/TestSymbolContext.py
@@ -6,11 +6,14 @@ from __future__ import print_function
-import os, time
+import os
import re
+import time
+
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class SymbolContextAPITestCase(TestBase):
@@ -23,7 +26,7 @@ class SymbolContextAPITestCase(TestBase):
self.line = line_number('main.c', '// Find the line number of function "c" here.')
@add_test_categories(['pyapi'])
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test(self):
"""Exercise SBSymbolContext API extensively."""
self.build()
diff --git a/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/Makefile b/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/Makefile
new file mode 100644
index 000000000000..650a8b261bea
--- /dev/null
+++ b/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := file1.cpp file2.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/TestSymbolContextTwoFiles.py b/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/TestSymbolContextTwoFiles.py
new file mode 100644
index 000000000000..1d8d70114573
--- /dev/null
+++ b/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/TestSymbolContextTwoFiles.py
@@ -0,0 +1,36 @@
+"""
+Test SBSymbolContext APIs.
+"""
+
+from __future__ import print_function
+
+import os
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class SymbolContextTwoFilesTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @add_test_categories(['pyapi'])
+ @expectedFailureAll(oslist=["windows"])
+ def test_lookup_by_address(self):
+ """Test lookup by address in a module with multiple compilation units"""
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ module = target.GetModuleAtIndex(0)
+ self.assertTrue(module.IsValid())
+ for symbol_name in ["struct1::f()", "struct2::f()"]:
+ sc_list = module.FindFunctions(symbol_name, lldb.eSymbolTypeCode)
+ self.assertTrue(1, sc_list.GetSize())
+ symbol_address = sc_list.GetContextAtIndex(0).GetSymbol().GetStartAddress()
+ self.assertTrue(symbol_address.IsValid())
+ sc_by_address = module.ResolveSymbolContextForAddress(symbol_address, lldb.eSymbolContextFunction)
+ self.assertEqual(symbol_name, sc_by_address.GetFunction().GetName())
diff --git a/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/decls.h b/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/decls.h
new file mode 100644
index 000000000000..0cb685622cd0
--- /dev/null
+++ b/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/decls.h
@@ -0,0 +1,11 @@
+struct struct1
+{
+ static void
+ f();
+};
+
+struct struct2
+{
+ static void
+ f();
+};
diff --git a/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file1.cpp b/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file1.cpp
new file mode 100644
index 000000000000..16c8ce7d9488
--- /dev/null
+++ b/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file1.cpp
@@ -0,0 +1,13 @@
+#include "decls.h"
+
+void
+struct1::f()
+{
+}
+
+int main()
+{
+ struct1::f();
+ struct2::f();
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file2.cpp b/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file2.cpp
new file mode 100644
index 000000000000..3bd1aaf95a73
--- /dev/null
+++ b/packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file2.cpp
@@ -0,0 +1,6 @@
+#include "decls.h"
+
+void
+struct2::f()
+{
+}
diff --git a/packages/Python/lldbsuite/test/python_api/target/TestTargetAPI.py b/packages/Python/lldbsuite/test/python_api/target/TestTargetAPI.py
index 0231d285ecf9..1278742675f3 100644
--- a/packages/Python/lldbsuite/test/python_api/target/TestTargetAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/target/TestTargetAPI.py
@@ -10,8 +10,9 @@ import unittest2
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TargetAPITestCase(TestBase):
@@ -41,7 +42,7 @@ class TargetAPITestCase(TestBase):
self.find_global_variables('b.out')
@add_test_categories(['pyapi'])
- @expectedFailureWindows("llvm.org/pr24778")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_find_functions(self):
"""Exercise SBTarget.FindFunctions() API."""
d = {'EXE': 'b.out'}
diff --git a/packages/Python/lldbsuite/test/python_api/thread/TestThreadAPI.py b/packages/Python/lldbsuite/test/python_api/thread/TestThreadAPI.py
index dad829a48f2f..588aa66cf53e 100644
--- a/packages/Python/lldbsuite/test/python_api/thread/TestThreadAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/thread/TestThreadAPI.py
@@ -8,8 +8,10 @@ from __future__ import print_function
import os, time
import lldb
-from lldbsuite.test.lldbutil import get_stopped_thread, get_caller_symbol
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.lldbutil import get_stopped_thread, get_caller_symbol
class ThreadAPITestCase(TestBase):
@@ -37,8 +39,8 @@ class ThreadAPITestCase(TestBase):
self.run_to_address(self.exe_name)
@add_test_categories(['pyapi'])
- @expectedFailureFreeBSD # llvm.org/pr20476
- @expectedFailureWindows # Test crashes
+ @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr20476')
+ @expectedFailureAll(oslist=["windows"])
def test_step_out_of_malloc_into_function_b(self):
"""Test Python SBThread.StepOut() API to step out of a malloc call where the call site is at function b()."""
# We build a different executable than the default build() does.
diff --git a/packages/Python/lldbsuite/test/python_api/type/TestTypeList.py b/packages/Python/lldbsuite/test/python_api/type/TestTypeList.py
index d9e5719844e2..20e899beee45 100644
--- a/packages/Python/lldbsuite/test/python_api/type/TestTypeList.py
+++ b/packages/Python/lldbsuite/test/python_api/type/TestTypeList.py
@@ -6,11 +6,14 @@ from __future__ import print_function
-import os, time
+import os
import re
+import time
+
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TypeAndTypeListTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/value/TestValueAPI.py b/packages/Python/lldbsuite/test/python_api/value/TestValueAPI.py
index 77ff07ea6488..2a53177d28af 100644
--- a/packages/Python/lldbsuite/test/python_api/value/TestValueAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/value/TestValueAPI.py
@@ -4,13 +4,14 @@ Test some SBValue APIs.
from __future__ import print_function
-
-
-import os, time
+import os
import re
+import time
+
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ValueAPITestCase(TestBase):
@@ -24,7 +25,7 @@ class ValueAPITestCase(TestBase):
# Find the line number to of function 'c'.
self.line = line_number('main.c', '// Break at this line')
- @expectedFailureWindows("llvm.org/pr24772")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24772")
@add_test_categories(['pyapi'])
def test(self):
"""Exercise some SBValue APIs."""
@@ -133,3 +134,12 @@ class ValueAPITestCase(TestBase):
val_a = target.EvaluateExpression('a')
self.assertTrue(val_s.GetChildMemberWithName('a').AddressOf(), VALID_VARIABLE)
self.assertTrue(val_a.Cast(val_i.GetType()).AddressOf(), VALID_VARIABLE)
+
+ self.assertTrue(int(lldb.value(frame0.FindVariable('uinthex'))) == 3768803088, 'uinthex == 3768803088')
+ self.assertTrue(int(lldb.value(frame0.FindVariable('sinthex'))) == -526164208, 'sinthex == -526164208')
+
+ self.assertTrue(frame0.FindVariable('uinthex').GetValueAsUnsigned() == 3768803088, 'unsigned uinthex == 3768803088')
+ self.assertTrue(frame0.FindVariable('sinthex').GetValueAsUnsigned() == 3768803088, 'unsigned sinthex == 3768803088')
+
+ self.assertTrue(frame0.FindVariable('uinthex').GetValueAsSigned() == -526164208, 'signed uinthex == -526164208')
+ self.assertTrue(frame0.FindVariable('sinthex').GetValueAsSigned() == -526164208, 'signed sinthex == -526164208')
diff --git a/packages/Python/lldbsuite/test/python_api/value/change_values/TestChangeValueAPI.py b/packages/Python/lldbsuite/test/python_api/value/change_values/TestChangeValueAPI.py
index f8ad97277f05..52c91e0b2621 100644
--- a/packages/Python/lldbsuite/test/python_api/value/change_values/TestChangeValueAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/value/change_values/TestChangeValueAPI.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ChangeValueAPITestCase(TestBase):
@@ -26,9 +27,9 @@ class ChangeValueAPITestCase(TestBase):
self.check_line = line_number('main.c', '// Stop here and check values')
self.end_line = line_number ('main.c', '// Set a breakpoint here at the end')
- @expectedFailureWindows("llvm.org/pr24772")
@add_test_categories(['pyapi'])
@expectedFlakeyLinux("llvm.org/pr25652")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24772")
def test_change_value(self):
"""Exercise the SBValue::SetValueFromCString API."""
d = {'EXE': self.exe_name}
diff --git a/packages/Python/lldbsuite/test/python_api/value/linked_list/TestValueAPILinkedList.py b/packages/Python/lldbsuite/test/python_api/value/linked_list/TestValueAPILinkedList.py
index 8b60be97bdc2..879efd186d68 100644
--- a/packages/Python/lldbsuite/test/python_api/value/linked_list/TestValueAPILinkedList.py
+++ b/packages/Python/lldbsuite/test/python_api/value/linked_list/TestValueAPILinkedList.py
@@ -10,8 +10,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class ValueAsLinkedListTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/value/main.c b/packages/Python/lldbsuite/test/python_api/value/main.c
index a00795750de0..2ebe3ad303cf 100644
--- a/packages/Python/lldbsuite/test/python_api/value/main.c
+++ b/packages/Python/lldbsuite/test/python_api/value/main.c
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
+#include <stdint.h>
// This simple program is to test the lldb Python API SBValue.GetChildAtIndex().
@@ -38,6 +39,9 @@ struct MyStruct
int main (int argc, char const *argv[])
{
+ uint32_t uinthex = 0xE0A35F10;
+ int32_t sinthex = 0xE0A35F10;
+
int i;
MyInt a = 12345;
struct MyStruct s = { 11, 22 };
diff --git a/packages/Python/lldbsuite/test/python_api/value_var_update/TestValueVarUpdate.py b/packages/Python/lldbsuite/test/python_api/value_var_update/TestValueVarUpdate.py
index 251bbcf4b24d..8620117386f9 100644
--- a/packages/Python/lldbsuite/test/python_api/value_var_update/TestValueVarUpdate.py
+++ b/packages/Python/lldbsuite/test/python_api/value_var_update/TestValueVarUpdate.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import os, sys, time
import lldb
import time
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class HelloWorldTestCase(TestBase):
diff --git a/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py b/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py
index 264e21240dd9..bedf286e199b 100644
--- a/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py
+++ b/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class SetWatchpointAPITestCase(TestBase):
@@ -26,7 +27,8 @@ class SetWatchpointAPITestCase(TestBase):
@add_test_categories(['pyapi'])
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAll(archs=['s390x']) # Read-write watchpoints not supported on SystemZ
def test_watch_val(self):
"""Exercise SBValue.Watch() API to set a watchpoint."""
self.build()
diff --git a/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py b/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py
index a15e73347030..d7b45a533e39 100644
--- a/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py
+++ b/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class WatchpointIgnoreCountTestCase(TestBase):
@@ -26,7 +27,8 @@ class WatchpointIgnoreCountTestCase(TestBase):
@add_test_categories(['pyapi'])
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+ @expectedFailureAll(archs=['s390x']) # Read-write watchpoints not supported on SystemZ
def test_set_watch_ignore_count(self):
"""Test SBWatchpoint.SetIgnoreCount() API."""
self.build()
diff --git a/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py b/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py
index 315450280675..8bbb93af07e5 100644
--- a/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py
+++ b/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py
@@ -6,11 +6,14 @@ from __future__ import print_function
-import os, time
+import os
import re
+import time
+
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class WatchpointIteratorTestCase(TestBase):
@@ -26,7 +29,7 @@ class WatchpointIteratorTestCase(TestBase):
@add_test_categories(['pyapi'])
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
def test_watch_iter(self):
"""Exercise SBTarget.watchpoint_iter() API to iterate on the available watchpoints."""
self.build()
@@ -55,7 +58,7 @@ class WatchpointIteratorTestCase(TestBase):
# Watch 'global' for read and write.
value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal)
error = lldb.SBError();
- watchpoint = value.Watch(True, True, True, error)
+ watchpoint = value.Watch(True, False, True, error)
self.assertTrue(value and watchpoint,
"Successfully found the variable and set a watchpoint")
self.DebugSBValue(value)
diff --git a/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py b/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py
index f30bf856aa07..b368cc066615 100644
--- a/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py
+++ b/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py
@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class WatchpointConditionAPITestCase(TestBase):
@@ -29,6 +30,7 @@ class WatchpointConditionAPITestCase(TestBase):
self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
+ @expectedFailureAll(oslist=["linux"], archs=["aarch64"], bugnumber="llvm.org/pr27710")
@skipIfWindows # Watchpoints not supported on Windows, and this test hangs
def test_watchpoint_cond_api(self):
"""Test watchpoint condition API."""
diff --git a/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py b/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py
index 5a4a464657d6..d0a2c2fff128 100644
--- a/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py
+++ b/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py
@@ -6,11 +6,14 @@ from __future__ import print_function
-import os, time
+import os
import re
+import time
+
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class SetWatchlocationAPITestCase(TestBase):
@@ -28,7 +31,7 @@ class SetWatchlocationAPITestCase(TestBase):
@add_test_categories(['pyapi'])
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
def test_watch_location(self):
"""Exercise SBValue.WatchPointee() API to set a watchpoint."""
self.build()
diff --git a/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py b/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
index 6facbaa8f2e9..468f3131f337 100644
--- a/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
+++ b/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TargetWatchAddressAPITestCase(TestBase):
@@ -28,7 +29,7 @@ class TargetWatchAddressAPITestCase(TestBase):
@add_test_categories(['pyapi'])
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
- @expectedFailureWindows("llvm.org/pr24446")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
def test_watch_address(self):
"""Exercise SBTarget.WatchAddress() API to set a watchpoint."""
self.build()
@@ -92,6 +93,7 @@ class TargetWatchAddressAPITestCase(TestBase):
@add_test_categories(['pyapi'])
@expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported
@skipIf(archs=['mips', 'mipsel', 'mips64', 'mips64el']) # No size constraint on MIPS for watches
+ @skipIf(archs=['s390x']) # Likewise on SystemZ
def test_watch_address_with_invalid_watch_size(self):
"""Exercise SBTarget.WatchAddress() API but pass an invalid watch_size."""
self.build()
diff --git a/packages/Python/lldbsuite/test/settings/TestSettings.py b/packages/Python/lldbsuite/test/settings/TestSettings.py
index 1d1912495551..9592fa9d6dfb 100644
--- a/packages/Python/lldbsuite/test/settings/TestSettings.py
+++ b/packages/Python/lldbsuite/test/settings/TestSettings.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import os, time, re
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class SettingsCommandTestCase(TestBase):
@@ -174,7 +176,7 @@ class SettingsCommandTestCase(TestBase):
self.expect("settings show auto-confirm", SETTING_MSG("auto-confirm"),
startstr = "auto-confirm (boolean) = false")
- @skipUnlessArch(['x86_64', 'i386', 'i686'])
+ @skipIf(archs=no_match(['x86_64', 'i386', 'i686']))
def test_disassembler_settings(self):
"""Test that user options for the disassembler take effect."""
self.build()
@@ -208,7 +210,6 @@ class SettingsCommandTestCase(TestBase):
self.expect("disassemble -n numberfn",
substrs = ["5ah"])
- @expectedFailureWindows("llvm.org/pr24579")
def test_run_args_and_env_vars(self):
"""Test that run-args and env-vars are passed to the launched process."""
self.build()
@@ -311,8 +312,11 @@ class SettingsCommandTestCase(TestBase):
with open('stderr.txt', 'r') as f:
output = f.read()
- self.expect(output, exe=False,
- startstr = "This message should go to standard error.")
+ message = "This message should go to standard error."
+ if lldbplatformutil.hasChattyStderr(self):
+ self.expect(output, exe=False, substrs = [message])
+ else:
+ self.expect(output, exe=False, startstr = message)
# The 'stdout.txt' file should now exist.
self.assertTrue(os.path.isfile("stdout.txt"),
diff --git a/packages/Python/lldbsuite/test/settings/quoting/TestQuoting.py b/packages/Python/lldbsuite/test/settings/quoting/TestQuoting.py
index 878fc8a50675..67c535d649fd 100644
--- a/packages/Python/lldbsuite/test/settings/quoting/TestQuoting.py
+++ b/packages/Python/lldbsuite/test/settings/quoting/TestQuoting.py
@@ -6,9 +6,14 @@ from __future__ import print_function
-import os, time, re
+import os
+import re
+import time
+
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class SettingsCommandTestCase(TestBase):
@@ -23,7 +28,7 @@ class SettingsCommandTestCase(TestBase):
def test_no_quote(self):
self.do_test_args("a b c", "a\0b\0c\0")
- @expectedFailureWindows("http://llvm.org/pr24557")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24557")
@no_debug_info_test
def test_single_quote(self):
self.do_test_args("'a b c'", "a b c\0")
@@ -32,17 +37,17 @@ class SettingsCommandTestCase(TestBase):
def test_double_quote(self):
self.do_test_args('"a b c"', "a b c\0")
- @expectedFailureWindows("http://llvm.org/pr24557")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24557")
@no_debug_info_test
def test_single_quote_escape(self):
self.do_test_args("'a b\\' c", "a b\\\0c\0")
- @expectedFailureWindows("http://llvm.org/pr24557")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24557")
@no_debug_info_test
def test_double_quote_escape(self):
self.do_test_args('"a b\\" c"', 'a b" c\0')
- @expectedFailureWindows("http://llvm.org/pr24557")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24557")
@no_debug_info_test
def test_double_quote_escape2(self):
self.do_test_args('"a b\\\\" c', 'a b\\\0c\0')
@@ -51,7 +56,7 @@ class SettingsCommandTestCase(TestBase):
def test_single_in_double(self):
self.do_test_args('"a\'b"', "a'b\0")
- @expectedFailureWindows("http://llvm.org/pr24557")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24557")
@no_debug_info_test
def test_double_in_single(self):
self.do_test_args("'a\"b'", 'a"b\0')
@@ -64,7 +69,7 @@ class SettingsCommandTestCase(TestBase):
def test_bare_single(self):
self.do_test_args("a\\'b", "a'b\0")
- @expectedFailureWindows("http://llvm.org/pr24557")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24557")
@no_debug_info_test
def test_bare_double(self):
self.do_test_args('a\\"b', 'a"b\0')
diff --git a/packages/Python/lldbsuite/test/source-manager/TestSourceManager.py b/packages/Python/lldbsuite/test/source-manager/TestSourceManager.py
index b4e7541a709a..93e1789103ce 100644
--- a/packages/Python/lldbsuite/test/source-manager/TestSourceManager.py
+++ b/packages/Python/lldbsuite/test/source-manager/TestSourceManager.py
@@ -14,8 +14,9 @@ from __future__ import print_function
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class SourceManagerTestCase(TestBase):
@@ -80,13 +81,17 @@ class SourceManagerTestCase(TestBase):
main_c_hidden = os.path.join("hidden", main_c)
os.rename(main_c, main_c_hidden)
+ # Restore main.c after the test.
+ self.addTearDownHook(lambda: os.rename(main_c_hidden, main_c))
+
if self.TraceOn():
system([["ls"]])
system([["ls", "hidden"]])
- # Restore main.c after the test.
- self.addTearDownHook(lambda: os.rename(main_c_hidden, main_c))
-
+ # Set source remapping with invalid replace path and verify we get an error
+ self.expect("settings set target.source-map /a/b/c/d/e /q/r/s/t/u", error=True,
+ substrs = ['''error: the replacement path doesn't exist: "/q/r/s/t/u"'''])
+
# Set target.source-map settings.
self.runCmd("settings set target.source-map %s %s" % (os.getcwd(), os.path.join(os.getcwd(), "hidden")))
# And verify that the settings work.
@@ -133,7 +138,7 @@ class SourceManagerTestCase(TestBase):
self.assertTrue(int(m.group(1)) > 0)
# Read the main.c file content.
- with open('main.c', 'r') as f:
+ with io.open('main.c', 'r', newline='\n') as f:
original_content = f.read()
if self.TraceOn():
print("original content:", original_content)
@@ -145,7 +150,7 @@ class SourceManagerTestCase(TestBase):
def restore_file():
#print("os.path.getmtime() before restore:", os.path.getmtime('main.c'))
time.sleep(1)
- with open('main.c', 'wb') as f:
+ with io.open('main.c', 'w', newline='\n') as f:
f.write(original_content)
if self.TraceOn():
with open('main.c', 'r') as f:
@@ -156,9 +161,8 @@ class SourceManagerTestCase(TestBase):
print("os.path.getmtime() after restore:", os.path.getmtime('main.c'))
-
# Modify the source code file.
- with open('main.c', 'wb') as f:
+ with io.open('main.c', 'w', newline='\n') as f:
time.sleep(1)
f.write(new_content)
if self.TraceOn():
@@ -170,3 +174,21 @@ class SourceManagerTestCase(TestBase):
# Display the source code again. We should see the updated line.
self.expect("source list -f main.c -l %d" % self.line, SOURCE_DISPLAYED_CORRECTLY,
substrs = ['Hello lldb'])
+
+ def test_set_breakpoint_with_absolute_path(self):
+ self.build()
+ self.runCmd("settings set target.source-map %s %s" % (os.getcwd(), os.path.join(os.getcwd(), "hidden")))
+
+ exe = os.path.join(os.getcwd(), "a.out")
+ main = os.path.join(os.getcwd(), "hidden", "main.c")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, main, self.line, num_expected_locations=1, loc_exact=False)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'main.c:%d' % self.line,
+ 'stop reason = breakpoint'])
diff --git a/packages/Python/lldbsuite/test/terminal/TestSTTYBeforeAndAfter.py b/packages/Python/lldbsuite/test/terminal/TestSTTYBeforeAndAfter.py
index 335042737d44..6644681d2ca1 100644
--- a/packages/Python/lldbsuite/test/terminal/TestSTTYBeforeAndAfter.py
+++ b/packages/Python/lldbsuite/test/terminal/TestSTTYBeforeAndAfter.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import os
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestSTTYBeforeAndAfter(TestBase):
@@ -22,7 +24,7 @@ class TestSTTYBeforeAndAfter(TestBase):
cls.RemoveTempFile("child_send2.txt")
cls.RemoveTempFile("child_read2.txt")
- @expectedFailureHostWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(hostoslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@no_debug_info_test
def test_stty_dash_a_before_and_afetr_invoking_lldb_command(self):
"""Test that 'stty -a' displays the same output before and after running the lldb command."""
diff --git a/packages/Python/lldbsuite/test/test_categories.py b/packages/Python/lldbsuite/test/test_categories.py
index 72b7afdf7241..0a85293109e7 100644
--- a/packages/Python/lldbsuite/test/test_categories.py
+++ b/packages/Python/lldbsuite/test/test_categories.py
@@ -11,9 +11,11 @@ import sys
# Third-party modules
# LLDB modules
+from lldbsuite.support import gmodules
+
debug_info_categories = [
- 'dwarf', 'dwo', 'dsym'
+ 'dwarf', 'dwo', 'dsym', 'gmodules'
]
all_categories = {
@@ -21,6 +23,7 @@ all_categories = {
'dwarf' : 'Tests that can be run with DWARF debug information',
'dwo' : 'Tests that can be run with DWO debug information',
'dsym' : 'Tests that can be run with DSYM debug information',
+ 'gmodules' : 'Tests that can be run with -gmodules debug information',
'expression' : 'Tests related to the expression parser',
'objc' : 'Tests related to the Objective-C programming language support',
'pyapi' : 'Tests related to the Python API',
@@ -42,12 +45,27 @@ def unique_string_match(yourentry, list):
candidate = item
return candidate
-def is_supported_on_platform(category, platform):
+
+def is_supported_on_platform(category, platform, compiler_paths):
if category == "dwo":
# -gsplit-dwarf is not implemented by clang on Windows.
return platform in ["linux", "freebsd"]
elif category == "dsym":
return platform in ["darwin", "macosx", "ios"]
+ elif category == "gmodules":
+ # First, check to see if the platform can even support gmodules.
+ if platform not in ["linux", "freebsd", "darwin", "macosx", "ios"]:
+ return False
+ # If all compilers specified support gmodules, we'll enable it.
+ for compiler_path in compiler_paths:
+ if not gmodules.is_compiler_clang_with_gmodules(compiler_path):
+ # Ideally in a multi-compiler scenario during a single test run, this would
+ # allow gmodules on compilers that support it and not on ones that don't.
+ # However, I didn't see an easy way for all the callers of this to know
+ # the compiler being used for a test invocation. As we tend to run with
+ # a single compiler per test run, this shouldn't be a major issue.
+ return False
+ return True
return True
def validate(categories, exact_match):
diff --git a/packages/Python/lldbsuite/test/test_result.py b/packages/Python/lldbsuite/test/test_result.py
index 9665d672a79a..01db1f691636 100644
--- a/packages/Python/lldbsuite/test/test_result.py
+++ b/packages/Python/lldbsuite/test/test_result.py
@@ -13,15 +13,15 @@ from __future__ import print_function
# System modules
import inspect
+import os
# Third-party modules
import unittest2
# LLDB Modules
-import lldbsuite
from . import configuration
-from .result_formatter import EventBuilder
-
+from lldbsuite.test_event.event_builder import EventBuilder
+from lldbsuite.test_event import build_exception
class LLDBTestResult(unittest2.TextTestResult):
"""
@@ -113,8 +113,6 @@ class LLDBTestResult(unittest2.TextTestResult):
def hardMarkAsSkipped(self,test):
getattr(test, test._testMethodName).__func__.__unittest_skip__ = True
getattr(test, test._testMethodName).__func__.__unittest_skip_why__ = "test case does not fall in any category of interest for this run"
- test.__class__.__unittest_skip__ = True
- test.__class__.__unittest_skip_why__ = "test case does not fall in any category of interest for this run"
def startTest(self, test):
if configuration.shouldSkipBecauseOfCategories(self.getCategoriesForTest(test)):
@@ -140,17 +138,48 @@ class LLDBTestResult(unittest2.TextTestResult):
self.results_formatter.handle_event(
EventBuilder.event_for_success(test))
+ def _isBuildError(self, err_tuple):
+ exception = err_tuple[1]
+ return isinstance(exception, build_exception.BuildError)
+
+ def _getTestPath(self, test):
+ if test is None:
+ return ""
+ elif hasattr(test, "test_filename"):
+ return test.test_filename
+ else:
+ return inspect.getsourcefile(test.__class__)
+
+
+ def _saveBuildErrorTuple(self, test, err):
+ # Adjust the error description so it prints the build command and build error
+ # rather than an uninformative Python backtrace.
+ build_error = err[1]
+ error_description = "{}\nTest Directory:\n{}".format(
+ str(build_error),
+ os.path.dirname(self._getTestPath(test)))
+ self.errors.append((test, error_description))
+ self._mirrorOutput = True
+
def addError(self, test, err):
configuration.sdir_has_content = True
- super(LLDBTestResult, self).addError(test, err)
+ if self._isBuildError(err):
+ self._saveBuildErrorTuple(test, err)
+ else:
+ super(LLDBTestResult, self).addError(test, err)
+
method = getattr(test, "markError", None)
if method:
method()
if configuration.parsable:
self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
if self.results_formatter:
- self.results_formatter.handle_event(
- EventBuilder.event_for_error(test, err))
+ # Handle build errors as a separate event type
+ if self._isBuildError(err):
+ error_event = EventBuilder.event_for_build_error(test, err)
+ else:
+ error_event = EventBuilder.event_for_error(test, err)
+ self.results_formatter.handle_event(error_event)
def addCleanupError(self, test, err):
configuration.sdir_has_content = True
diff --git a/packages/Python/lldbsuite/test/test_runner/__init__.py b/packages/Python/lldbsuite/test/test_runner/__init__.py
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/test_runner/__init__.py
diff --git a/packages/Python/lldbsuite/test/test_runner/lib/process_control.py b/packages/Python/lldbsuite/test/test_runner/process_control.py
index a7e639e4b8b6..a7e639e4b8b6 100644
--- a/packages/Python/lldbsuite/test/test_runner/lib/process_control.py
+++ b/packages/Python/lldbsuite/test/test_runner/process_control.py
diff --git a/packages/Python/lldbsuite/test/test_runner/test/__init__.py b/packages/Python/lldbsuite/test/test_runner/test/__init__.py
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/test_runner/test/__init__.py
diff --git a/packages/Python/lldbsuite/test/test_runner/test/process_control_tests.py b/packages/Python/lldbsuite/test/test_runner/test/test_process_control.py
index 354506d65812..817c83c4fb55 100755
--- a/packages/Python/lldbsuite/test/test_runner/test/process_control_tests.py
+++ b/packages/Python/lldbsuite/test/test_runner/test/test_process_control.py
@@ -12,18 +12,18 @@ within the LLDB test suite.
Tests the process_control module.
"""
+from __future__ import print_function
+
# System imports.
import os
+import os.path
import platform
import unittest
import sys
import threading
-# Add lib dir to pythonpath
-sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'lib'))
-
# Our imports.
-import process_control
+from test_runner import process_control
class TestInferiorDriver(process_control.ProcessDriver):
@@ -77,7 +77,10 @@ class ProcessControlTests(unittest.TestCase):
options=None):
# Base command.
- command = ([sys.executable, "inferior.py"])
+ script_name = "{}/inferior.py".format(os.path.dirname(__file__))
+ if not os.path.exists(script_name):
+ raise Exception("test inferior python script not found: {}".format(script_name))
+ command = ([sys.executable, script_name])
if ignore_soft_terminate:
cls._suppress_soft_terminate(command)
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiExit.py b/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiExit.py
index 86a0a65b05a7..6f814c13ec83 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiExit.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiExit.py
@@ -4,16 +4,16 @@ Test that the lldb-mi driver exits properly.
from __future__ import print_function
-
-
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiExitTestCase(lldbmi_testcase.MiTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_gdb_exit(self):
"""Test that '-gdb-exit' terminates local debug session and exits."""
@@ -37,7 +37,7 @@ class MiExitTestCase(lldbmi_testcase.MiTestCaseBase):
import pexpect
self.expect(pexpect.EOF)
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_quit(self):
"""Test that 'quit' exits immediately."""
@@ -60,7 +60,7 @@ class MiExitTestCase(lldbmi_testcase.MiTestCaseBase):
import pexpect
self.expect(pexpect.EOF)
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_q(self):
"""Test that 'q' exits immediately."""
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiFile.py b/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiFile.py
index 8b4eac156362..99a06f2711fa 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiFile.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiFile.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiFileTestCase(lldbmi_testcase.MiTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiGdbSetShow.py b/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiGdbSetShow.py
index ab3eb1fb37de..9898ad4398fb 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiGdbSetShow.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiGdbSetShow.py
@@ -8,13 +8,15 @@ from __future__ import print_function
import unittest2
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_gdb_set_target_async_default(self):
"""Test that 'lldb-mi --interpreter' switches to async mode by default."""
@@ -33,7 +35,7 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
self.runCmd("-gdb-show target-async")
self.expect("\^done,value=\"on\"")
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@expectedFlakeyLinux("llvm.org/pr26028") # Fails in ~1% of cases
def test_lldbmi_gdb_set_target_async_on(self):
@@ -62,9 +64,9 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
self.expect("\*running")
self.expect("@\"argc=1")
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
- @expectedFailureLinux # Failing in ~11/600 dosep runs (build 3120-3122)
+ @expectedFailureAll(oslist=["linux"], bugnumber="Failing in ~11/600 dosep runs (build 3120-3122)")
def test_lldbmi_gdb_set_target_async_off(self):
"""Test that 'lldb-mi --interpreter' can execute commands in sync mode."""
@@ -87,7 +89,7 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
if it < len(unexpected):
self.fail("unexpected found: %s" % unexpected[it])
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_gdb_show_target_async(self):
"""Test that 'lldb-mi --interpreter' in async mode by default."""
@@ -98,7 +100,7 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
self.runCmd("-gdb-show target-async")
self.expect("\^done,value=\"on\"")
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_gdb_show_language(self):
"""Test that 'lldb-mi --interpreter' can get current language."""
@@ -120,7 +122,7 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
self.runCmd("-gdb-show language")
self.expect("\^done,value=\"c\+\+\"")
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@unittest2.expectedFailure("-gdb-set ignores unknown properties")
def test_lldbmi_gdb_set_unknown(self):
"""Test that 'lldb-mi --interpreter' fails when setting an unknown property."""
@@ -131,7 +133,7 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
self.runCmd("-gdb-set unknown some_value")
self.expect("\^error")
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@unittest2.expectedFailure("-gdb-show ignores unknown properties")
def test_lldbmi_gdb_show_unknown(self):
"""Test that 'lldb-mi --interpreter' fails when showing an unknown property."""
@@ -143,7 +145,7 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
self.expect("\^error")
- @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
def test_lldbmi_gdb_set_ouptut_radix(self):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiLibraryLoaded.py b/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiLibraryLoaded.py
index 4d9c935576df..8e1d72aa19c6 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiLibraryLoaded.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiLibraryLoaded.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiLibraryLoadedTestCase(lldbmi_testcase.MiTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiPrompt.py b/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiPrompt.py
index d810267d9489..50e108e9fa20 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiPrompt.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiPrompt.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiPromptTestCase(lldbmi_testcase.MiTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/breakpoint/TestMiBreak.py b/packages/Python/lldbsuite/test/tools/lldb-mi/breakpoint/TestMiBreak.py
index 020954ff9b41..c4a801c991a4 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/breakpoint/TestMiBreak.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/breakpoint/TestMiBreak.py
@@ -5,10 +5,11 @@ Test lldb-mi -break-xxx commands.
from __future__ import print_function
-
import unittest2
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiBreakTestCase(lldbmi_testcase.MiTestCaseBase):
@@ -16,6 +17,7 @@ class MiBreakTestCase(lldbmi_testcase.MiTestCaseBase):
@skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
+ @expectedFlakeyLinux("llvm.org/pr24717")
def test_lldbmi_break_insert_function_pending(self):
"""Test that 'lldb-mi --interpreter' works for pending function breakpoints."""
@@ -244,3 +246,48 @@ class MiBreakTestCase(lldbmi_testcase.MiTestCaseBase):
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"exited-normally\"")
+
+ @skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows
+ @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
+ def test_lldbmi_break_enable_disable(self):
+ """Test that 'lldb-mi --interpreter' works for enabling / disabling breakpoints."""
+
+ self.spawnLldbMi(args = None)
+
+ self.runCmd("-file-exec-and-symbols %s" % self.myexe)
+ self.expect("\^done")
+
+ self.runCmd("-break-insert main")
+ self.expect("\^done,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\"")
+ self.expect("=breakpoint-modified,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"main\"}")
+
+ self.runCmd("-exec-run")
+ self.expect("\^running")
+ self.expect("=breakpoint-modified,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"main\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"main\"}")
+ self.expect("\*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"1\"")
+
+ self.runCmd("-break-insert ns::foo1")
+ self.expect("\^done,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo1\(\)\"")
+ self.expect("=breakpoint-modified,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo1\(\)\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"ns::foo1\"}")
+
+ self.runCmd("-break-insert ns::foo2")
+ self.expect("\^done,bkpt={number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo2\(\)\"")
+ self.expect("=breakpoint-modified,bkpt={number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo2\(\)\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"ns::foo2\"}")
+
+ # disable the 2nd breakpoint
+ self.runCmd("-break-disable 2")
+ self.expect("\^done")
+ self.expect("=breakpoint-modified,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"n\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo1\(\)\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"ns::foo1\"}")
+
+ # disable the 3rd breakpoint and re-enable
+ self.runCmd("-break-disable 3")
+ self.expect("\^done")
+ self.expect("=breakpoint-modified,bkpt={number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"n\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo2\(\)\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"ns::foo2\"}")
+
+ self.runCmd("-break-enable 3")
+ self.expect("\^done")
+ self.expect("=breakpoint-modified,bkpt={number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\"ns::foo2\(\)\",file=\"main\.cpp\",fullname=\".+?main\.cpp\",line=\"\d+\",times=\"0\",original-location=\"ns::foo2\"}")
+
+ self.runCmd("-exec-continue")
+ self.expect("\^running")
+ self.expect("\*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"3\"")
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py b/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py
index 742bbc8af6bd..a62b9a25400c 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiExecTestCase(lldbmi_testcase.MiTestCaseBase):
@@ -15,7 +17,7 @@ class MiExecTestCase(lldbmi_testcase.MiTestCaseBase):
@skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
- @expectedFailureLinux # llvm.org/pr25000: lldb-mi does not receive broadcasted notification from Core/Process about process stopped
+ @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr25000: lldb-mi does not receive broadcasted notification from Core/Process about process stopped")
def test_lldbmi_exec_run(self):
"""Test that 'lldb-mi --interpreter' can stop at entry."""
@@ -204,7 +206,7 @@ class MiExecTestCase(lldbmi_testcase.MiTestCaseBase):
@skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
- @expectedFailurei386 #xfail to get buildbot green, failing config: i386 binary running on ubuntu 14.04 x86_64
+ @expectedFailureAll(archs=["i[3-6]86"], bugnumber="xfail to get buildbot green, failing config: i386 binary running on ubuntu 14.04 x86_64")
def test_lldbmi_exec_next_instruction(self):
"""Test that 'lldb-mi --interpreter' works for instruction stepping."""
@@ -232,18 +234,20 @@ class MiExecTestCase(lldbmi_testcase.MiTestCaseBase):
# Test that --thread is optional
self.runCmd("-exec-next-instruction --frame 0")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"28\"")
+ # Depending on compiler, it can stop at different line
+ self.expect("\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"(28|29)\"")
# Test that --frame is optional
self.runCmd("-exec-next-instruction --thread 1")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"29\"")
+ # Depending on compiler, it can stop at different line
+ self.expect("\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"(29|30)\"")
# Test that both --thread and --frame are optional
self.runCmd("-exec-next-instruction")
self.expect("\^running")
# Depending on compiler, it can stop at different line
- self.expect("\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"(29|30)\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"(29|30|31)\"")
# Test that an invalid --thread is handled
self.runCmd("-exec-next-instruction --thread 0")
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/data/TestMiData.py b/packages/Python/lldbsuite/test/tools/lldb-mi/data/TestMiData.py
index df9f54110f4b..a19387627c49 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/data/TestMiData.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/data/TestMiData.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import unittest2
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiDataTestCase(lldbmi_testcase.MiTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/interpreter/TestMiCliSupport.py b/packages/Python/lldbsuite/test/tools/lldb-mi/interpreter/TestMiCliSupport.py
index 562be912fbc1..d80bc7f94a65 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/interpreter/TestMiCliSupport.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/interpreter/TestMiCliSupport.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiCliSupportTestCase(lldbmi_testcase.MiTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/interpreter/TestMiInterpreterExec.py b/packages/Python/lldbsuite/test/tools/lldb-mi/interpreter/TestMiInterpreterExec.py
index 93d9f25683b0..2bcaaad38f45 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/interpreter/TestMiInterpreterExec.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/interpreter/TestMiInterpreterExec.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiInterpreterExecTestCase(lldbmi_testcase.MiTestCaseBase):
@@ -55,7 +57,7 @@ class MiInterpreterExecTestCase(lldbmi_testcase.MiTestCaseBase):
@skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
- @expectedFailureLinux # Failing in ~9/600 dosep runs (build 3120-3122)
+ @expectedFlakeyLinux(bugnumber="llvm.org/pr25470")
def test_lldbmi_settings_set_target_run_args_before(self):
"""Test that 'lldb-mi --interpreter' can set target arguments by 'setting set target.run-args' command before than target was created."""
@@ -87,7 +89,7 @@ class MiInterpreterExecTestCase(lldbmi_testcase.MiTestCaseBase):
@skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
- @expectedFailureLinux # Failing in ~9/600 dosep runs (build 3120-3122)
+ @expectedFailureAll(oslist=["linux"], bugnumber="Failing in ~9/600 dosep runs (build 3120-3122)")
def test_lldbmi_settings_set_target_run_args_after(self):
"""Test that 'lldb-mi --interpreter' can set target arguments by 'setting set target.run-args' command after than target was created."""
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/signal/TestMiSignal.py b/packages/Python/lldbsuite/test/tools/lldb-mi/signal/TestMiSignal.py
index 11e7b8a82f68..197bfa80b3a0 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/signal/TestMiSignal.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/signal/TestMiSignal.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiSignalTestCase(lldbmi_testcase.MiTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/stack/TestMiStack.py b/packages/Python/lldbsuite/test/tools/lldb-mi/stack/TestMiStack.py
index 14dab38bb338..54ed91951333 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/stack/TestMiStack.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/stack/TestMiStack.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiStackTestCase(lldbmi_testcase.MiTestCaseBase):
@@ -199,7 +201,20 @@ class MiStackTestCase(lldbmi_testcase.MiTestCaseBase):
self.expect("\^done,locals=\[{name=\"test_str\",type=\"const char \*\",value=\".*?Rakaposhi.*?\"},{name=\"var_e\",type=\"int\",value=\"24\"},{name=\"ptr\",type=\"int \*\",value=\".*?\"}\]")
self.runCmd("-stack-list-locals --simple-values")
self.expect("\^done,locals=\[{name=\"test_str\",type=\"const char \*\",value=\".*?Rakaposhi.*?\"},{name=\"var_e\",type=\"int\",value=\"24\"},{name=\"ptr\",type=\"int \*\",value=\".*?\"}\]")
+
+ # Test -stack-list-locals in a function with catch clause,
+ # having unnamed parameter
+ # Run to BP_catch_unnamed
+ line = line_number('main.cpp', '// BP_catch_unnamed')
+ self.runCmd("-break-insert --file main.cpp:%d" % line)
+ self.expect("\^done,bkpt={number=\"6\"")
+ self.runCmd("-exec-continue")
+ self.expect("\^running")
+ self.expect("\*stopped,reason=\"breakpoint-hit\"")
+ # Test -stack-list-locals: use --no-values
+ self.runCmd("-stack-list-locals --no-values")
+ self.expect("\^done,locals=\[name=\"i\",name=\"j\"\]")
@skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_stack_list_variables(self):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/stack/main.cpp b/packages/Python/lldbsuite/test/tools/lldb-mi/stack/main.cpp
index e11f83e108ec..32db32d2fd16 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/stack/main.cpp
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/stack/main.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include <exception>
+
struct inner
{
int var_d;
@@ -114,6 +116,18 @@ int do_tests_with_args()
return 0;
}
+void catch_unnamed_test()
+{
+ try
+ {
+ int i = 1, j = 2;
+ throw std::exception(); // BP_catch_unnamed
+ }
+ catch(std::exception&)
+ {
+ }
+}
+
int
main(int argc, char const *argv[])
{
@@ -121,6 +135,7 @@ main(int argc, char const *argv[])
local_struct_test();
local_array_test();
local_pointer_test();
+ catch_unnamed_test();
do_tests_with_args();
return 0;
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py b/packages/Python/lldbsuite/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py
index 8f02f1c1eca8..8ddb6b3a1509 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py
@@ -4,10 +4,10 @@ Test lldb-mi startup options.
from __future__ import print_function
-
-
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiStartupOptionsTestCase(lldbmi_testcase.MiTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/symbol/TestMiSymbol.py b/packages/Python/lldbsuite/test/tools/lldb-mi/symbol/TestMiSymbol.py
index 3566b2f220c2..859c096e336d 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/symbol/TestMiSymbol.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/symbol/TestMiSymbol.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiSymbolTestCase(lldbmi_testcase.MiTestCaseBase):
@@ -15,7 +17,7 @@ class MiSymbolTestCase(lldbmi_testcase.MiTestCaseBase):
@skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
- @expectedFailureLinux # new failure after r256863
+ @expectedFailureAll(oslist=["linux"], bugnumber="new failure after r256863")
def test_lldbmi_symbol_list_lines_file(self):
"""Test that 'lldb-mi --interpreter' works for -symbol-list-lines when file exists."""
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/syntax/TestMiSyntax.py b/packages/Python/lldbsuite/test/tools/lldb-mi/syntax/TestMiSyntax.py
index f8a6743eb16d..a40e49f70e7e 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/syntax/TestMiSyntax.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/syntax/TestMiSyntax.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiSyntaxTestCase(lldbmi_testcase.MiTestCaseBase):
@@ -61,7 +63,7 @@ class MiSyntaxTestCase(lldbmi_testcase.MiTestCaseBase):
@skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
- @expectedFailureLinux # Failing in ~6/600 dosep runs (build 3120-3122)
+ @expectedFailureAll(oslist=["linux"], bugnumber="Failing in ~6/600 dosep runs (build 3120-3122)")
def test_lldbmi_process_output(self):
"""Test that 'lldb-mi --interpreter' wraps process output correctly."""
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/target/TestMiTarget.py b/packages/Python/lldbsuite/test/tools/lldb-mi/target/TestMiTarget.py
index 73ef913691cf..2d47db03637c 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/target/TestMiTarget.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/target/TestMiTarget.py
@@ -4,10 +4,10 @@ Test lldb-mi -target-xxx commands.
from __future__ import print_function
-
-
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiTargetTestCase(lldbmi_testcase.MiTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/Makefile b/packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/Makefile
new file mode 100644
index 000000000000..b6fad6778428
--- /dev/null
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := test_threadinfo.cpp
+
+ENABLE_THREADS := YES
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/TestMiThreadInfo.py b/packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/TestMiThreadInfo.py
new file mode 100644
index 000000000000..7226f2e8d320
--- /dev/null
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/TestMiThreadInfo.py
@@ -0,0 +1,39 @@
+"""
+Test lldb-mi -thread-info command.
+"""
+
+from __future__ import print_function
+
+import lldbmi_testcase
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class MiThreadInfoTestCase(lldbmi_testcase.MiTestCaseBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfWindows # pthreads not supported on Windows
+ @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
+ def test_lldbmi_thread_info(self):
+ """Test that -thread-info prints thread info and the current-thread-id"""
+
+ self.spawnLldbMi(args = None)
+
+ # Load executable
+ self.runCmd("-file-exec-and-symbols %s" % self.myexe)
+ self.expect("\^done")
+
+ self.runCmd("-break-insert ThreadProc")
+ self.expect("\^done")
+
+ # Run to the breakpoint
+ self.runCmd("-exec-run")
+ self.expect("\^running")
+ self.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+ self.runCmd("-thread-info")
+ self.expect("\^done,threads=\[\{id=\"1\",(.*)\},\{id=\"2\",(.*)\],current-thread-id=\"2\"")
+
+ self.runCmd("-gdb-quit")
+
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/test_threadinfo.cpp b/packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/test_threadinfo.cpp
new file mode 100644
index 000000000000..1f444ece8c21
--- /dev/null
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/test_threadinfo.cpp
@@ -0,0 +1,21 @@
+#include <cstdlib>
+#include <iostream>
+#include <thread>
+
+using namespace std;
+
+void
+ThreadProc()
+{
+ int i = 0;
+ i++;
+}
+
+int
+main()
+{
+ thread t(ThreadProc);
+ t.join();
+
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py b/packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py
index 067df6408bd4..5ce2b99bbdee 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py
@@ -8,7 +8,9 @@ from __future__ import print_function
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
@@ -108,7 +110,7 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
self.expect("\^error,msg=\"The request ''print' expects option-name and \"on\" or \"off\"' failed.\"")
@skipIfWindows #llvm.org/pr24452: Get lldb-mi working on Windows
- @expectedFailureGcc("https://llvm.org/bugs/show_bug.cgi?id=23357")
+ @expectedFailureAll(compiler="gcc", bugnumber="llvm.org/pr23357")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_gdb_set_show_print_expand_aggregates(self):
"""Test that 'lldb-mi --interpreter' can expand aggregates everywhere."""
@@ -167,7 +169,7 @@ class MiGdbSetShowTestCase(lldbmi_testcase.MiTestCaseBase):
self.expect("\^error,msg=\"The request ''print' expects option-name and \"on\" or \"off\"' failed.\"")
@skipIfWindows #llvm.org/pr24452: Get lldb-mi working on Windows
- @expectedFailureGcc("https://llvm.org/bugs/show_bug.cgi?id=23357")
+ @expectedFailureAll(compiler="gcc", bugnumber="llvm.org/pr23357")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_gdb_set_show_print_aggregate_field_names(self):
"""Test that 'lldb-mi --interpreter' can expand aggregates everywhere."""
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiVar.py b/packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiVar.py
index 26f3a9c63bdc..51f02b9e4a74 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiVar.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/variable/TestMiVar.py
@@ -7,7 +7,9 @@ from __future__ import print_function
import lldbmi_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class MiVarTestCase(lldbmi_testcase.MiTestCaseBase):
@@ -34,9 +36,9 @@ class MiVarTestCase(lldbmi_testcase.MiTestCaseBase):
# Print non-existant variable
self.runCmd("-var-create var1 * undef")
- self.expect("\^error,msg=\"error: error: use of undeclared identifier \'undef\'\\\\nerror: 1 errors parsing expression\\\\n\"")
+ self.expect("\^error,msg=\"error: use of undeclared identifier \'undef\'\\\\n\"")
self.runCmd("-data-evaluate-expression undef")
- self.expect("\^error,msg=\"Could not evaluate expression\"")
+ self.expect("\^error,msg=\"error: use of undeclared identifier \'undef\'\\\\n\"")
# Print global "g_MyVar", modify, delete and create again
self.runCmd("-data-evaluate-expression g_MyVar")
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGDBRemoteMemoryRead.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGDBRemoteMemoryRead.py
index 7b974e548a58..1296d513b917 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGDBRemoteMemoryRead.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGDBRemoteMemoryRead.py
@@ -6,18 +6,21 @@ from __future__ import print_function
+import binascii
import os
+
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
-import binascii
+from lldbsuite.test import lldbutil
+from lldbsuite.test import lldbplatformutil
class MemoryReadTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipUnlessPlatform(getDarwinOSTriples()+["linux"])
+ @skipUnlessPlatform(lldbplatformutil.getDarwinOSTriples()+["linux"])
def test_memory_read(self):
self.build()
exe = os.path.join (os.getcwd(), "a.out")
@@ -34,7 +37,8 @@ class MemoryReadTestCase(TestBase):
error = lldb.SBError()
memory = process.ReadMemory(pc, size, error)
self.assertTrue(error.Success())
- self.match("process plugin packet send x%x,%x" % (pc, size), ["response:", memory])
+ # Results in trying to write non-printable characters to the session log.
+ # self.match("process plugin packet send x%x,%x" % (pc, size), ["response:", memory])
self.match("process plugin packet send m%x,%x" % (pc, size), ["response:", binascii.hexlify(memory)])
process.Continue()
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAttach.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAttach.py
index ca96a9a837b9..5460b21382ec 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAttach.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAttach.py
@@ -4,8 +4,9 @@ from __future__ import print_function
import gdbremote_testcase
import lldbgdbserverutils
-
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGdbRemoteAttach(gdbremote_testcase.GdbRemoteTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAuxvSupport.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAuxvSupport.py
index 1ce5779e7897..e70ad5f570a7 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAuxvSupport.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAuxvSupport.py
@@ -3,7 +3,9 @@ from __future__ import print_function
import gdbremote_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGdbRemoteAuxvSupport(gdbremote_testcase.GdbRemoteTestCaseBase):
@@ -23,7 +25,7 @@ class TestGdbRemoteAuxvSupport(gdbremote_testcase.GdbRemoteTestCaseBase):
# Start the inferior...
"read packet: $c#63",
# ... match output....
- { "type":"output_match", "regex":r"^message:main entered\r\n$" },
+ { "type":"output_match", "regex":self.maybe_strict_output_regex(r"message:main entered\r\n") },
], True)
# ... then interrupt.
self.add_interrupt_packets()
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py
index 6535ce40475d..7daae871caf6 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py
@@ -3,7 +3,9 @@ from __future__ import print_function
import gdbremote_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGdbRemoteExpeditedRegisters(gdbremote_testcase.GdbRemoteTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteKill.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteKill.py
index b253254c78ed..560da9d41429 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteKill.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteKill.py
@@ -4,8 +4,9 @@ from __future__ import print_function
import gdbremote_testcase
import lldbgdbserverutils
-
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGdbRemoteKill(gdbremote_testcase.GdbRemoteTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteProcessInfo.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteProcessInfo.py
index a11167b87c25..f26b62043613 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteProcessInfo.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteProcessInfo.py
@@ -1,12 +1,13 @@
from __future__ import print_function
+import sys
import gdbremote_testcase
import lldbgdbserverutils
-import sys
-
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGdbRemoteProcessInfo(gdbremote_testcase.GdbRemoteTestCaseBase):
@@ -51,7 +52,7 @@ class TestGdbRemoteProcessInfo(gdbremote_testcase.GdbRemoteTestCaseBase):
self.add_process_info_collection_packets()
# Run the stream
- context = self.expect_gdbremote_sequence()
+ context = self.expect_gdbremote_sequence(timeout_seconds = 8)
self.assertIsNotNone(context)
# Gather process info response
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py
index a36b4ae781ad..63a8995c6729 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py
@@ -3,7 +3,9 @@ from __future__ import print_function
import gdbremote_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGdbRemoteRegisterState(gdbremote_testcase.GdbRemoteTestCaseBase):
"""Test QSaveRegisterState/QRestoreRegisterState support."""
@@ -24,7 +26,7 @@ class TestGdbRemoteRegisterState(gdbremote_testcase.GdbRemoteTestCaseBase):
# Start the inferior...
"read packet: $c#63",
# ... match output....
- { "type":"output_match", "regex":r"^message:main entered\r\n$" },
+ { "type":"output_match", "regex":self.maybe_strict_output_regex(r"message:main entered\r\n") },
], True)
# ... then interrupt.
self.add_interrupt_packets()
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteSingleStep.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteSingleStep.py
index 3b008249f557..31d53bed2593 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteSingleStep.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteSingleStep.py
@@ -3,7 +3,9 @@ from __future__ import print_function
import gdbremote_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGdbRemoteSingleStep(gdbremote_testcase.GdbRemoteTestCaseBase):
@@ -17,7 +19,8 @@ class TestGdbRemoteSingleStep(gdbremote_testcase.GdbRemoteTestCaseBase):
self.single_step_only_steps_one_instruction(use_Hc_packet=True, step_instruction="s")
@llgs_test
- @expectedFailureAndroid(bugnumber="llvm.com/pr24739", archs=["arm", "aarch64"])
+ @expectedFailureAndroid(bugnumber="llvm.org/pr24739", archs=["arm", "aarch64"])
+ @expectedFailureAll(oslist=["linux"], archs=["arm", "aarch64"], bugnumber="llvm.org/pr24739")
def test_single_step_only_steps_one_instruction_with_s_llgs(self):
self.init_llgs_test()
self.build()
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py
index a7938795b9bf..d55416569ac4 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py
@@ -1,9 +1,9 @@
from __future__ import print_function
-
-
import gdbremote_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGdbRemoteThreadsInStopReply(gdbremote_testcase.GdbRemoteTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py
index cce484451de4..b2b54e3f0394 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py
@@ -6,7 +6,9 @@ import sys
import unittest2
import gdbremote_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGdbRemote_qThreadStopInfo(gdbremote_testcase.GdbRemoteTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_vCont.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_vCont.py
index 579e99d6d774..335d96c2b074 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_vCont.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_vCont.py
@@ -1,9 +1,9 @@
from __future__ import print_function
-
-
import gdbremote_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGdbRemote_vCont(gdbremote_testcase.GdbRemoteTestCaseBase):
@@ -93,7 +93,8 @@ class TestGdbRemote_vCont(gdbremote_testcase.GdbRemoteTestCaseBase):
self.single_step_only_steps_one_instruction(use_Hc_packet=True, step_instruction="vCont;s")
@llgs_test
- @expectedFailureAndroid(bugnumber="llvm.com/pr24739", archs=["arm", "aarch64"])
+ @expectedFailureAndroid(bugnumber="llvm.org/pr24739", archs=["arm", "aarch64"])
+ @expectedFailureAll(oslist=["linux"], archs=["arm", "aarch64"], bugnumber="llvm.org/pr24739")
def test_single_step_only_steps_one_instruction_with_Hc_vCont_s_llgs(self):
self.init_llgs_test()
self.build()
@@ -108,7 +109,8 @@ class TestGdbRemote_vCont(gdbremote_testcase.GdbRemoteTestCaseBase):
self.single_step_only_steps_one_instruction(use_Hc_packet=False, step_instruction="vCont;s:{thread}")
@llgs_test
- @expectedFailureAndroid(bugnumber="llvm.com/pr24739", archs=["arm", "aarch64"])
+ @expectedFailureAndroid(bugnumber="llvm.org/pr24739", archs=["arm", "aarch64"])
+ @expectedFailureAll(oslist=["linux"], archs=["arm", "aarch64"], bugnumber="llvm.org/pr24739")
def test_single_step_only_steps_one_instruction_with_vCont_s_thread_llgs(self):
self.init_llgs_test()
self.build()
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py
index aec040c50569..c01cc7a17250 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py
@@ -19,7 +19,9 @@ import gdbremote_testcase
import lldbgdbserverutils
import platform
import signal
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
@@ -230,7 +232,7 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
self.add_verified_launch_packets(launch_args)
self.test_sequence.add_log_lines(
["read packet: $vCont;c#a8",
- {"type":"output_match", "regex":r"^hello, world\r\n$" },
+ {"type":"output_match", "regex": self.maybe_strict_output_regex(r"hello, world\r\n")},
"send packet: $W00#00"],
True)
@@ -244,6 +246,7 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
self.inferior_print_exit()
@llgs_test
+ @expectedFlakeyLinux("llvm.org/pr25652")
def test_inferior_print_exit_llgs(self):
self.init_llgs_test()
self.build()
@@ -865,7 +868,8 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
"read packet: $c#63",
# Match output line that prints the memory address of the message buffer within the inferior.
# Note we require launch-only testing so we can get inferior otuput.
- { "type":"output_match", "regex":r"^data address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"message_address"} },
+ { "type":"output_match", "regex":self.maybe_strict_output_regex(r"data address: 0x([0-9a-fA-F]+)\r\n"),
+ "capture":{ 1:"message_address"} },
# Now stop the inferior.
"read packet: {}".format(chr(3)),
# And wait for the stop notification.
@@ -947,7 +951,8 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
"read packet: $c#63",
# Match output line that prints the memory address of the message buffer within the inferior.
# Note we require launch-only testing so we can get inferior otuput.
- { "type":"output_match", "regex":r"^code address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"code_address"} },
+ { "type":"output_match", "regex":self.maybe_strict_output_regex(r"code address: 0x([0-9a-fA-F]+)\r\n"),
+ "capture":{ 1:"code_address"} },
# Now stop the inferior.
"read packet: {}".format(chr(3)),
# And wait for the stop notification.
@@ -1008,7 +1013,8 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
"read packet: $c#63",
# Match output line that prints the memory address of the message buffer within the inferior.
# Note we require launch-only testing so we can get inferior otuput.
- { "type":"output_match", "regex":r"^stack address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"stack_address"} },
+ { "type":"output_match", "regex":self.maybe_strict_output_regex(r"stack address: 0x([0-9a-fA-F]+)\r\n"),
+ "capture":{ 1:"stack_address"} },
# Now stop the inferior.
"read packet: {}".format(chr(3)),
# And wait for the stop notification.
@@ -1069,7 +1075,8 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
"read packet: $c#63",
# Match output line that prints the memory address of the message buffer within the inferior.
# Note we require launch-only testing so we can get inferior otuput.
- { "type":"output_match", "regex":r"^heap address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"heap_address"} },
+ { "type":"output_match", "regex":self.maybe_strict_output_regex(r"heap address: 0x([0-9a-fA-F]+)\r\n"),
+ "capture":{ 1:"heap_address"} },
# Now stop the inferior.
"read packet: {}".format(chr(3)),
# And wait for the stop notification.
@@ -1132,7 +1139,8 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
"read packet: $c#63",
# Match output line that prints the memory address of the function call entry point.
# Note we require launch-only testing so we can get inferior otuput.
- { "type":"output_match", "regex":r"^code address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"function_address"} },
+ { "type":"output_match", "regex":self.maybe_strict_output_regex(r"code address: 0x([0-9a-fA-F]+)\r\n"),
+ "capture":{ 1:"function_address"} },
# Now stop the inferior.
"read packet: {}".format(chr(3)),
# And wait for the stop notification.
@@ -1230,6 +1238,7 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
self.software_breakpoint_set_and_remove_work()
@llgs_test
+ @expectedFlakeyLinux("llvm.org/pr25652")
def test_software_breakpoint_set_and_remove_work_llgs(self):
self.init_llgs_test()
self.build()
@@ -1275,7 +1284,8 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
"read packet: $c#63",
# Match output line that prints the memory address of the message buffer within the inferior.
# Note we require launch-only testing so we can get inferior otuput.
- { "type":"output_match", "regex":r"^data address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"message_address"} },
+ { "type":"output_match", "regex":self.maybe_strict_output_regex(r"data address: 0x([0-9a-fA-F]+)\r\n"),
+ "capture":{ 1:"message_address"} },
# Now stop the inferior.
"read packet: {}".format(chr(3)),
# And wait for the stop notification.
@@ -1316,6 +1326,7 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
self.written_M_content_reads_back_correctly()
@llgs_test
+ @expectedFlakeyLinux("llvm.org/pr25652")
def test_written_M_content_reads_back_correctly_llgs(self):
self.init_llgs_test()
self.build()
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubReverseConnect.py b/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubReverseConnect.py
index 9035237b982a..6894d1ceacc6 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubReverseConnect.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubReverseConnect.py
@@ -6,7 +6,9 @@ import re
import select
import socket
import time
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestStubReverseConnect(gdbremote_testcase.GdbRemoteTestCaseBase):
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubSetSID.py b/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubSetSID.py
index 2b2b0e82379b..bda93155d27e 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubSetSID.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubSetSID.py
@@ -8,7 +8,9 @@ import os
import select
import tempfile
import time
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestStubSetSIDTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
@@ -47,7 +49,7 @@ class TestStubSetSIDTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
@llgs_test
@skipIfRemote # --setsid not used on remote platform and currently it is also impossible to get the sid of lldb-platform running on a remote target
- @expectedFailureFreeBSD()
+ @expectedFailureAll(oslist=['freebsd'])
def test_sid_is_same_without_setsid_llgs(self):
self.init_llgs_test()
self.set_inferior_startup_launch()
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py b/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
index 113e01e36ba7..d63ddbe39998 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
@@ -24,14 +24,16 @@ from lldbsuite.test.lldbtest import *
from lldbgdbserverutils import *
import logging
+class _ConnectionRefused(IOError):
+ pass
+
class GdbRemoteTestCaseBase(TestBase):
- _TIMEOUT_SECONDS = 5
+ NO_DEBUG_INFO_TESTCASE = True
- _GDBREMOTE_KILL_PACKET = "$k#6b"
+ _TIMEOUT_SECONDS = 7
- _LOGGING_LEVEL = logging.WARNING
- # _LOGGING_LEVEL = logging.DEBUG
+ _GDBREMOTE_KILL_PACKET = "$k#6b"
# Start the inferior separately, attach to the inferior on the stub command line.
_STARTUP_ATTACH = "attach"
@@ -48,12 +50,44 @@ class GdbRemoteTestCaseBase(TestBase):
TARGET_EXC_SOFTWARE = 0x95
TARGET_EXC_BREAKPOINT = 0x96
+ _verbose_log_handler = None
+ _log_formatter = logging.Formatter(fmt='%(asctime)-15s %(levelname)-8s %(message)s')
+
+ def setUpBaseLogging(self):
+ self.logger = logging.getLogger(__name__)
+
+ if len(self.logger.handlers) > 0:
+ return # We have set up this handler already
+
+ self.logger.propagate = False
+ self.logger.setLevel(logging.DEBUG)
+
+ # log all warnings to stderr
+ handler = logging.StreamHandler()
+ handler.setLevel(logging.WARNING)
+ handler.setFormatter(self._log_formatter)
+ self.logger.addHandler(handler)
+
+
+ def isVerboseLoggingRequested(self):
+ # We will report our detailed logs if the user requested that the "gdb-remote" channel is
+ # logged.
+ return any(("gdb-remote" in channel) for channel in lldbtest_config.channels)
+
def setUp(self):
TestBase.setUp(self)
- FORMAT = '%(asctime)-15s %(levelname)-8s %(message)s'
- logging.basicConfig(format=FORMAT)
- self.logger = logging.getLogger(__name__)
- self.logger.setLevel(self._LOGGING_LEVEL)
+
+ self.setUpBaseLogging()
+ self.debug_monitor_extra_args = []
+ self._pump_queues = socket_packet_pump.PumpQueues()
+
+ if self.isVerboseLoggingRequested():
+ # If requested, full logs go to a log file
+ self._verbose_log_handler = logging.FileHandler(self.log_basename + "-host.log")
+ self._verbose_log_handler.setFormatter(self._log_formatter)
+ self._verbose_log_handler.setLevel(logging.DEBUG)
+ self.logger.addHandler(self._verbose_log_handler)
+
self.test_sequence = GdbRemoteTestSequence(self.logger)
self.set_inferior_startup_launch()
self.port = self.get_next_port()
@@ -76,6 +110,31 @@ class GdbRemoteTestCaseBase(TestBase):
else:
self.stub_hostname = "localhost"
+ def tearDown(self):
+ self._pump_queues.verify_queues_empty()
+
+ self.logger.removeHandler(self._verbose_log_handler)
+ self._verbose_log_handler = None
+ TestBase.tearDown(self)
+
+ def getLocalServerLogFile(self):
+ return self.log_basename + "-server.log"
+
+ def setUpServerLogging(self, is_llgs):
+ if len(lldbtest_config.channels) == 0:
+ return # No logging requested
+
+ if lldb.remote_platform:
+ log_file = lldbutil.join_remote_paths(lldb.remote_platform.GetWorkingDirectory(), "server.log")
+ else:
+ log_file = self.getLocalServerLogFile()
+
+ if is_llgs:
+ self.debug_monitor_extra_args.append("--log-file=" + log_file)
+ self.debug_monitor_extra_args.append("--log-channels={}".format(":".join(lldbtest_config.channels)))
+ else:
+ self.debug_monitor_extra_args = ["--log-file=" + self.log_file, "--log-flags=0x800000"]
+
def get_next_port(self):
return 12000 + random.randint(0,3999)
@@ -147,30 +206,21 @@ class GdbRemoteTestCaseBase(TestBase):
return stub_port
- def run_shell_cmd(self, cmd):
- platform = self.dbg.GetSelectedPlatform()
- shell_cmd = lldb.SBPlatformShellCommand(cmd)
- err = platform.Run(shell_cmd)
- if err.Fail() or shell_cmd.GetStatus():
- m = "remote_platform.RunShellCommand('%s') failed:\n" % cmd
- m += ">>> return code: %d\n" % shell_cmd.GetStatus()
- if err.Fail():
- m += ">>> %s\n" % str(err).strip()
- m += ">>> %s\n" % (shell_cmd.GetOutput() or
- "Command generated no output.")
- raise Exception(m)
- return shell_cmd.GetOutput().strip()
-
def init_llgs_test(self, use_named_pipe=True):
if lldb.remote_platform:
# Remote platforms don't support named pipe based port negotiation
use_named_pipe = False
# Grab the ppid from /proc/[shell pid]/stat
- shell_stat = self.run_shell_cmd("cat /proc/$$/stat")
+ err, retcode, shell_stat = self.run_platform_command("cat /proc/$$/stat")
+ self.assertTrue(err.Success() and retcode == 0,
+ "Failed to read file /proc/$$/stat: %s, retcode: %d" % (err.GetCString(), retcode))
+
# [pid] ([executable]) [state] [*ppid*]
pid = re.match(r"^\d+ \(.+\) . (\d+)", shell_stat).group(1)
- ls_output = self.run_shell_cmd("ls -l /proc/%s/exe" % pid)
+ err, retcode, ls_output = self.run_platform_command("ls -l /proc/%s/exe" % pid)
+ self.assertTrue(err.Success() and retcode == 0,
+ "Failed to read file /proc/%s/exe: %s, retcode: %d" % (pid, err.GetCString(), retcode))
exe = ls_output.split()[-1]
# If the binary has been deleted, the link name has " (deleted)" appended.
@@ -182,10 +232,7 @@ class GdbRemoteTestCaseBase(TestBase):
self.skipTest("lldb-server exe not found")
self.debug_monitor_extra_args = ["gdbserver"]
-
- if len(lldbtest_config.channels) > 0:
- self.debug_monitor_extra_args.append("--log-file={}-server.log".format(self.log_basename))
- self.debug_monitor_extra_args.append("--log-channels={}".format(":".join(lldbtest_config.channels)))
+ self.setUpServerLogging(is_llgs=True)
if use_named_pipe:
(self.named_pipe_path, self.named_pipe, self.named_pipe_fd) = self.create_named_pipe()
@@ -194,7 +241,7 @@ class GdbRemoteTestCaseBase(TestBase):
self.debug_monitor_exe = get_debugserver_exe()
if not self.debug_monitor_exe:
self.skipTest("debugserver exe not found")
- self.debug_monitor_extra_args = ["--log-file={}-server.log".format(self.log_basename), "--log-flags=0x800000"]
+ self.setUpServerLogging(is_llgs=False)
if use_named_pipe:
(self.named_pipe_path, self.named_pipe, self.named_pipe_fd) = self.create_named_pipe()
# The debugserver stub has a race on handling the 'k' command, so it sends an X09 right away, then sends the real X notification
@@ -209,6 +256,22 @@ class GdbRemoteTestCaseBase(TestBase):
subprocess.call(adb + [ "tcp:%d" % source, "tcp:%d" % target])
self.addTearDownHook(remove_port_forward)
+ def _verify_socket(self, sock):
+ # Normally, when the remote stub is not ready, we will get ECONNREFUSED during the
+ # connect() attempt. However, due to the way how ADB forwarding works, on android targets
+ # the connect() will always be successful, but the connection will be immediately dropped
+ # if ADB could not connect on the remote side. This function tries to detect this
+ # situation, and report it as "connection refused" so that the upper layers attempt the
+ # connection again.
+ triple = self.dbg.GetSelectedPlatform().GetTriple()
+ if not re.match(".*-.*-.*-android", triple):
+ return # Not android.
+ can_read, _, _ = select.select([sock], [], [], 0.1)
+ if sock not in can_read:
+ return # Data is not available, but the connection is alive.
+ if len(sock.recv(1, socket.MSG_PEEK)) == 0:
+ raise _ConnectionRefused() # Got EOF, connection dropped.
+
def create_socket(self):
sock = socket.socket()
logger = self.logger
@@ -217,8 +280,14 @@ class GdbRemoteTestCaseBase(TestBase):
if re.match(".*-.*-.*-android", triple):
self.forward_adb_port(self.port, self.port, "forward", self.stub_device)
+ logger.info("Connecting to debug monitor on %s:%d", self.stub_hostname, self.port)
connect_info = (self.stub_hostname, self.port)
- sock.connect(connect_info)
+ try:
+ sock.connect(connect_info)
+ except socket.error as serr:
+ if serr.errno == errno.ECONNREFUSED:
+ raise _ConnectionRefused()
+ raise serr
def shutdown_socket():
if sock:
@@ -235,6 +304,8 @@ class GdbRemoteTestCaseBase(TestBase):
self.addTearDownHook(shutdown_socket)
+ self._verify_socket(sock)
+
return sock
def set_inferior_startup_launch(self):
@@ -258,12 +329,6 @@ class GdbRemoteTestCaseBase(TestBase):
commandline_args += ["--named-pipe", self.named_pipe_path]
return commandline_args
- def run_platform_command(self, cmd):
- platform = self.dbg.GetSelectedPlatform()
- shell_command = lldb.SBPlatformShellCommand(cmd)
- err = platform.Run(shell_command)
- return (err, shell_command.GetOutput())
-
def launch_debug_monitor(self, attach_pid=None, logfile=None):
# Create the command line.
commandline_args = self.get_debug_monitor_command_line_args(attach_pid=attach_pid)
@@ -322,12 +387,12 @@ class GdbRemoteTestCaseBase(TestBase):
while connect_attemps < MAX_CONNECT_ATTEMPTS:
# Create a socket to talk to the server
try:
+ logger.info("Connect attempt %d", connect_attemps+1)
self.sock = self.create_socket()
return server
- except socket.error as serr:
- # We're only trying to handle connection refused.
- if serr.errno != errno.ECONNREFUSED:
- raise serr
+ except _ConnectionRefused as serr:
+ # Ignore, and try again.
+ pass
time.sleep(0.5)
connect_attemps += 1
@@ -546,7 +611,8 @@ class GdbRemoteTestCaseBase(TestBase):
def expect_gdbremote_sequence(self, timeout_seconds=None):
if not timeout_seconds:
timeout_seconds = self._TIMEOUT_SECONDS
- return expect_lldb_gdbserver_replay(self, self.sock, self.test_sequence, timeout_seconds, self.logger)
+ return expect_lldb_gdbserver_replay(self, self.sock, self.test_sequence,
+ self._pump_queues, timeout_seconds, self.logger)
_KNOWN_REGINFO_KEYS = [
"name",
@@ -556,6 +622,7 @@ class GdbRemoteTestCaseBase(TestBase):
"encoding",
"format",
"set",
+ "gcc",
"ehframe",
"dwarf",
"generic",
@@ -1281,6 +1348,9 @@ class GdbRemoteTestCaseBase(TestBase):
#MIPS required "3" (ADDIU, SB, LD) machine instructions for updation of variable value
if re.match("mips",arch):
expected_step_count = 3
+ #S390X requires "2" (LARL, MVI) machine instructions for updation of variable value
+ if re.match("s390x",arch):
+ expected_step_count = 2
self.assertEqual(step_count, expected_step_count)
# Verify we hit the next state.
@@ -1297,3 +1367,6 @@ class GdbRemoteTestCaseBase(TestBase):
self.assertTrue(state_reached)
self.assertEqual(step_count, expected_step_count)
+ def maybe_strict_output_regex(self, regex):
+ return '.*'+regex+'.*' if lldbplatformutil.hasChattyStderr(self) else '^'+regex+'$'
+
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteAbort.py b/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteAbort.py
index d13433252e12..8bd00a3f1b21 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteAbort.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteAbort.py
@@ -4,7 +4,9 @@ from __future__ import print_function
import gdbremote_testcase
import signal
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGdbRemoteAbort(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteSegFault.py b/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteSegFault.py
index 6618d8f75fc9..949b00b0f614 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteSegFault.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteSegFault.py
@@ -4,7 +4,9 @@ from __future__ import print_function
import gdbremote_testcase
import signal
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class TestGdbRemoteSegFault(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py b/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py
index c0ea841e2a03..0c73bed9ea0a 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py
@@ -154,6 +154,7 @@ def expect_lldb_gdbserver_replay(
asserter,
sock,
test_sequence,
+ pump_queues,
timeout_seconds,
logger=None):
"""Replay socket communication with lldb-gdbserver and verify responses.
@@ -193,7 +194,7 @@ def expect_lldb_gdbserver_replay(
return {}
context = {"O_count":0, "O_content":""}
- with socket_packet_pump.SocketPacketPump(sock, logger) as pump:
+ with socket_packet_pump.SocketPacketPump(sock, pump_queues, logger) as pump:
# Grab the first sequence entry.
sequence_entry = test_sequence.entries.pop(0)
@@ -220,14 +221,14 @@ def expect_lldb_gdbserver_replay(
if sequence_entry.is_output_matcher():
try:
# Grab next entry from the output queue.
- content = pump.output_queue().get(True, timeout_seconds)
+ content = pump_queues.output_queue().get(True, timeout_seconds)
except queue.Empty:
if logger:
logger.warning("timeout waiting for stub output (accumulated output:{})".format(pump.get_accumulated_output()))
raise Exception("timed out while waiting for output match (accumulated output: {})".format(pump.get_accumulated_output()))
else:
try:
- content = pump.packet_queue().get(True, timeout_seconds)
+ content = pump_queues.packet_queue().get(True, timeout_seconds)
except queue.Empty:
if logger:
logger.warning("timeout waiting for packet match (receive buffer: {})".format(pump.get_receive_buffer()))
@@ -386,7 +387,10 @@ def pack_register_hex(endian, value, byte_size=None):
return retval
elif endian == 'big':
- retval = value.encode("hex")
+ retval = ""
+ while value != 0:
+ retval = "{:02x}".format(value & 0xff) + retval
+ value = value >> 8
if byte_size:
# Add zero-fill to the left/front (MSB side) of the value.
retval = ("00" * (byte_size - len(retval)/2)) + retval
@@ -783,7 +787,7 @@ class GdbRemoteTestSequence(object):
regex = line.get("regex", None)
# Compile the regex.
if regex and (type(regex) == str):
- regex = re.compile(regex)
+ regex = re.compile(regex, re.DOTALL)
regex_mode = line.get("regex_mode", "match")
capture = line.get("capture", None)
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py b/packages/Python/lldbsuite/test/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py
index b50a03015462..5c28d288db53 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py
@@ -1,8 +1,11 @@
from __future__ import print_function
+import time
+
import gdbremote_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test import lldbutil
class TestPlatformProcessConnect(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@@ -21,11 +24,22 @@ class TestPlatformProcessConnect(gdbremote_testcase.GdbRemoteTestCaseBase):
if err.Fail():
raise RuntimeError("Unable copy '%s' to '%s'.\n>>> %s" % (f, wd, err.GetCString()))
+ m = re.search("^(.*)://([^:/]*)", configuration.lldb_platform_url)
+ protocol = m.group(1)
+ hostname = m.group(2)
+ unix_protocol = protocol.startswith("unix-")
+ if unix_protocol:
+ p = re.search("^(.*)-connect", protocol)
+ listen_url = "%s://%s" % (p.group(1), os.path.join(working_dir, "platform-%d.sock" % int(time.time())))
+ else:
+ listen_url = "*:0"
+
port_file = "%s/port" % working_dir
- commandline_args = ["platform", "--listen", "*:0", "--socket-file", port_file, "--", "%s/a.out" % working_dir, "foo"]
+ commandline_args = ["platform", "--listen", listen_url, "--socket-file", port_file, "--", "%s/a.out" % working_dir, "foo"]
self.spawnSubprocess(self.debug_monitor_exe, commandline_args, install_remote=False)
self.addTearDownHook(self.cleanupSubprocesses)
- new_port = self.run_shell_cmd("while [ ! -f %s ]; do sleep 0.25; done && cat %s" % (port_file, port_file))
+
+ socket_id = lldbutil.wait_for_file_on_target(self, port_file)
new_debugger = lldb.SBDebugger.Create()
new_debugger.SetAsync(False)
@@ -37,8 +51,12 @@ class TestPlatformProcessConnect(gdbremote_testcase.GdbRemoteTestCaseBase):
new_debugger.SetSelectedPlatform(new_platform)
new_interpreter = new_debugger.GetCommandInterpreter()
- m = re.search("(.*):[0-9]+", configuration.lldb_platform_url)
- command = "platform connect %s:%s" % (m.group(1), new_port)
+ if unix_protocol:
+ connect_url = "%s://%s%s" % (protocol, hostname, socket_id)
+ else:
+ connect_url = "%s://%s:%s" % (protocol, hostname, socket_id)
+
+ command = "platform connect %s" % (connect_url)
result = lldb.SBCommandReturnObject()
new_interpreter.HandleCommand(command, result)
self.assertTrue(result.Succeeded(), "platform process connect failed: %s" % result.GetOutput())
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/socket_packet_pump.py b/packages/Python/lldbsuite/test/tools/lldb-server/socket_packet_pump.py
index 795a8c6652d0..9f594b7df73c 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-server/socket_packet_pump.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/socket_packet_pump.py
@@ -26,6 +26,33 @@ def _dump_queue(the_queue):
print(codecs.encode(the_queue.get(True), "string_escape"))
print("\n")
+class PumpQueues(object):
+ def __init__(self):
+ self._output_queue = queue.Queue()
+ self._packet_queue = queue.Queue()
+
+ def output_queue(self):
+ return self._output_queue
+
+ def packet_queue(self):
+ return self._packet_queue
+
+ def verify_queues_empty(self):
+ # Warn if there is any content left in any of the queues.
+ # That would represent unmatched packets.
+ if not self.output_queue().empty():
+ print("warning: output queue entries still exist:")
+ _dump_queue(self.output_queue())
+ print("from here:")
+ traceback.print_stack()
+
+ if not self.packet_queue().empty():
+ print("warning: packet queue entries still exist:")
+ _dump_queue(self.packet_queue())
+ print("from here:")
+ traceback.print_stack()
+
+
class SocketPacketPump(object):
"""A threaded packet reader that partitions packets into two streams.
@@ -40,18 +67,17 @@ class SocketPacketPump(object):
_GDB_REMOTE_PACKET_REGEX = re.compile(r'^\$([^\#]*)#[0-9a-fA-F]{2}')
- def __init__(self, pump_socket, logger=None):
+ def __init__(self, pump_socket, pump_queues, logger=None):
if not pump_socket:
raise Exception("pump_socket cannot be None")
- self._output_queue = queue.Queue()
- self._packet_queue = queue.Queue()
self._thread = None
self._stop_thread = False
self._socket = pump_socket
self._logger = logger
self._receive_buffer = ""
self._accumulated_output = ""
+ self._pump_queues = pump_queues
def __enter__(self):
"""Support the python 'with' statement.
@@ -66,20 +92,6 @@ class SocketPacketPump(object):
Shut down the pump thread."""
self.stop_pump_thread()
- # Warn if there is any content left in any of the queues.
- # That would represent unmatched packets.
- if not self.output_queue().empty():
- print("warning: output queue entries still exist:")
- _dump_queue(self.output_queue())
- print("from here:")
- traceback.print_stack()
-
- if not self.packet_queue().empty():
- print("warning: packet queue entries still exist:")
- _dump_queue(self.packet_queue())
- print("from here:")
- traceback.print_stack()
-
def start_pump_thread(self):
if self._thread:
raise Exception("pump thread is already running")
@@ -92,12 +104,6 @@ class SocketPacketPump(object):
if self._thread:
self._thread.join()
- def output_queue(self):
- return self._output_queue
-
- def packet_queue(self):
- return self._packet_queue
-
def _process_new_bytes(self, new_bytes):
if not new_bytes:
return
@@ -114,7 +120,7 @@ class SocketPacketPump(object):
has_more = False
# handle '+' ack
elif self._receive_buffer[0] == "+":
- self._packet_queue.put("+")
+ self._pump_queues.packet_queue().put("+")
self._receive_buffer = self._receive_buffer[1:]
if self._logger:
self._logger.debug(
@@ -132,10 +138,10 @@ class SocketPacketPump(object):
if new_output_content:
# This was an $O packet with new content.
self._accumulated_output += new_output_content
- self._output_queue.put(self._accumulated_output)
+ self._pump_queues.output_queue().put(self._accumulated_output)
else:
# Any packet other than $O.
- self._packet_queue.put(packet_match.group(0))
+ self._pump_queues.packet_queue().put(packet_match.group(0))
# Remove the parsed packet from the receive
# buffer.
@@ -173,7 +179,7 @@ class SocketPacketPump(object):
# Likely a closed socket. Done with the pump thread.
if self._logger:
self._logger.debug(
- "socket read failed, stopping pump read thread")
+ "socket read failed, stopping pump read thread\n" + traceback.format_exc(3))
break
self._process_new_bytes(new_bytes)
diff --git a/packages/Python/lldbsuite/test/types/TestFloatTypes.py b/packages/Python/lldbsuite/test/types/TestFloatTypes.py
index 01fd4a267804..9fb555943b81 100644
--- a/packages/Python/lldbsuite/test/types/TestFloatTypes.py
+++ b/packages/Python/lldbsuite/test/types/TestFloatTypes.py
@@ -7,9 +7,12 @@ from __future__ import print_function
import AbstractBase
-import lldb
import sys
+
+import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class FloatTypesTestCase(AbstractBase.GenericTester):
diff --git a/packages/Python/lldbsuite/test/types/TestFloatTypesExpr.py b/packages/Python/lldbsuite/test/types/TestFloatTypesExpr.py
index a825a92c66cc..188033fffa33 100644
--- a/packages/Python/lldbsuite/test/types/TestFloatTypesExpr.py
+++ b/packages/Python/lldbsuite/test/types/TestFloatTypesExpr.py
@@ -5,11 +5,13 @@ Test that variable expressions of floating point types are evaluated correctly.
from __future__ import print_function
-
import AbstractBase
-import lldb
import sys
+
+import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class FloatTypesExprTestCase(AbstractBase.GenericTester):
diff --git a/packages/Python/lldbsuite/test/types/TestIntegerTypes.py b/packages/Python/lldbsuite/test/types/TestIntegerTypes.py
index 4b979df51db3..c1eab7183070 100644
--- a/packages/Python/lldbsuite/test/types/TestIntegerTypes.py
+++ b/packages/Python/lldbsuite/test/types/TestIntegerTypes.py
@@ -4,12 +4,13 @@ Test that variables of integer basic types are displayed correctly.
from __future__ import print_function
-
-
import AbstractBase
-import lldb
import sys
+
+import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class IntegerTypesTestCase(AbstractBase.GenericTester):
diff --git a/packages/Python/lldbsuite/test/types/TestIntegerTypesExpr.py b/packages/Python/lldbsuite/test/types/TestIntegerTypesExpr.py
index c6dda91ad13e..2c3edea7adac 100644
--- a/packages/Python/lldbsuite/test/types/TestIntegerTypesExpr.py
+++ b/packages/Python/lldbsuite/test/types/TestIntegerTypesExpr.py
@@ -5,11 +5,13 @@ Test that variable expressions of integer basic types are evaluated correctly.
from __future__ import print_function
-
import AbstractBase
-import lldb
import sys
+
+import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
class IntegerTypesExprTestCase(AbstractBase.GenericTester):
diff --git a/packages/Python/lldbsuite/test/warnings/uuid/TestAddDsymCommand.py b/packages/Python/lldbsuite/test/warnings/uuid/TestAddDsymCommand.py
index 002a7aef0c76..5010309e8944 100644
--- a/packages/Python/lldbsuite/test/warnings/uuid/TestAddDsymCommand.py
+++ b/packages/Python/lldbsuite/test/warnings/uuid/TestAddDsymCommand.py
@@ -6,7 +6,9 @@ from __future__ import print_function
import os, time
import lldb
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
@skipUnlessDarwin
class AddDsymCommandCase(TestBase):
diff --git a/packages/Python/lldbsuite/test_event/__init__.py b/packages/Python/lldbsuite/test_event/__init__.py
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/packages/Python/lldbsuite/test_event/__init__.py
diff --git a/packages/Python/lldbsuite/test_event/build_exception.py b/packages/Python/lldbsuite/test_event/build_exception.py
new file mode 100644
index 000000000000..4a7c5f4a9d38
--- /dev/null
+++ b/packages/Python/lldbsuite/test_event/build_exception.py
@@ -0,0 +1,14 @@
+class BuildError(Exception):
+ def __init__(self, called_process_error):
+ super(BuildError, self).__init__("Error when building test subject")
+ self.command = called_process_error.lldb_extensions.get("command", "<command unavailable>")
+ self.build_error = called_process_error.lldb_extensions.get("stderr_content", "<error output unavailable>")
+
+ def __str__(self):
+ return self.format_build_error(self.command, self.build_error)
+
+ @staticmethod
+ def format_build_error(command, command_output):
+ return "Error when building test subject.\n\nBuild Command:\n{}\n\nBuild Command Output:\n{}".format(
+ command,
+ command_output)
diff --git a/packages/Python/lldbsuite/test/dotest_channels.py b/packages/Python/lldbsuite/test_event/dotest_channels.py
index d2faf10c8929..d69720e4f66a 100644
--- a/packages/Python/lldbsuite/test/dotest_channels.py
+++ b/packages/Python/lldbsuite/test_event/dotest_channels.py
@@ -55,6 +55,13 @@ class UnpicklingForwardingReaderChannel(asyncore.dispatcher):
# unpickled results.
raise Exception("forwarding function must be set")
+ # Initiate all connections by sending an ack. This allows
+ # the initiators of the socket to await this to ensure
+ # that this end is up and running (and therefore already
+ # into the async map).
+ ack_bytes = b'*'
+ file_object.send(ack_bytes)
+
def deserialize_payload(self):
"""Unpickles the collected input buffer bytes and forwards."""
if len(self.ibuffer) > 0:
diff --git a/packages/Python/lldbsuite/test_event/event_builder.py b/packages/Python/lldbsuite/test_event/event_builder.py
new file mode 100644
index 000000000000..aabbd986bd70
--- /dev/null
+++ b/packages/Python/lldbsuite/test_event/event_builder.py
@@ -0,0 +1,475 @@
+"""
+ The LLVM Compiler Infrastructure
+
+This file is distributed under the University of Illinois Open Source
+License. See LICENSE.TXT for details.
+
+Provides a class to build Python test event data structures.
+"""
+
+from __future__ import print_function
+from __future__ import absolute_import
+
+# System modules
+import inspect
+import time
+import traceback
+
+# Third-party modules
+
+# LLDB modules
+from . import build_exception
+
+class EventBuilder(object):
+ """Helper class to build test result event dictionaries."""
+
+ BASE_DICTIONARY = None
+
+ # Test Event Types
+ TYPE_JOB_RESULT = "job_result"
+ TYPE_TEST_RESULT = "test_result"
+ TYPE_TEST_START = "test_start"
+ TYPE_MARK_TEST_RERUN_ELIGIBLE = "test_eligible_for_rerun"
+ TYPE_MARK_TEST_EXPECTED_FAILURE = "test_expected_failure"
+ TYPE_SESSION_TERMINATE = "terminate"
+
+ RESULT_TYPES = {TYPE_JOB_RESULT, TYPE_TEST_RESULT}
+
+ # Test/Job Status Tags
+ STATUS_EXCEPTIONAL_EXIT = "exceptional_exit"
+ STATUS_SUCCESS = "success"
+ STATUS_FAILURE = "failure"
+ STATUS_EXPECTED_FAILURE = "expected_failure"
+ STATUS_EXPECTED_TIMEOUT = "expected_timeout"
+ STATUS_UNEXPECTED_SUCCESS = "unexpected_success"
+ STATUS_SKIP = "skip"
+ STATUS_ERROR = "error"
+ STATUS_TIMEOUT = "timeout"
+
+ """Test methods or jobs with a status matching any of these
+ status values will cause a testrun failure, unless
+ the test methods rerun and do not trigger an issue when rerun."""
+ TESTRUN_ERROR_STATUS_VALUES = {
+ STATUS_ERROR,
+ STATUS_EXCEPTIONAL_EXIT,
+ STATUS_FAILURE,
+ STATUS_TIMEOUT}
+
+ @staticmethod
+ def _get_test_name_info(test):
+ """Returns (test-class-name, test-method-name) from a test case instance.
+
+ @param test a unittest.TestCase instance.
+
+ @return tuple containing (test class name, test method name)
+ """
+ test_class_components = test.id().split(".")
+ test_class_name = ".".join(test_class_components[:-1])
+ test_name = test_class_components[-1]
+ return test_class_name, test_name
+
+ @staticmethod
+ def bare_event(event_type):
+ """Creates an event with default additions, event type and timestamp.
+
+ @param event_type the value set for the "event" key, used
+ to distinguish events.
+
+ @returns an event dictionary with all default additions, the "event"
+ key set to the passed in event_type, and the event_time value set to
+ time.time().
+ """
+ if EventBuilder.BASE_DICTIONARY is not None:
+ # Start with a copy of the "always include" entries.
+ event = dict(EventBuilder.BASE_DICTIONARY)
+ else:
+ event = {}
+
+ event.update({
+ "event": event_type,
+ "event_time": time.time()
+ })
+ return event
+
+ @staticmethod
+ def _assert_is_python_sourcefile(test_filename):
+ if test_filename is not None:
+ if not test_filename.endswith(".py"):
+ raise Exception("source python filename has unexpected extension: {}".format(test_filename))
+ return test_filename
+
+ @staticmethod
+ def _event_dictionary_common(test, event_type):
+ """Returns an event dictionary setup with values for the given event type.
+
+ @param test the unittest.TestCase instance
+
+ @param event_type the name of the event type (string).
+
+ @return event dictionary with common event fields set.
+ """
+ test_class_name, test_name = EventBuilder._get_test_name_info(test)
+
+ # Determine the filename for the test case. If there is an attribute
+ # for it, use it. Otherwise, determine from the TestCase class path.
+ if hasattr(test, "test_filename"):
+ test_filename = EventBuilder._assert_is_python_sourcefile(test.test_filename)
+ else:
+ test_filename = EventBuilder._assert_is_python_sourcefile(inspect.getsourcefile(test.__class__))
+
+ event = EventBuilder.bare_event(event_type)
+ event.update({
+ "test_class": test_class_name,
+ "test_name": test_name,
+ "test_filename": test_filename
+ })
+
+ return event
+
+ @staticmethod
+ def _error_tuple_class(error_tuple):
+ """Returns the unittest error tuple's error class as a string.
+
+ @param error_tuple the error tuple provided by the test framework.
+
+ @return the error type (typically an exception) raised by the
+ test framework.
+ """
+ type_var = error_tuple[0]
+ module = inspect.getmodule(type_var)
+ if module:
+ return "{}.{}".format(module.__name__, type_var.__name__)
+ else:
+ return type_var.__name__
+
+ @staticmethod
+ def _error_tuple_message(error_tuple):
+ """Returns the unittest error tuple's error message.
+
+ @param error_tuple the error tuple provided by the test framework.
+
+ @return the error message provided by the test framework.
+ """
+ return str(error_tuple[1])
+
+ @staticmethod
+ def _error_tuple_traceback(error_tuple):
+ """Returns the unittest error tuple's error message.
+
+ @param error_tuple the error tuple provided by the test framework.
+
+ @return the error message provided by the test framework.
+ """
+ return error_tuple[2]
+
+ @staticmethod
+ def _event_dictionary_test_result(test, status):
+ """Returns an event dictionary with common test result fields set.
+
+ @param test a unittest.TestCase instance.
+
+ @param status the status/result of the test
+ (e.g. "success", "failure", etc.)
+
+ @return the event dictionary
+ """
+ event = EventBuilder._event_dictionary_common(
+ test, EventBuilder.TYPE_TEST_RESULT)
+ event["status"] = status
+ return event
+
+ @staticmethod
+ def _event_dictionary_issue(test, status, error_tuple):
+ """Returns an event dictionary with common issue-containing test result
+ fields set.
+
+ @param test a unittest.TestCase instance.
+
+ @param status the status/result of the test
+ (e.g. "success", "failure", etc.)
+
+ @param error_tuple the error tuple as reported by the test runner.
+ This is of the form (type<error>, error).
+
+ @return the event dictionary
+ """
+ event = EventBuilder._event_dictionary_test_result(test, status)
+ event["issue_class"] = EventBuilder._error_tuple_class(error_tuple)
+ event["issue_message"] = EventBuilder._error_tuple_message(error_tuple)
+ backtrace = EventBuilder._error_tuple_traceback(error_tuple)
+ if backtrace is not None:
+ event["issue_backtrace"] = traceback.format_tb(backtrace)
+ return event
+
+ @staticmethod
+ def event_for_start(test):
+ """Returns an event dictionary for the test start event.
+
+ @param test a unittest.TestCase instance.
+
+ @return the event dictionary
+ """
+ return EventBuilder._event_dictionary_common(
+ test, EventBuilder.TYPE_TEST_START)
+
+ @staticmethod
+ def event_for_success(test):
+ """Returns an event dictionary for a successful test.
+
+ @param test a unittest.TestCase instance.
+
+ @return the event dictionary
+ """
+ return EventBuilder._event_dictionary_test_result(
+ test, EventBuilder.STATUS_SUCCESS)
+
+ @staticmethod
+ def event_for_unexpected_success(test, bugnumber):
+ """Returns an event dictionary for a test that succeeded but was
+ expected to fail.
+
+ @param test a unittest.TestCase instance.
+
+ @param bugnumber the issue identifier for the bug tracking the
+ fix request for the test expected to fail (but is in fact
+ passing here).
+
+ @return the event dictionary
+
+ """
+ event = EventBuilder._event_dictionary_test_result(
+ test, EventBuilder.STATUS_UNEXPECTED_SUCCESS)
+ if bugnumber:
+ event["bugnumber"] = str(bugnumber)
+ return event
+
+ @staticmethod
+ def event_for_failure(test, error_tuple):
+ """Returns an event dictionary for a test that failed.
+
+ @param test a unittest.TestCase instance.
+
+ @param error_tuple the error tuple as reported by the test runner.
+ This is of the form (type<error>, error).
+
+ @return the event dictionary
+ """
+ return EventBuilder._event_dictionary_issue(
+ test, EventBuilder.STATUS_FAILURE, error_tuple)
+
+ @staticmethod
+ def event_for_expected_failure(test, error_tuple, bugnumber):
+ """Returns an event dictionary for a test that failed as expected.
+
+ @param test a unittest.TestCase instance.
+
+ @param error_tuple the error tuple as reported by the test runner.
+ This is of the form (type<error>, error).
+
+ @param bugnumber the issue identifier for the bug tracking the
+ fix request for the test expected to fail.
+
+ @return the event dictionary
+
+ """
+ event = EventBuilder._event_dictionary_issue(
+ test, EventBuilder.STATUS_EXPECTED_FAILURE, error_tuple)
+ if bugnumber:
+ event["bugnumber"] = str(bugnumber)
+ return event
+
+ @staticmethod
+ def event_for_skip(test, reason):
+ """Returns an event dictionary for a test that was skipped.
+
+ @param test a unittest.TestCase instance.
+
+ @param reason the reason why the test is being skipped.
+
+ @return the event dictionary
+ """
+ event = EventBuilder._event_dictionary_test_result(
+ test, EventBuilder.STATUS_SKIP)
+ event["skip_reason"] = reason
+ return event
+
+ @staticmethod
+ def event_for_error(test, error_tuple):
+ """Returns an event dictionary for a test that hit a test execution error.
+
+ @param test a unittest.TestCase instance.
+
+ @param error_tuple the error tuple as reported by the test runner.
+ This is of the form (type<error>, error).
+
+ @return the event dictionary
+ """
+ event = EventBuilder._event_dictionary_issue(
+ test, EventBuilder.STATUS_ERROR, error_tuple)
+ event["issue_phase"] = "test"
+ return event
+
+ @staticmethod
+ def event_for_build_error(test, error_tuple):
+ """Returns an event dictionary for a test that hit a test execution error
+ during the test cleanup phase.
+
+ @param test a unittest.TestCase instance.
+
+ @param error_tuple the error tuple as reported by the test runner.
+ This is of the form (type<error>, error).
+
+ @return the event dictionary
+ """
+ event = EventBuilder._event_dictionary_issue(
+ test, EventBuilder.STATUS_ERROR, error_tuple)
+ event["issue_phase"] = "build"
+
+ build_error = error_tuple[1]
+ event["build_command"] = build_error.command
+ event["build_error"] = build_error.build_error
+ return event
+
+ @staticmethod
+ def event_for_cleanup_error(test, error_tuple):
+ """Returns an event dictionary for a test that hit a test execution error
+ during the test cleanup phase.
+
+ @param test a unittest.TestCase instance.
+
+ @param error_tuple the error tuple as reported by the test runner.
+ This is of the form (type<error>, error).
+
+ @return the event dictionary
+ """
+ event = EventBuilder._event_dictionary_issue(
+ test, EventBuilder.STATUS_ERROR, error_tuple)
+ event["issue_phase"] = "cleanup"
+ return event
+
+ @staticmethod
+ def event_for_job_test_add_error(test_filename, exception, backtrace):
+ event = EventBuilder.bare_event(EventBuilder.TYPE_JOB_RESULT)
+ event["status"] = EventBuilder.STATUS_ERROR
+ if test_filename is not None:
+ event["test_filename"] = EventBuilder._assert_is_python_sourcefile(test_filename)
+ if exception is not None and "__class__" in dir(exception):
+ event["issue_class"] = exception.__class__
+ event["issue_message"] = exception
+ if backtrace is not None:
+ event["issue_backtrace"] = backtrace
+ return event
+
+ @staticmethod
+ def event_for_job_exceptional_exit(
+ pid, worker_index, exception_code, exception_description,
+ test_filename, command_line):
+ """Creates an event for a job (i.e. process) exit due to signal.
+
+ @param pid the process id for the job that failed
+ @param worker_index optional id for the job queue running the process
+ @param exception_code optional code
+ (e.g. SIGTERM integer signal number)
+ @param exception_description optional string containing symbolic
+ representation of the issue (e.g. "SIGTERM")
+ @param test_filename the path to the test filename that exited
+ in some exceptional way.
+ @param command_line the Popen()-style list provided as the command line
+ for the process that timed out.
+
+ @return an event dictionary coding the job completion description.
+ """
+ event = EventBuilder.bare_event(EventBuilder.TYPE_JOB_RESULT)
+ event["status"] = EventBuilder.STATUS_EXCEPTIONAL_EXIT
+ if pid is not None:
+ event["pid"] = pid
+ if worker_index is not None:
+ event["worker_index"] = int(worker_index)
+ if exception_code is not None:
+ event["exception_code"] = exception_code
+ if exception_description is not None:
+ event["exception_description"] = exception_description
+ if test_filename is not None:
+ event["test_filename"] = EventBuilder._assert_is_python_sourcefile(test_filename)
+ if command_line is not None:
+ event["command_line"] = command_line
+ return event
+
+ @staticmethod
+ def event_for_job_timeout(pid, worker_index, test_filename, command_line):
+ """Creates an event for a job (i.e. process) timeout.
+
+ @param pid the process id for the job that timed out
+ @param worker_index optional id for the job queue running the process
+ @param test_filename the path to the test filename that timed out.
+ @param command_line the Popen-style list provided as the command line
+ for the process that timed out.
+
+ @return an event dictionary coding the job completion description.
+ """
+ event = EventBuilder.bare_event(EventBuilder.TYPE_JOB_RESULT)
+ event["status"] = "timeout"
+ if pid is not None:
+ event["pid"] = pid
+ if worker_index is not None:
+ event["worker_index"] = int(worker_index)
+ if test_filename is not None:
+ event["test_filename"] = EventBuilder._assert_is_python_sourcefile(test_filename)
+ if command_line is not None:
+ event["command_line"] = command_line
+ return event
+
+ @staticmethod
+ def event_for_mark_test_rerun_eligible(test):
+ """Creates an event that indicates the specified test is explicitly
+ eligible for rerun.
+
+ Note there is a mode that will enable test rerun eligibility at the
+ global level. These markings for explicit rerun eligibility are
+ intended for the mode of running where only explicitly re-runnable
+ tests are rerun upon hitting an issue.
+
+ @param test the TestCase instance to which this pertains.
+
+ @return an event that specifies the given test as being eligible to
+ be rerun.
+ """
+ event = EventBuilder._event_dictionary_common(
+ test,
+ EventBuilder.TYPE_MARK_TEST_RERUN_ELIGIBLE)
+ return event
+
+ @staticmethod
+ def event_for_mark_test_expected_failure(test):
+ """Creates an event that indicates the specified test is expected
+ to fail.
+
+ @param test the TestCase instance to which this pertains.
+
+ @return an event that specifies the given test is expected to fail.
+ """
+ event = EventBuilder._event_dictionary_common(
+ test,
+ EventBuilder.TYPE_MARK_TEST_EXPECTED_FAILURE)
+ return event
+
+ @staticmethod
+ def add_entries_to_all_events(entries_dict):
+ """Specifies a dictionary of entries to add to all test events.
+
+ This provides a mechanism for, say, a parallel test runner to
+ indicate to each inferior dotest.py that it should add a
+ worker index to each.
+
+ Calling this method replaces all previous entries added
+ by a prior call to this.
+
+ Event build methods will overwrite any entries that collide.
+ Thus, the passed in dictionary is the base, which gets merged
+ over by event building when keys collide.
+
+ @param entries_dict a dictionary containing key and value
+ pairs that should be merged into all events created by the
+ event generator. May be None to clear out any extra entries.
+ """
+ EventBuilder.BASE_DICTIONARY = dict(entries_dict)
diff --git a/packages/Python/lldbsuite/test_event/formatter/__init__.py b/packages/Python/lldbsuite/test_event/formatter/__init__.py
new file mode 100644
index 000000000000..556370ebb9de
--- /dev/null
+++ b/packages/Python/lldbsuite/test_event/formatter/__init__.py
@@ -0,0 +1,162 @@
+"""
+ The LLVM Compiler Infrastructure
+
+This file is distributed under the University of Illinois Open Source
+License. See LICENSE.TXT for details.
+"""
+
+from __future__ import print_function
+from __future__ import absolute_import
+
+# System modules
+import importlib
+import socket
+import sys
+
+# Third-party modules
+
+# LLDB modules
+
+
+# Ignore method count on DTOs.
+# pylint: disable=too-few-public-methods
+class FormatterConfig(object):
+ """Provides formatter configuration info to create_results_formatter()."""
+
+ def __init__(self):
+ self.filename = None
+ self.port = None
+ self.formatter_name = None
+ self.formatter_options = None
+
+
+# Ignore method count on DTOs.
+# pylint: disable=too-few-public-methods
+class CreatedFormatter(object):
+ """Provides transfer object for returns from create_results_formatter()."""
+
+ def __init__(self, formatter, cleanup_func):
+ self.formatter = formatter
+ self.cleanup_func = cleanup_func
+
+
+def create_results_formatter(config):
+ """Sets up a test results formatter.
+
+ @param config an instance of FormatterConfig
+ that indicates how to setup the ResultsFormatter.
+
+ @return an instance of CreatedFormatter.
+ """
+
+ def create_socket(port):
+ """Creates a socket to the localhost on the given port.
+
+ @param port the port number of the listening port on
+ the localhost.
+
+ @return (socket object, socket closing function)
+ """
+
+ def socket_closer(open_sock):
+ """Close down an opened socket properly."""
+ open_sock.shutdown(socket.SHUT_RDWR)
+ open_sock.close()
+
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.connect(("localhost", port))
+
+ # Wait for the ack from the listener side.
+ # This is needed to prevent a race condition
+ # in the main dosep.py processing loop: we
+ # can't allow a worker queue thread to die
+ # that has outstanding messages to a listener
+ # socket before the listener socket asyncore
+ # listener socket gets spun up; otherwise,
+ # we lose the test result info.
+ read_bytes = sock.recv(1)
+ if read_bytes is None or (len(read_bytes) < 1) or (read_bytes != b'*'):
+ raise Exception("listening socket did not respond with ack byte: response={}".format(read_bytes))
+
+ return sock, lambda: socket_closer(sock)
+
+ default_formatter_name = None
+ results_file_object = None
+ cleanup_func = None
+
+ file_is_stream = False
+ if config.filename:
+ # Open the results file for writing.
+ if config.filename == 'stdout':
+ results_file_object = sys.stdout
+ cleanup_func = None
+ elif config.filename == 'stderr':
+ results_file_object = sys.stderr
+ cleanup_func = None
+ else:
+ results_file_object = open(config.filename, "w")
+ cleanup_func = results_file_object.close
+ default_formatter_name = (
+ "lldbsuite.test_event.formatter.xunit.XunitFormatter")
+ elif config.port:
+ # Connect to the specified localhost port.
+ results_file_object, cleanup_func = create_socket(config.port)
+ default_formatter_name = (
+ "lldbsuite.test_event.formatter.pickled.RawPickledFormatter")
+ file_is_stream = True
+
+ # If we have a results formatter name specified and we didn't specify
+ # a results file, we should use stdout.
+ if config.formatter_name is not None and results_file_object is None:
+ # Use stdout.
+ results_file_object = sys.stdout
+ cleanup_func = None
+
+ if results_file_object:
+ # We care about the formatter. Choose user-specified or, if
+ # none specified, use the default for the output type.
+ if config.formatter_name:
+ formatter_name = config.formatter_name
+ else:
+ formatter_name = default_formatter_name
+
+ # Create an instance of the class.
+ # First figure out the package/module.
+ components = formatter_name.split(".")
+ module = importlib.import_module(".".join(components[:-1]))
+
+ # Create the class name we need to load.
+ cls = getattr(module, components[-1])
+
+ # Handle formatter options for the results formatter class.
+ formatter_arg_parser = cls.arg_parser()
+ if config.formatter_options and len(config.formatter_options) > 0:
+ command_line_options = config.formatter_options
+ else:
+ command_line_options = []
+
+ formatter_options = formatter_arg_parser.parse_args(
+ command_line_options)
+
+ # Create the TestResultsFormatter given the processed options.
+ results_formatter_object = cls(
+ results_file_object,
+ formatter_options,
+ file_is_stream)
+
+ def shutdown_formatter():
+ """Shuts down the formatter when it is no longer needed."""
+ # Tell the formatter to write out anything it may have
+ # been saving until the very end (e.g. xUnit results
+ # can't complete its output until this point).
+ results_formatter_object.send_terminate_as_needed()
+
+ # And now close out the output file-like object.
+ if cleanup_func is not None:
+ cleanup_func()
+
+ return CreatedFormatter(
+ results_formatter_object,
+ shutdown_formatter)
+ else:
+ return None
diff --git a/packages/Python/lldbsuite/test/curses_results.py b/packages/Python/lldbsuite/test_event/formatter/curses.py
index 9d480b946ea2..4e89fa9bf01e 100644
--- a/packages/Python/lldbsuite/test/curses_results.py
+++ b/packages/Python/lldbsuite/test_event/formatter/curses.py
@@ -1,16 +1,12 @@
-#!/usr/bin/env python
-
"""
The LLVM Compiler Infrastructure
This file is distributed under the University of Illinois Open Source
License. See LICENSE.TXT for details.
-
-Configuration options for lldbtest.py set by dotest.py during initialization
"""
-from __future__ import print_function
from __future__ import absolute_import
+from __future__ import print_function
# System modules
import curses
@@ -22,17 +18,18 @@ import time
# Third-party modules
# LLDB modules
-from . import lldbcurses
-from . import result_formatter
-from .result_formatter import EventBuilder
+from lldbsuite.test import lldbcurses
+
+from . import results_formatter
+from ..event_builder import EventBuilder
-class Curses(result_formatter.ResultsFormatter):
+class Curses(results_formatter.ResultsFormatter):
"""Receives live results from tests that are running and reports them to the terminal in a curses GUI"""
- def __init__(self, out_file, options):
+ def __init__(self, out_file, options, file_is_stream):
# Initialize the parent
- super(Curses, self).__init__(out_file, options)
+ super(Curses, self).__init__(out_file, options, file_is_stream)
self.using_terminal = True
self.have_curses = True
self.initialize_event = None
@@ -62,7 +59,7 @@ class Curses(result_formatter.ResultsFormatter):
# if tee_results_formatter:
# self.formatters.append(tee_results_formatter)
- def status_to_short_str(self, status):
+ def status_to_short_str(self, status, test_event):
if status == EventBuilder.STATUS_SUCCESS:
return '.'
elif status == EventBuilder.STATUS_FAILURE:
@@ -74,7 +71,15 @@ class Curses(result_formatter.ResultsFormatter):
elif status == EventBuilder.STATUS_SKIP:
return 'S'
elif status == EventBuilder.STATUS_ERROR:
- return 'E'
+ if test_event.get("issue_phase", None) == "build":
+ # Build failure
+ return 'B'
+ else:
+ return 'E'
+ elif status == EventBuilder.STATUS_TIMEOUT:
+ return 'T'
+ elif status == EventBuilder.STATUS_EXPECTED_TIMEOUT:
+ return 't'
else:
return status
@@ -122,7 +127,7 @@ class Curses(result_formatter.ResultsFormatter):
if status in self.hide_status_list:
continue
name = test_result['test_class'] + '.' + test_result['test_name']
- self.results_panel.append_line('%s (%6.2f sec) %s' % (self.status_to_short_str(status), test_result['elapsed_time'], name))
+ self.results_panel.append_line('%s (%6.2f sec) %s' % (self.status_to_short_str(status, test_result), test_result['elapsed_time'], name))
if update:
self.main_window.refresh()
@@ -161,7 +166,7 @@ class Curses(result_formatter.ResultsFormatter):
name = test_event['test_class'] + '.' + test_event['test_name']
elapsed_time = test_event['event_time'] - self.job_tests[worker_index]['event_time']
if not status in self.hide_status_list:
- self.results_panel.append_line('%s (%6.2f sec) %s' % (self.status_to_short_str(status), elapsed_time, name))
+ self.results_panel.append_line('%s (%6.2f sec) %s' % (self.status_to_short_str(status, test_event), elapsed_time, name))
self.main_window.refresh()
# Append the result pairs
test_event['elapsed_time'] = elapsed_time
diff --git a/packages/Python/lldbsuite/test_event/formatter/dump_formatter.py b/packages/Python/lldbsuite/test_event/formatter/dump_formatter.py
new file mode 100644
index 000000000000..d42dcb18bb4f
--- /dev/null
+++ b/packages/Python/lldbsuite/test_event/formatter/dump_formatter.py
@@ -0,0 +1,23 @@
+"""
+ The LLVM Compiler Infrastructure
+
+This file is distributed under the University of Illinois Open Source
+License. See LICENSE.TXT for details.
+"""
+
+from __future__ import print_function
+from __future__ import absolute_import
+
+# System modules
+import pprint
+
+# Our modules
+from .results_formatter import ResultsFormatter
+
+
+class DumpFormatter(ResultsFormatter):
+ """Formats events to the file as their raw python dictionary format."""
+
+ def handle_event(self, test_event):
+ super(DumpFormatter, self).handle_event(test_event)
+ self.out_file.write("\n" + pprint.pformat(test_event) + "\n")
diff --git a/packages/Python/lldbsuite/test_event/formatter/pickled.py b/packages/Python/lldbsuite/test_event/formatter/pickled.py
new file mode 100644
index 000000000000..6d800f6c8baa
--- /dev/null
+++ b/packages/Python/lldbsuite/test_event/formatter/pickled.py
@@ -0,0 +1,72 @@
+"""
+ The LLVM Compiler Infrastructure
+
+This file is distributed under the University of Illinois Open Source
+License. See LICENSE.TXT for details.
+"""
+
+from __future__ import print_function
+from __future__ import absolute_import
+
+# System modules
+import os
+
+# Our modules
+from .results_formatter import ResultsFormatter
+from six.moves import cPickle
+
+
+class RawPickledFormatter(ResultsFormatter):
+ """Formats events as a pickled stream.
+
+ The parallel test runner has inferiors pickle their results and send them
+ over a socket back to the parallel test. The parallel test runner then
+ aggregates them into the final results formatter (e.g. xUnit).
+ """
+
+ @classmethod
+ def arg_parser(cls):
+ """@return arg parser used to parse formatter-specific options."""
+ parser = super(RawPickledFormatter, cls).arg_parser()
+ return parser
+
+ class StreamSerializer(object):
+ @staticmethod
+ def serialize(test_event, out_file):
+ # Send it as {serialized_length_of_serialized_bytes}{serialized_bytes}
+ import struct
+ msg = cPickle.dumps(test_event)
+ packet = struct.pack("!I%ds" % len(msg), len(msg), msg)
+ out_file.send(packet)
+
+ class BlockSerializer(object):
+ @staticmethod
+ def serialize(test_event, out_file):
+ cPickle.dump(test_event, out_file)
+
+ def __init__(self, out_file, options, file_is_stream):
+ super(RawPickledFormatter, self).__init__(out_file, options, file_is_stream)
+ self.pid = os.getpid()
+ if file_is_stream:
+ self.serializer = self.StreamSerializer()
+ else:
+ self.serializer = self.BlockSerializer()
+
+ def handle_event(self, test_event):
+ super(RawPickledFormatter, self).handle_event(test_event)
+
+ # Convert initialize/terminate events into job_begin/job_end events.
+ event_type = test_event["event"]
+ if event_type is None:
+ return
+
+ if event_type == "initialize":
+ test_event["event"] = "job_begin"
+ elif event_type == "terminate":
+ test_event["event"] = "job_end"
+
+ # Tack on the pid.
+ test_event["pid"] = self.pid
+
+ # Serialize the test event.
+ self.serializer.serialize(test_event, self.out_file)
diff --git a/packages/Python/lldbsuite/test/result_formatter.py b/packages/Python/lldbsuite/test_event/formatter/results_formatter.py
index 44474918895e..3bf389b97266 100644
--- a/packages/Python/lldbsuite/test/result_formatter.py
+++ b/packages/Python/lldbsuite/test_event/formatter/results_formatter.py
@@ -13,568 +13,24 @@ from __future__ import absolute_import
# System modules
import argparse
-import importlib
-import inspect
import os
-import pprint
-import socket
import sys
import threading
-import time
-import traceback
# Third-party modules
-import six
-from six.moves import cPickle
+
# LLDB modules
-from . import configuration
+from lldbsuite.test import configuration
+from ..event_builder import EventBuilder
import lldbsuite
-# Ignore method count on DTOs.
-# pylint: disable=too-few-public-methods
-class FormatterConfig(object):
- """Provides formatter configuration info to create_results_formatter()."""
- def __init__(self):
- self.filename = None
- self.port = None
- self.formatter_name = None
- self.formatter_options = None
-
-
-# Ignore method count on DTOs.
-# pylint: disable=too-few-public-methods
-class CreatedFormatter(object):
- """Provides transfer object for returns from create_results_formatter()."""
- def __init__(self, formatter, cleanup_func):
- self.formatter = formatter
- self.cleanup_func = cleanup_func
-
-
-def create_results_formatter(config):
- """Sets up a test results formatter.
-
- @param config an instance of FormatterConfig
- that indicates how to setup the ResultsFormatter.
-
- @return an instance of CreatedFormatter.
- """
- def create_socket(port):
- """Creates a socket to the localhost on the given port.
-
- @param port the port number of the listenering port on
- the localhost.
-
- @return (socket object, socket closing function)
- """
- def socket_closer(open_sock):
- """Close down an opened socket properly."""
- open_sock.shutdown(socket.SHUT_RDWR)
- open_sock.close()
-
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.connect(("localhost", port))
- return (sock, lambda: socket_closer(sock))
-
- default_formatter_name = None
- results_file_object = None
- cleanup_func = None
-
- if config.filename:
- # Open the results file for writing.
- if config.filename == 'stdout':
- results_file_object = sys.stdout
- cleanup_func = None
- elif config.filename == 'stderr':
- results_file_object = sys.stderr
- cleanup_func = None
- else:
- results_file_object = open(config.filename, "w")
- cleanup_func = results_file_object.close
- default_formatter_name = (
- "lldbsuite.test.xunit_formatter.XunitFormatter")
- elif config.port:
- # Connect to the specified localhost port.
- results_file_object, cleanup_func = create_socket(config.port)
- default_formatter_name = (
- "lldbsuite.test.result_formatter.RawPickledFormatter")
-
- # If we have a results formatter name specified and we didn't specify
- # a results file, we should use stdout.
- if config.formatter_name is not None and results_file_object is None:
- # Use stdout.
- results_file_object = sys.stdout
- cleanup_func = None
-
- if results_file_object:
- # We care about the formatter. Choose user-specified or, if
- # none specified, use the default for the output type.
- if config.formatter_name:
- formatter_name = config.formatter_name
- else:
- formatter_name = default_formatter_name
-
- # Create an instance of the class.
- # First figure out the package/module.
- components = formatter_name.split(".")
- module = importlib.import_module(".".join(components[:-1]))
-
- # Create the class name we need to load.
- cls = getattr(module, components[-1])
-
- # Handle formatter options for the results formatter class.
- formatter_arg_parser = cls.arg_parser()
- if config.formatter_options and len(config.formatter_options) > 0:
- command_line_options = config.formatter_options
- else:
- command_line_options = []
-
- formatter_options = formatter_arg_parser.parse_args(
- command_line_options)
-
- # Create the TestResultsFormatter given the processed options.
- results_formatter_object = cls(results_file_object, formatter_options)
-
- def shutdown_formatter():
- """Shuts down the formatter when it is no longer needed."""
- # Tell the formatter to write out anything it may have
- # been saving until the very end (e.g. xUnit results
- # can't complete its output until this point).
- results_formatter_object.send_terminate_as_needed()
-
- # And now close out the output file-like object.
- if cleanup_func is not None:
- cleanup_func()
-
- return CreatedFormatter(
- results_formatter_object,
- shutdown_formatter)
- else:
- return None
-
-
-class EventBuilder(object):
- """Helper class to build test result event dictionaries."""
-
- BASE_DICTIONARY = None
-
- # Test Event Types
- TYPE_JOB_RESULT = "job_result"
- TYPE_TEST_RESULT = "test_result"
- TYPE_TEST_START = "test_start"
- TYPE_MARK_TEST_RERUN_ELIGIBLE = "test_eligible_for_rerun"
- TYPE_MARK_TEST_EXPECTED_FAILURE = "test_expected_failure"
- TYPE_SESSION_TERMINATE = "terminate"
-
- RESULT_TYPES = set([
- TYPE_JOB_RESULT,
- TYPE_TEST_RESULT
- ])
-
- # Test/Job Status Tags
- STATUS_EXCEPTIONAL_EXIT = "exceptional_exit"
- STATUS_SUCCESS = "success"
- STATUS_FAILURE = "failure"
- STATUS_EXPECTED_FAILURE = "expected_failure"
- STATUS_EXPECTED_TIMEOUT = "expected_timeout"
- STATUS_UNEXPECTED_SUCCESS = "unexpected_success"
- STATUS_SKIP = "skip"
- STATUS_ERROR = "error"
- STATUS_TIMEOUT = "timeout"
-
- """Test methods or jobs with a status matching any of these
- status values will cause a testrun failure, unless
- the test methods rerun and do not trigger an issue when rerun."""
- TESTRUN_ERROR_STATUS_VALUES = set([
- STATUS_ERROR,
- STATUS_EXCEPTIONAL_EXIT,
- STATUS_FAILURE,
- STATUS_TIMEOUT
- ])
-
- @staticmethod
- def _get_test_name_info(test):
- """Returns (test-class-name, test-method-name) from a test case instance.
-
- @param test a unittest.TestCase instance.
-
- @return tuple containing (test class name, test method name)
- """
- test_class_components = test.id().split(".")
- test_class_name = ".".join(test_class_components[:-1])
- test_name = test_class_components[-1]
- return (test_class_name, test_name)
-
- @staticmethod
- def bare_event(event_type):
- """Creates an event with default additions, event type and timestamp.
-
- @param event_type the value set for the "event" key, used
- to distinguish events.
-
- @returns an event dictionary with all default additions, the "event"
- key set to the passed in event_type, and the event_time value set to
- time.time().
- """
- if EventBuilder.BASE_DICTIONARY is not None:
- # Start with a copy of the "always include" entries.
- event = dict(EventBuilder.BASE_DICTIONARY)
- else:
- event = {}
-
- event.update({
- "event": event_type,
- "event_time": time.time()
- })
- return event
-
- @staticmethod
- def _event_dictionary_common(test, event_type):
- """Returns an event dictionary setup with values for the given event type.
-
- @param test the unittest.TestCase instance
-
- @param event_type the name of the event type (string).
-
- @return event dictionary with common event fields set.
- """
- test_class_name, test_name = EventBuilder._get_test_name_info(test)
-
- # Determine the filename for the test case. If there is an attribute
- # for it, use it. Otherwise, determine from the TestCase class path.
- if hasattr(test, "test_filename"):
- test_filename = test.test_filename
- else:
- test_filename = inspect.getfile(test.__class__)
-
- event = EventBuilder.bare_event(event_type)
- event.update({
- "test_class": test_class_name,
- "test_name": test_name,
- "test_filename": test_filename
- })
-
- return event
-
- @staticmethod
- def _error_tuple_class(error_tuple):
- """Returns the unittest error tuple's error class as a string.
-
- @param error_tuple the error tuple provided by the test framework.
-
- @return the error type (typically an exception) raised by the
- test framework.
- """
- type_var = error_tuple[0]
- module = inspect.getmodule(type_var)
- if module:
- return "{}.{}".format(module.__name__, type_var.__name__)
- else:
- return type_var.__name__
-
- @staticmethod
- def _error_tuple_message(error_tuple):
- """Returns the unittest error tuple's error message.
-
- @param error_tuple the error tuple provided by the test framework.
-
- @return the error message provided by the test framework.
- """
- return str(error_tuple[1])
-
- @staticmethod
- def _error_tuple_traceback(error_tuple):
- """Returns the unittest error tuple's error message.
-
- @param error_tuple the error tuple provided by the test framework.
-
- @return the error message provided by the test framework.
- """
- return error_tuple[2]
-
- @staticmethod
- def _event_dictionary_test_result(test, status):
- """Returns an event dictionary with common test result fields set.
-
- @param test a unittest.TestCase instance.
-
- @param status the status/result of the test
- (e.g. "success", "failure", etc.)
-
- @return the event dictionary
- """
- event = EventBuilder._event_dictionary_common(
- test, EventBuilder.TYPE_TEST_RESULT)
- event["status"] = status
- return event
-
- @staticmethod
- def _event_dictionary_issue(test, status, error_tuple):
- """Returns an event dictionary with common issue-containing test result
- fields set.
-
- @param test a unittest.TestCase instance.
-
- @param status the status/result of the test
- (e.g. "success", "failure", etc.)
-
- @param error_tuple the error tuple as reported by the test runner.
- This is of the form (type<error>, error).
-
- @return the event dictionary
- """
- event = EventBuilder._event_dictionary_test_result(test, status)
- event["issue_class"] = EventBuilder._error_tuple_class(error_tuple)
- event["issue_message"] = EventBuilder._error_tuple_message(error_tuple)
- backtrace = EventBuilder._error_tuple_traceback(error_tuple)
- if backtrace is not None:
- event["issue_backtrace"] = traceback.format_tb(backtrace)
- return event
-
- @staticmethod
- def event_for_start(test):
- """Returns an event dictionary for the test start event.
-
- @param test a unittest.TestCase instance.
-
- @return the event dictionary
- """
- return EventBuilder._event_dictionary_common(
- test, EventBuilder.TYPE_TEST_START)
-
- @staticmethod
- def event_for_success(test):
- """Returns an event dictionary for a successful test.
-
- @param test a unittest.TestCase instance.
-
- @return the event dictionary
- """
- return EventBuilder._event_dictionary_test_result(
- test, EventBuilder.STATUS_SUCCESS)
-
- @staticmethod
- def event_for_unexpected_success(test, bugnumber):
- """Returns an event dictionary for a test that succeeded but was
- expected to fail.
-
- @param test a unittest.TestCase instance.
-
- @param bugnumber the issue identifier for the bug tracking the
- fix request for the test expected to fail (but is in fact
- passing here).
-
- @return the event dictionary
-
- """
- event = EventBuilder._event_dictionary_test_result(
- test, EventBuilder.STATUS_UNEXPECTED_SUCCESS)
- if bugnumber:
- event["bugnumber"] = str(bugnumber)
- return event
-
- @staticmethod
- def event_for_failure(test, error_tuple):
- """Returns an event dictionary for a test that failed.
-
- @param test a unittest.TestCase instance.
-
- @param error_tuple the error tuple as reported by the test runner.
- This is of the form (type<error>, error).
-
- @return the event dictionary
- """
- return EventBuilder._event_dictionary_issue(
- test, EventBuilder.STATUS_FAILURE, error_tuple)
-
- @staticmethod
- def event_for_expected_failure(test, error_tuple, bugnumber):
- """Returns an event dictionary for a test that failed as expected.
-
- @param test a unittest.TestCase instance.
-
- @param error_tuple the error tuple as reported by the test runner.
- This is of the form (type<error>, error).
-
- @param bugnumber the issue identifier for the bug tracking the
- fix request for the test expected to fail.
-
- @return the event dictionary
-
- """
- event = EventBuilder._event_dictionary_issue(
- test, EventBuilder.STATUS_EXPECTED_FAILURE, error_tuple)
- if bugnumber:
- event["bugnumber"] = str(bugnumber)
- return event
-
- @staticmethod
- def event_for_skip(test, reason):
- """Returns an event dictionary for a test that was skipped.
-
- @param test a unittest.TestCase instance.
-
- @param reason the reason why the test is being skipped.
-
- @return the event dictionary
- """
- event = EventBuilder._event_dictionary_test_result(
- test, EventBuilder.STATUS_SKIP)
- event["skip_reason"] = reason
- return event
-
- @staticmethod
- def event_for_error(test, error_tuple):
- """Returns an event dictionary for a test that hit a test execution error.
-
- @param test a unittest.TestCase instance.
-
- @param error_tuple the error tuple as reported by the test runner.
- This is of the form (type<error>, error).
-
- @return the event dictionary
- """
- return EventBuilder._event_dictionary_issue(
- test, EventBuilder.STATUS_ERROR, error_tuple)
-
- @staticmethod
- def event_for_cleanup_error(test, error_tuple):
- """Returns an event dictionary for a test that hit a test execution error
- during the test cleanup phase.
-
- @param test a unittest.TestCase instance.
-
- @param error_tuple the error tuple as reported by the test runner.
- This is of the form (type<error>, error).
-
- @return the event dictionary
- """
- event = EventBuilder._event_dictionary_issue(
- test, EventBuilder.STATUS_ERROR, error_tuple)
- event["issue_phase"] = "cleanup"
- return event
-
- @staticmethod
- def event_for_job_exceptional_exit(
- pid, worker_index, exception_code, exception_description,
- test_filename, command_line):
- """Creates an event for a job (i.e. process) exit due to signal.
-
- @param pid the process id for the job that failed
- @param worker_index optional id for the job queue running the process
- @param exception_code optional code
- (e.g. SIGTERM integer signal number)
- @param exception_description optional string containing symbolic
- representation of the issue (e.g. "SIGTERM")
- @param test_filename the path to the test filename that exited
- in some exceptional way.
- @param command_line the Popen-style list provided as the command line
- for the process that timed out.
-
- @return an event dictionary coding the job completion description.
- """
- event = EventBuilder.bare_event(EventBuilder.TYPE_JOB_RESULT)
- event["status"] = EventBuilder.STATUS_EXCEPTIONAL_EXIT
- if pid is not None:
- event["pid"] = pid
- if worker_index is not None:
- event["worker_index"] = int(worker_index)
- if exception_code is not None:
- event["exception_code"] = exception_code
- if exception_description is not None:
- event["exception_description"] = exception_description
- if test_filename is not None:
- event["test_filename"] = test_filename
- if command_line is not None:
- event["command_line"] = command_line
- return event
-
- @staticmethod
- def event_for_job_timeout(pid, worker_index, test_filename, command_line):
- """Creates an event for a job (i.e. process) timeout.
-
- @param pid the process id for the job that timed out
- @param worker_index optional id for the job queue running the process
- @param test_filename the path to the test filename that timed out.
- @param command_line the Popen-style list provided as the command line
- for the process that timed out.
-
- @return an event dictionary coding the job completion description.
- """
- event = EventBuilder.bare_event(EventBuilder.TYPE_JOB_RESULT)
- event["status"] = "timeout"
- if pid is not None:
- event["pid"] = pid
- if worker_index is not None:
- event["worker_index"] = int(worker_index)
- if test_filename is not None:
- event["test_filename"] = test_filename
- if command_line is not None:
- event["command_line"] = command_line
- return event
-
- @staticmethod
- def event_for_mark_test_rerun_eligible(test):
- """Creates an event that indicates the specified test is explicitly
- eligible for rerun.
-
- Note there is a mode that will enable test rerun eligibility at the
- global level. These markings for explicit rerun eligibility are
- intended for the mode of running where only explicitly rerunnable
- tests are rerun upon hitting an issue.
-
- @param test the TestCase instance to which this pertains.
-
- @return an event that specifies the given test as being eligible to
- be rerun.
- """
- event = EventBuilder._event_dictionary_common(
- test,
- EventBuilder.TYPE_MARK_TEST_RERUN_ELIGIBLE)
- return event
-
- @staticmethod
- def event_for_mark_test_expected_failure(test):
- """Creates an event that indicates the specified test is expected
- to fail.
-
- @param test the TestCase instance to which this pertains.
-
- @return an event that specifies the given test is expected to fail.
- """
- event = EventBuilder._event_dictionary_common(
- test,
- EventBuilder.TYPE_MARK_TEST_EXPECTED_FAILURE)
- return event
-
- @staticmethod
- def add_entries_to_all_events(entries_dict):
- """Specifies a dictionary of entries to add to all test events.
-
- This provides a mechanism for, say, a parallel test runner to
- indicate to each inferior dotest.py that it should add a
- worker index to each.
-
- Calling this method replaces all previous entries added
- by a prior call to this.
-
- Event build methods will overwrite any entries that collide.
- Thus, the passed in dictionary is the base, which gets merged
- over by event building when keys collide.
-
- @param entries_dict a dictionary containing key and value
- pairs that should be merged into all events created by the
- event generator. May be None to clear out any extra entries.
- """
- EventBuilder.BASE_DICTIONARY = dict(entries_dict)
-
-
class ResultsFormatter(object):
"""Provides interface to formatting test results out to a file-like object.
- This class allows the LLDB test framework's raw test-realted
+ This class allows the LLDB test framework's raw test-related
events to be processed and formatted in any manner desired.
Test events are represented by python dictionaries, formatted
as in the EventBuilder class above.
@@ -590,7 +46,7 @@ class ResultsFormatter(object):
# passed to dotest.py via the "--results-formatter-options"
# argument. See the help on that for syntactic requirements
# on getting that parsed correctly.
- formatter = SomeResultFormatter(file_like_object, argpared_options_dict)
+ formatter = SomeResultFormatter(file_like_object, argparse_options_dict)
# Single call to session start, before parsing any events.
formatter.begin_session()
@@ -606,7 +62,7 @@ class ResultsFormatter(object):
for event in zero_or_more_test_events():
formatter.handle_event(event)
- # Single call to terminate/wrap-up. Formatters that need all the
+ # Single call to terminate/wrap-up. For formatters that need all the
# data before they can print a correct result (e.g. xUnit/JUnit),
# this is where the final report can be generated.
formatter.handle_event({"event":"terminate",...})
@@ -655,7 +111,7 @@ class ResultsFormatter(object):
'the summary output.'))
return parser
- def __init__(self, out_file, options):
+ def __init__(self, out_file, options, file_is_stream):
super(ResultsFormatter, self).__init__()
self.out_file = out_file
self.options = options
@@ -664,6 +120,7 @@ class ResultsFormatter(object):
raise Exception("ResultsFormatter created with no file object")
self.start_time_by_test = {}
self.terminate_called = False
+ self.file_is_stream = file_is_stream
# Store counts of test_result events by status.
self.result_status_counts = {
@@ -736,6 +193,8 @@ class ResultsFormatter(object):
if "test_filename" in result_event:
key = result_event["test_filename"]
component_count += 1
+ else:
+ key = "<no_filename>"
if "test_class" in result_event:
if component_count > 0:
key += ":"
@@ -991,6 +450,7 @@ class ResultsFormatter(object):
# Derived classes may require self access
# pylint: disable=no-self-use
+ # noinspection PyMethodMayBeStatic,PyMethodMayBeStatic
def replaces_summary(self):
"""Returns whether the results formatter includes a summary
suitable to replace the old lldb test run results.
@@ -1051,7 +511,8 @@ class ResultsFormatter(object):
key=lambda x: self._event_sort_key(x[1]))
return partitioned_events
- def _print_banner(self, out_file, banner_text):
+ @staticmethod
+ def _print_banner(out_file, banner_text):
"""Prints an ASCII banner around given text.
Output goes to the out file for the results formatter.
@@ -1142,7 +603,8 @@ class ResultsFormatter(object):
# details.
return False
- def _report_category_details(self, out_file, category, result_events_by_status):
+ @staticmethod
+ def _report_category_details(out_file, category, result_events_by_status):
"""Reports all test results matching the given category spec.
@param out_file a file-like object used to print output.
@@ -1247,58 +709,9 @@ class ResultsFormatter(object):
if self.options.dump_results:
# Debug dump of the key/result info for all categories.
- self._print_banner("Results Dump")
+ self._print_banner(out_file, "Results Dump")
for status, events_by_key in result_events_by_status.items():
out_file.write("\nSTATUS: {}\n".format(status))
for key, event in events_by_key:
out_file.write("key: {}\n".format(key))
out_file.write("event: {}\n".format(event))
-
-
-class RawPickledFormatter(ResultsFormatter):
- """Formats events as a pickled stream.
-
- The parallel test runner has inferiors pickle their results and send them
- over a socket back to the parallel test. The parallel test runner then
- aggregates them into the final results formatter (e.g. xUnit).
- """
-
- @classmethod
- def arg_parser(cls):
- """@return arg parser used to parse formatter-specific options."""
- parser = super(RawPickledFormatter, cls).arg_parser()
- return parser
-
- def __init__(self, out_file, options):
- super(RawPickledFormatter, self).__init__(out_file, options)
- self.pid = os.getpid()
-
- def handle_event(self, test_event):
- super(RawPickledFormatter, self).handle_event(test_event)
-
- # Convert initialize/terminate events into job_begin/job_end events.
- event_type = test_event["event"]
- if event_type is None:
- return
-
- if event_type == "initialize":
- test_event["event"] = "job_begin"
- elif event_type == "terminate":
- test_event["event"] = "job_end"
-
- # Tack on the pid.
- test_event["pid"] = self.pid
-
- # Send it as {serialized_length_of_serialized_bytes}{serialized_bytes}
- import struct
- msg = cPickle.dumps(test_event)
- packet = struct.pack("!I%ds" % len(msg), len(msg), msg)
- self.out_file.send(packet)
-
-
-class DumpFormatter(ResultsFormatter):
- """Formats events to the file as their raw python dictionary format."""
-
- def handle_event(self, test_event):
- super(DumpFormatter, self).handle_event(test_event)
- self.out_file.write("\n" + pprint.pformat(test_event) + "\n")
diff --git a/packages/Python/lldbsuite/test/xunit_formatter.py b/packages/Python/lldbsuite/test_event/formatter/xunit.py
index 35fdba449a0c..b3682f8fb107 100644
--- a/packages/Python/lldbsuite/test/xunit_formatter.py
+++ b/packages/Python/lldbsuite/test_event/formatter/xunit.py
@@ -8,8 +8,8 @@ Provides an xUnit ResultsFormatter for integrating the LLDB
test suite with the Jenkins xUnit aggregator and other xUnit-compliant
test output processors.
"""
-from __future__ import print_function
from __future__ import absolute_import
+from __future__ import print_function
# System modules
import re
@@ -20,8 +20,9 @@ import xml.sax.saxutils
import six
# Local modules
-from .result_formatter import EventBuilder
-from .result_formatter import ResultsFormatter
+from ..event_builder import EventBuilder
+from ..build_exception import BuildError
+from .results_formatter import ResultsFormatter
class XunitFormatter(ResultsFormatter):
@@ -36,10 +37,10 @@ class XunitFormatter(ResultsFormatter):
@staticmethod
def _build_illegal_xml_regex():
- """Contructs a regex to match all illegal xml characters.
+ """Constructs a regex to match all illegal xml characters.
Expects to be used against a unicode string."""
- # Construct the range pairs of invalid unicode chareacters.
+ # Construct the range pairs of invalid unicode characters.
illegal_chars_u = [
(0x00, 0x08), (0x0B, 0x0C), (0x0E, 0x1F), (0x7F, 0x84),
(0x86, 0x9F), (0xFDD0, 0xFDDF), (0xFFFE, 0xFFFF)]
@@ -139,10 +140,10 @@ class XunitFormatter(ResultsFormatter):
@staticmethod
def _build_regex_list_from_patterns(patterns):
- """Builds a list of compiled regexes from option value.
+ """Builds a list of compiled regular expressions from option value.
- @param option string containing a comma-separated list of regex
- patterns. Zero-length or None will produce an empty regex list.
+ @param patterns contains a list of regular expression
+ patterns.
@return list of compiled regular expressions, empty if no
patterns provided.
@@ -153,14 +154,14 @@ class XunitFormatter(ResultsFormatter):
regex_list.append(re.compile(pattern))
return regex_list
- def __init__(self, out_file, options):
+ def __init__(self, out_file, options, file_is_stream):
"""Initializes the XunitFormatter instance.
@param out_file file-like object where formatted output is written.
- @param options_dict specifies a dictionary of options for the
+ @param options specifies a dictionary of options for the
formatter.
"""
# Initialize the parent
- super(XunitFormatter, self).__init__(out_file, options)
+ super(XunitFormatter, self).__init__(out_file, options, file_is_stream)
self.text_encoding = "UTF-8"
self.invalid_xml_re = XunitFormatter._build_illegal_xml_regex()
self.total_test_count = 0
@@ -198,9 +199,7 @@ class XunitFormatter(ResultsFormatter):
self._handle_timeout
}
- RESULT_TYPES = set(
- [EventBuilder.TYPE_TEST_RESULT,
- EventBuilder.TYPE_JOB_RESULT])
+ RESULT_TYPES = {EventBuilder.TYPE_TEST_RESULT, EventBuilder.TYPE_JOB_RESULT}
def handle_event(self, test_event):
super(XunitFormatter, self).handle_event(test_event)
@@ -248,7 +247,28 @@ class XunitFormatter(ResultsFormatter):
with self.lock:
self.elements["failures"].append(result)
- def _handle_error(self, test_event):
+ def _handle_error_build(self, test_event):
+ """Handles a test error.
+ @param test_event the test event to handle.
+ """
+ message = self._replace_invalid_xml(test_event["issue_message"])
+ build_issue_description = self._replace_invalid_xml(
+ BuildError.format_build_error(
+ test_event.get("build_command", "<None>"),
+ test_event.get("build_error", "<None>")))
+
+ result = self._common_add_testcase_entry(
+ test_event,
+ inner_content=(
+ '<error type={} message={}><![CDATA[{}]]></error>'.format(
+ XunitFormatter._quote_attribute(test_event["issue_class"]),
+ XunitFormatter._quote_attribute(message),
+ build_issue_description)
+ ))
+ with self.lock:
+ self.elements["errors"].append(result)
+
+ def _handle_error_standard(self, test_event):
"""Handles a test error.
@param test_event the test event to handle.
"""
@@ -267,6 +287,12 @@ class XunitFormatter(ResultsFormatter):
with self.lock:
self.elements["errors"].append(result)
+ def _handle_error(self, test_event):
+ if test_event.get("issue_phase", None) == "build":
+ self._handle_error_build(test_event)
+ else:
+ self._handle_error_standard(test_event)
+
def _handle_exceptional_exit(self, test_event):
"""Handles an exceptional exit.
@param test_event the test method or job result event to handle.
@@ -401,7 +427,8 @@ class XunitFormatter(ResultsFormatter):
raise Exception(
"unknown xfail option: {}".format(self.options.xfail))
- def _handle_expected_timeout(self, test_event):
+ @staticmethod
+ def _handle_expected_timeout(test_event):
"""Handles expected_timeout.
@param test_event the test event to handle.
"""
@@ -418,7 +445,7 @@ class XunitFormatter(ResultsFormatter):
# test results viewer.
result = self._common_add_testcase_entry(
test_event,
- inner_content=("<unexpected-success />"))
+ inner_content="<unexpected-success />")
with self.lock:
self.elements["unexpected_successes"].append(result)
elif self.options.xpass == XunitFormatter.RM_SUCCESS:
@@ -484,8 +511,8 @@ class XunitFormatter(ResultsFormatter):
"""
# Get elapsed time.
- test_class = test_event["test_class"]
- test_name = test_event["test_name"]
+ test_class = test_event.get("test_class", "<no_class>")
+ test_name = test_event.get("test_name", "<no_test_method>")
event_time = test_event["event_time"]
time_taken = self.elapsed_time_for_test(
test_class, test_name, event_time)
@@ -519,7 +546,7 @@ class XunitFormatter(ResultsFormatter):
xUnit output is in XML. The reporting system cannot complete the
formatting of the output without knowing when there is no more input.
- This call addresses notifcation of the completed test run and thus is
+ This call addresses notification of the completed test run and thus is
when we can finish off the report output.
"""
diff --git a/packages/Python/lldbsuite/test_event/test/resources/invalid_decorator/TestInvalidDecorator.py b/packages/Python/lldbsuite/test_event/test/resources/invalid_decorator/TestInvalidDecorator.py
new file mode 100644
index 000000000000..7f5c4cb79cf5
--- /dev/null
+++ b/packages/Python/lldbsuite/test_event/test/resources/invalid_decorator/TestInvalidDecorator.py
@@ -0,0 +1,13 @@
+from __future__ import print_function
+from lldbsuite.test import lldbtest
+from lldbsuite.test import decorators
+
+
+class NonExistentDecoratorTestCase(lldbtest.TestBase):
+
+ mydir = lldbtest.TestBase.compute_mydir(__file__)
+
+ @decorators.nonExistentDecorator(bugnumber="yt/1300")
+ def test(self):
+ """Verify non-existent decorators are picked up by test runner."""
+ pass
diff --git a/packages/Python/lldbsuite/test_event/test/src/TestCatchInvalidDecorator.py b/packages/Python/lldbsuite/test_event/test/src/TestCatchInvalidDecorator.py
new file mode 100644
index 000000000000..56814416c333
--- /dev/null
+++ b/packages/Python/lldbsuite/test_event/test/src/TestCatchInvalidDecorator.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+"""
+Tests that the event system reports issues during decorator
+handling as errors.
+"""
+# System-provided imports
+import os
+import unittest
+
+# Local-provided imports
+import event_collector
+
+
+class TestCatchInvalidDecorator(unittest.TestCase):
+
+ TEST_DIR = os.path.join(
+ os.path.dirname(__file__),
+ os.path.pardir,
+ "resources",
+ "invalid_decorator")
+
+ def test_with_whole_file(self):
+ """
+ Test that a non-existent decorator generates a test-event error
+ when running all tests in the file.
+ """
+ # Determine the test case file we're using.
+ test_file = os.path.join(self.TEST_DIR, "TestInvalidDecorator.py")
+
+ # Collect all test events generated for this file.
+ error_results = _filter_error_results(
+ event_collector.collect_events_whole_file(test_file))
+
+ self.assertGreater(
+ len(error_results),
+ 0,
+ "At least one job or test error result should have been returned")
+
+ def test_with_function_filter(self):
+ """
+ Test that a non-existent decorator generates a test-event error
+ when running a filtered test.
+ """
+ # Collect all test events generated during running of tests
+ # in a given directory using a test name filter. Internally,
+ # this runs through a different code path that needs to be
+ # set up to catch exceptions.
+ error_results = _filter_error_results(
+ event_collector.collect_events_for_directory_with_filter(
+ self.TEST_DIR,
+ "NonExistentDecoratorTestCase.test"))
+
+ self.assertGreater(
+ len(error_results),
+ 0,
+ "At least one job or test error result should have been returned")
+
+
+def _filter_error_results(events):
+ # Filter out job result events.
+ return [
+ event
+ for event in events
+ if event.get("event", None) in ["job_result", "test_result"] and
+ event.get("status", None) == "error"
+ ]
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/packages/Python/lldbsuite/test_event/test/src/event_collector.py b/packages/Python/lldbsuite/test_event/test/src/event_collector.py
new file mode 100644
index 000000000000..35d132066898
--- /dev/null
+++ b/packages/Python/lldbsuite/test_event/test/src/event_collector.py
@@ -0,0 +1,85 @@
+from __future__ import absolute_import
+from __future__ import print_function
+
+import os
+import subprocess
+import sys
+import tempfile
+
+# noinspection PyUnresolvedReferences
+from six.moves import cPickle
+
+
+def path_to_dotest_py():
+ return os.path.join(
+ os.path.dirname(__file__),
+ os.path.pardir,
+ os.path.pardir,
+ os.path.pardir,
+ os.path.pardir,
+ os.path.pardir,
+ os.path.pardir,
+ "test",
+ "dotest.py")
+
+
+def _make_pickled_events_filename():
+ with tempfile.NamedTemporaryFile(
+ prefix="lldb_test_event_pickled_event_output",
+ delete=False) as temp_file:
+ return temp_file.name
+
+
+def _collect_events_with_command(command, events_filename):
+ # Run the single test with dotest.py, outputting
+ # the raw pickled events to a temp file.
+ with open(os.devnull, 'w') as dev_null_file:
+ subprocess.call(
+ command,
+ stdout=dev_null_file,
+ stderr=dev_null_file)
+
+ # Unpickle the events
+ events = []
+ if os.path.exists(events_filename):
+ with open(events_filename, "rb") as events_file:
+ while True:
+ try:
+ # print("reading event")
+ event = cPickle.load(events_file)
+ # print("read event: {}".format(event))
+ if event:
+ events.append(event)
+ except EOFError:
+ # This is okay.
+ break
+ os.remove(events_filename)
+ return events
+
+
+def collect_events_whole_file(test_filename):
+ events_filename = _make_pickled_events_filename()
+ command = [
+ sys.executable,
+ path_to_dotest_py(),
+ "--inferior",
+ "--results-formatter=lldbsuite.test_event.formatter.pickled.RawPickledFormatter",
+ "--results-file={}".format(events_filename),
+ "-p", os.path.basename(test_filename),
+ os.path.dirname(test_filename)
+ ]
+ return _collect_events_with_command(command, events_filename)
+
+
+def collect_events_for_directory_with_filter(test_filename, filter_desc):
+ events_filename = _make_pickled_events_filename()
+ command = [
+ sys.executable,
+ path_to_dotest_py(),
+ "--inferior",
+ "--results-formatter=lldbsuite.test_event.formatter.pickled.RawPickledFormatter",
+ "--results-file={}".format(events_filename),
+ "-f", filter_desc,
+ os.path.dirname(test_filename)
+ ]
+ return _collect_events_with_command(command, events_filename)
diff --git a/resources/LLDB-Info.plist b/resources/LLDB-Info.plist
index 57e5a51fd797..4a8bcaa96a7b 100644
--- a/resources/LLDB-Info.plist
+++ b/resources/LLDB-Info.plist
@@ -17,7 +17,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>350.99.0</string>
+ <string>360.99.0</string>
<key>CFBundleName</key>
<string>${EXECUTABLE_NAME}</string>
</dict>
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index 00bec0b2dae5..35b453aa1f10 100644
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -9,6 +9,8 @@ set(SWIG_HEADERS
${LLDB_SOURCE_DIR}/include/lldb/lldb-versioning.h
)
+include(FindPythonInterp)
+
find_package(SWIG REQUIRED)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp
diff --git a/scripts/Makefile b/scripts/Makefile
deleted file mode 100644
index 807823f43e44..000000000000
--- a/scripts/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-##===- scripts/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
-
-ifeq (,$(findstring -DLLDB_DISABLE_PYTHON,$(CXXFLAGS)))
-DIRS := Python
-endif
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/scripts/Python/Makefile b/scripts/Python/Makefile
deleted file mode 100644
index ad6c0af442b4..000000000000
--- a/scripts/Python/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- scripts/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 := ../..
-include $(LLDB_LEVEL)/../../Makefile.config
-
-DIRS := modules
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/scripts/Python/finishSwigPythonLLDB.py b/scripts/Python/finishSwigPythonLLDB.py
index 435cb88c20f0..4d733a164361 100644
--- a/scripts/Python/finishSwigPythonLLDB.py
+++ b/scripts/Python/finishSwigPythonLLDB.py
@@ -229,6 +229,23 @@ def make_symlink_windows(vstrSrcPath, vstrTargetPath):
dbg = utilsDebug.CDebugFnVerbose("Python script make_symlink_windows()")
bOk = True
strErrMsg = ""
+ # If the src file doesn't exist, this is an error and we should throw.
+ src_stat = os.stat(vstrSrcPath)
+
+ try:
+ target_stat = os.stat(vstrTargetPath)
+ # If the target file exists but refers to a different file, delete it so that we can
+ # re-create the link. This can happen if you run this script once (creating a link)
+ # and then delete the source file (so that a brand new file gets created the next time
+ # you compile and link), and then re-run this script, so that both the target hardlink
+ # and the source file exist, but the target refers to an old copy of the source.
+ if (target_stat.st_ino == src_stat.st_ino) and (target_stat.st_dev == src_stat.st_dev):
+ return (bOk, strErrMsg)
+
+ os.remove(vstrTargetPath)
+ except:
+ # If the target file don't exist, ignore this exception, we will link it shortly.
+ pass
try:
csl = ctypes.windll.kernel32.CreateHardLinkW
@@ -280,10 +297,6 @@ def make_symlink_native(vDictArgs, strSrc, strTarget):
bOk = False
strErrMsg = strErrMsgOsTypeUnknown
elif eOSType == utilsOsType.EnumOsType.Windows:
- if os.path.isfile(strTarget):
- if bDbg:
- print((strMsgSymlinkExists % target_filename))
- return (bOk, strErrMsg)
if bDbg:
print((strMsgSymlinkMk % (target_filename, strSrc, strTarget)))
bOk, strErrMsg = make_symlink_windows(strSrc,
@@ -345,11 +358,12 @@ def make_symlink(vDictArgs, vstrFrameworkPythonDir, vstrSrcFile, vstrTargetFile)
# Args: vDictArgs - (R) Program input parameters.
# vstrFrameworkPythonDir - (R) Python framework directory.
# vstrLiblldbName - (R) File name for _lldb library.
+# vstrLiblldbDir - (R) liblldb directory.
# Returns: Bool - True = function success, False = failure.
# Str - Error description on task failure.
# Throws: None.
#--
-def make_symlink_liblldb(vDictArgs, vstrFrameworkPythonDir, vstrLiblldbFileName):
+def make_symlink_liblldb(vDictArgs, vstrFrameworkPythonDir, vstrLiblldbFileName, vstrLldbLibDir):
dbg = utilsDebug.CDebugFnVerbose("Python script make_symlink_liblldb()")
bOk = True
strErrMsg = ""
@@ -369,7 +383,7 @@ def make_symlink_liblldb(vDictArgs, vstrFrameworkPythonDir, vstrLiblldbFileName)
bMakeFileCalled = "-m" in vDictArgs
if not bMakeFileCalled:
- strSrc = os.path.join("lib", "LLDB")
+ strSrc = os.path.join(vstrLldbLibDir, "LLDB")
else:
strLibFileExtn = ""
if eOSType == utilsOsType.EnumOsType.Windows:
@@ -379,7 +393,7 @@ def make_symlink_liblldb(vDictArgs, vstrFrameworkPythonDir, vstrLiblldbFileName)
strLibFileExtn = ".dylib"
else:
strLibFileExtn = ".so"
- strSrc = os.path.join("lib", "liblldb" + strLibFileExtn)
+ strSrc = os.path.join(vstrLldbLibDir, "liblldb" + strLibFileExtn)
bOk, strErrMsg = make_symlink(vDictArgs, vstrFrameworkPythonDir, strSrc, strTarget)
@@ -449,11 +463,12 @@ def make_symlink_lldb_argdumper(vDictArgs, vstrFrameworkPythonDir, vstrArgdumper
# the Python framework directory.
# Args: vDictArgs - (R) Program input parameters.
# vstrFrameworkPythonDir - (R) Python framework directory.
+# vstrLldbLibDir - (R) liblldb directory.
# Returns: Bool - True = function success, False = failure.
# strErrMsg - Error description on task failure.
# Throws: None.
#--
-def create_symlinks(vDictArgs, vstrFrameworkPythonDir):
+def create_symlinks(vDictArgs, vstrFrameworkPythonDir, vstrLldbLibDir):
dbg = utilsDebug.CDebugFnVerbose("Python script create_symlinks()")
bOk = True
strErrMsg = ""
@@ -464,7 +479,8 @@ def create_symlinks(vDictArgs, vstrFrameworkPythonDir):
if bOk:
bOk, strErrMsg = make_symlink_liblldb(vDictArgs,
vstrFrameworkPythonDir,
- strLibLldbFileName)
+ strLibLldbFileName,
+ vstrLldbLibDir)
# Make symlink for darwin-debug on Darwin
strDarwinDebugFileName = "darwin-debug"
@@ -659,6 +675,28 @@ def get_framework_python_dir(vDictArgs):
return (bOk, strWkDir, strErrMsg)
+#++---------------------------------------------------------------------------
+# Details: Retrieve the liblldb directory path, if it exists and is valid.
+# Args: vDictArgs - (R) Program input parameters.
+# Returns: Bool - True = function success, False = failure.
+# Str - liblldb directory path.
+# strErrMsg - Error description on task failure.
+# Throws: None.
+#--
+def get_liblldb_dir(vDictArgs):
+ dbg = utilsDebug.CDebugFnVerbose("Python script get_liblldb_dir()")
+ bOk = True
+ strErrMsg = ""
+
+ strLldbLibDir = ""
+ bHaveLldbLibDir = "--lldbLibDir" in vDictArgs
+ if bHaveLldbLibDir:
+ strLldbLibDir = vDictArgs["--lldbLibDir"]
+ if (bHaveLldbLibDir == False) or (strLldbLibDir.__len__() == 0):
+ strLldbLibDir = "lib"
+
+ return (bOk, strLldbLibDir, strErrMsg)
+
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@@ -684,6 +722,8 @@ def get_framework_python_dir(vDictArgs):
be installed. Where non-Darwin systems want to put
the .py and .so files so that Python can find them
automatically. Python install directory.
+ --lldbLibDir The name of the directory containing liblldb.so.
+ (optional) "lib" by default.
Results: 0 Success
-100+ Error from this script to the caller script.
-100 Error program failure with optional message.
@@ -714,10 +754,13 @@ def main(vDictArgs):
print((strMsgConfigBuildDir % strCfgBldDir))
if bOk:
+ bOk, strLldbLibDir, strMsg = get_liblldb_dir(vDictArgs)
+
+ if bOk:
bOk, strMsg = find_or_create_python_dir(vDictArgs, strFrameworkPythonDir)
if bOk:
- bOk, strMsg = create_symlinks(vDictArgs, strFrameworkPythonDir)
+ bOk, strMsg = create_symlinks(vDictArgs, strFrameworkPythonDir, strLldbLibDir)
if bOk:
bOk, strMsg = copy_six(vDictArgs, strFrameworkPythonDir)
diff --git a/scripts/Python/modules/Makefile b/scripts/Python/modules/Makefile
deleted file mode 100644
index b6989889858d..000000000000
--- a/scripts/Python/modules/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-##===- scripts/Python/modules/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
-
-DIRS:=
-
-# only build the readline suppression module on Linux, Kfreebsd & Hurd
-ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux GNU GNU/kFreeBSD))
-DIRS += readline
-endif
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/scripts/Python/modules/readline/Makefile b/scripts/Python/modules/readline/Makefile
deleted file mode 100644
index dc0d757bc175..000000000000
--- a/scripts/Python/modules/readline/Makefile
+++ /dev/null
@@ -1,100 +0,0 @@
-##===- scripts/Python/modules/readline/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-# Skip this entire Makefile if python is disabled.
-ifeq (,$(findstring -DLLDB_DISABLE_PYTHON,$(CXXFLAGS)))
-
-LEVEL := ../../../../../..
-LLDB_LEVEL := ../../../..
-
-LIBRARYNAME = readline
-
-NO_BUILD_ARCHIVE = 1
-LINK_LIBS_IN_SHARED = 1
-SHARED_LIBRARY = 1
-LOADABLE_MODULE = 1
-
-PYTHON_CONFIG?= python-config
-PYTHON_INC_DIR = $(shell $(PYTHON_CONFIG) --includes)
-
-# Include all archives in the shared lib
-USEDLIBS :=
-
-include $(LLDB_LEVEL)/../../Makefile.config
-
-LINK_COMPONENTS :=
-
-include $(LEVEL)/Makefile.common
-
-# include python headers
-CPP.Flags += $(PYTHON_INC_DIR)
-
-ifeq ($(HOST_OS),Darwin)
- LLVMLibsOptions += -Wl,-all_load
- # set dylib internal version number to llvmCore submission number
- ifdef LLDB_SUBMIT_VERSION
- LLVMLibsOptions += -Wl,-current_version \
- -Wl,$(LLDB_SUBMIT_VERSION).$(LLDB_SUBMIT_SUBVERSION) \
- -Wl,-compatibility_version -Wl,1
- endif
- # extra options to override libtool defaults
- LVMLibsOptions += -F/System/Library/Frameworks -F/System/Library/PrivateFrameworks
- LLVMLibsOptions += -framework Foundation -framework CoreFoundation
- LLVMLibsOptions += -framework CoreServices -framework Carbon -framework Security
- LLVMLibsOptions += -framework DebugSymbols $(PYTHON_BUILD_FLAGS) -lobjc
- # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line
- DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/')
- ifneq ($(DARWIN_VERS),8)
- LLVMLibsOptions += -Wl,-install_name \
- -Wl,"@executable_path/../lib/$(LIBRARYNAME)$(SHLIBEXT)"
- endif
-endif
-
-ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux GNU GNU/kFreeBSD))
- # Include everything from the .a's into the shared library.
- ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \
- -Wl,--no-whole-archive
- # Link in libedit
- # LLVMLibsOptions += -ledit
- LLVMLibsOptions += -Wl,--soname,$(LIBRARYNAME)$(SHLIBEXT)
-endif
-
-ifeq ($(HOST_OS),FreeBSD)
- # Include everything from the .a's into the shared library.
- ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \
- -Wl,--no-whole-archive
- # Allow unresolved symbols.
- LLVMLibsOptions += -Wl,--allow-shlib-undefined
- # Link in libedit
- # LLVMLibsOptions += -L/usr/local/lib -ledit
-endif
-
-# FIXME: dynamically construct the version from `python -V`
-PYTHON_VERSION:=2.7
-LLDB_PYTHON_MODULE_REL_DIR:=python$(PYTHON_VERSION)/site-packages
-LLDB_PYTHON_MODULE_DIR:=$(LibDir)/$(LLDB_PYTHON_MODULE_REL_DIR)
-
-# Target to move readline module from shared lib build location to
-# local python module directory.
-all-local:: $(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT)
-
-$(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT): $(SharedLibDir)/$(LIBRARYNAME)$(SHLIBEXT)
- $(Echo) Staging $(BuildMode) $(LIBRARYNAME)$(SHLIBEXT) to $(LLDB_PYTHON_MODULE_DIR)
- $(Verb) $(MKDIR) "$(LLDB_PYTHON_MODULE_DIR)"
- $(Verb) $(ProgInstall) $(SharedLibDir)/$(LIBRARYNAME)$(SHLIBEXT) $(LLDB_PYTHON_MODULE_DIR)
-
-# Target to move the shared library from the build python lib dir to
-# the install python lib dir.
-install-local:: $(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT)
- $(Echo) Installing $(BuildMode) $(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT) to $(DESTDIR)$(prefix)/lib/$(LLDB_PYTHON_MODULE_REL_DIR)
- $(Verb) $(MKDIR) "$(DESTDIR)$(prefix)/lib/$(LLDB_PYTHON_MODULE_REL_DIR)"
- $(Verb) $(ProgInstall) "$(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT)" "$(DESTDIR)$(prefix)/lib/$(LLDB_PYTHON_MODULE_REL_DIR)"
- $(Verb) $(RM) "$(DESTDIR)$(prefix)/lib/$(LIBRARYNAME)$(SHLIBEXT)"
-
-endif # if !defined(LLDB_DISABLE_PYTHON)
diff --git a/scripts/Python/modules/readline/readline.cpp b/scripts/Python/modules/readline/readline.cpp
index d66ccf4b6b7d..d4b4962cc313 100644
--- a/scripts/Python/modules/readline/readline.cpp
+++ b/scripts/Python/modules/readline/readline.cpp
@@ -20,11 +20,6 @@
// work around LLVM pr18841 to avoid seg faults in the stock Python
// readline.so linked against GNU readline.
-static struct PyMethodDef moduleMethods[] =
-{
- {nullptr, nullptr, 0, nullptr}
-};
-
#ifndef LLDB_DISABLE_LIBEDIT
PyDoc_STRVAR(
moduleDocumentation,
@@ -35,9 +30,33 @@ PyDoc_STRVAR(
"Stub module meant to avoid linking GNU readline.");
#endif
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef readline_module =
+{
+ PyModuleDef_HEAD_INIT, // m_base
+ "readline", // m_name
+ moduleDocumentation, // m_doc
+ -1, // m_size
+ nullptr, // m_methods
+ nullptr, // m_reload
+ nullptr, // m_traverse
+ nullptr, // m_clear
+ nullptr, // m_free
+};
+#else
+static struct PyMethodDef moduleMethods[] =
+{
+ {nullptr, nullptr, 0, nullptr}
+};
+#endif
+
#ifndef LLDB_DISABLE_LIBEDIT
static char*
+#if PY_MAJOR_VERSION >= 3
+simple_readline(FILE *stdin, FILE *stdout, const char *prompt)
+#else
simple_readline(FILE *stdin, FILE *stdout, char *prompt)
+#endif
{
rl_instream = stdin;
rl_outstream = stdout;
@@ -67,10 +86,15 @@ initreadline(void)
#ifndef LLDB_DISABLE_LIBEDIT
PyOS_ReadlineFunctionPointer = simple_readline;
#endif
+
+#if PY_MAJOR_VERSION >= 3
+ return PyModule_Create(&readline_module);
+#else
Py_InitModule4(
"readline",
moduleMethods,
moduleDocumentation,
static_cast<PyObject *>(NULL),
PYTHON_API_VERSION);
+#endif
}
diff --git a/scripts/Python/prepare_binding_Python.py b/scripts/Python/prepare_binding_Python.py
index 1996841baf18..28fc3e5bc7fc 100644
--- a/scripts/Python/prepare_binding_Python.py
+++ b/scripts/Python/prepare_binding_Python.py
@@ -16,7 +16,7 @@ import re
import shutil
import subprocess
import sys
-
+import platform
class SwigSettings(object):
"""Provides a single object to represent swig files and settings."""
@@ -205,6 +205,8 @@ def do_swig_rebuild(options, dependency_file, config_build_dir, settings):
"-I\"%s\"" % os.path.normcase("./."),
"-D__STDC_LIMIT_MACROS",
"-D__STDC_CONSTANT_MACROS"]
+ if options.target_platform == "Darwin":
+ command.append("-D__APPLE__")
if options.generate_dependency_file:
command.append("-MMD -MF \"%s\"" % temp_dep_file_path)
command.extend([
diff --git a/scripts/Python/python-extensions.swig b/scripts/Python/python-extensions.swig
index fae7f401bf13..693b06b9aab3 100644
--- a/scripts/Python/python-extensions.swig
+++ b/scripts/Python/python-extensions.swig
@@ -325,6 +325,22 @@
return getattr(_lldb,self.__class__.__name__+"___ne__")(self, rhs)
%}
}
+
+%extend lldb::SBMemoryRegionInfo {
+ PyObject *lldb::SBMemoryRegionInfo::__str__ (){
+ lldb::SBStream description;
+ $self->GetDescription (description);
+ const char *desc = description.GetData();
+ size_t desc_len = description.GetSize();
+ if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
+ --desc_len;
+ if (desc_len > 0)
+ return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
+ else
+ return lldb_private::PythonString("").release();
+ }
+}
+
%extend lldb::SBModule {
PyObject *lldb::SBModule::__str__ (){
lldb::SBStream description;
@@ -810,6 +826,7 @@
def command(*args, **kwargs):
import lldb
+ import inspect
"""A decorator function that registers an LLDB command line
command that is bound to the function it is attached to."""
class obj(object):
@@ -821,11 +838,15 @@ def command(*args, **kwargs):
command = "command script add -f %s.%s %s" % (function.__module__, function.__name__, command_name)
lldb.debugger.HandleCommand(command)
self.function = function
- def __call__(self, *args, **kwargs):
- self.function(*args, **kwargs)
+ def __call__(self, debugger, command, exe_ctx, result, dict):
+ if len(inspect.getargspec(self.function).args) == 5:
+ self.function(debugger, command, exe_ctx, result, dict)
+ else:
+ self.function(debugger, command, result, dict)
def callable(function):
"""Creates a callable object that gets used."""
- return obj(function, *args, **kwargs)
+ f = obj(function, *args, **kwargs)
+ return f.__call__
return callable
class declaration(object):
@@ -1024,11 +1045,13 @@ class value(object):
return complex (int(self))
def __int__(self):
+ is_num,is_sign = is_numeric_type(self.sbvalue.GetType().GetCanonicalType().GetBasicType())
+ if is_num and not is_sign: return self.sbvalue.GetValueAsUnsigned()
return self.sbvalue.GetValueAsSigned()
-
+
def __long__(self):
- return self.sbvalue.GetValueAsSigned()
-
+ return self.__int__()
+
def __float__(self):
return float (self.sbvalue.GetValueAsSigned())
@@ -1084,4 +1107,47 @@ class SBSyntheticValueProvider(object):
return False
-%} \ No newline at end of file
+%}
+
+%pythoncode %{
+
+# given an lldb.SBBasicType it returns a tuple
+# (is_numeric, is_signed)
+# the value of is_signed is undefined if is_numeric == false
+def is_numeric_type(basic_type):
+ if basic_type == eBasicTypeInvalid: return (False,False)
+ if basic_type == eBasicTypeVoid: return (False,False)
+ if basic_type == eBasicTypeChar: return (True,False)
+ if basic_type == eBasicTypeSignedChar: return (True,True)
+ if basic_type == eBasicTypeUnsignedChar: return (True,False)
+ if basic_type == eBasicTypeWChar: return (True,False)
+ if basic_type == eBasicTypeSignedWChar: return (True,True)
+ if basic_type == eBasicTypeUnsignedWChar: return (True,False)
+ if basic_type == eBasicTypeChar16: return (True,False)
+ if basic_type == eBasicTypeChar32: return (True,False)
+ if basic_type == eBasicTypeShort: return (True,True)
+ if basic_type == eBasicTypeUnsignedShort: return (True,False)
+ if basic_type == eBasicTypeInt: return (True,True)
+ if basic_type == eBasicTypeUnsignedInt: return (True,False)
+ if basic_type == eBasicTypeLong: return (True,True)
+ if basic_type == eBasicTypeUnsignedLong: return (True,False)
+ if basic_type == eBasicTypeLongLong: return (True,True)
+ if basic_type == eBasicTypeUnsignedLongLong: return (True,False)
+ if basic_type == eBasicTypeInt128: return (True,True)
+ if basic_type == eBasicTypeUnsignedInt128: return (True,False)
+ if basic_type == eBasicTypeBool: return (False,False)
+ if basic_type == eBasicTypeHalf: return (True,True)
+ if basic_type == eBasicTypeFloat: return (True,True)
+ if basic_type == eBasicTypeDouble: return (True,True)
+ if basic_type == eBasicTypeLongDouble: return (True,True)
+ if basic_type == eBasicTypeFloatComplex: return (True,True)
+ if basic_type == eBasicTypeDoubleComplex: return (True,True)
+ if basic_type == eBasicTypeLongDoubleComplex: return (True,True)
+ if basic_type == eBasicTypeObjCID: return (False,False)
+ if basic_type == eBasicTypeObjCClass: return (False,False)
+ if basic_type == eBasicTypeObjCSel: return (False,False)
+ if basic_type == eBasicTypeNullPtr: return (False,False)
+ #if basic_type == eBasicTypeOther:
+ return (False,False)
+
+%}
diff --git a/scripts/Python/python-typemaps.swig b/scripts/Python/python-typemaps.swig
index 9c4e5cecb363..df16a6d27b3b 100644
--- a/scripts/Python/python-typemaps.swig
+++ b/scripts/Python/python-typemaps.swig
@@ -1,20 +1,22 @@
/* Typemap definitions, to allow SWIG to properly handle 'char**' data types. */
%typemap(in) char ** {
+ using namespace lldb_private;
/* Check if is a list */
- if (PyList_Check($input)) {
- int size = PyList_Size($input);
+ if (PythonList::Check($input)) {
+ PythonList list(PyRefType::Borrowed, $input);
+ int size = list.GetSize();
int i = 0;
- $1 = (char **) malloc((size+1) * sizeof(char*));
+ $1 = (char**)malloc((size+1)*sizeof(char*));
for (i = 0; i < size; i++) {
- PyObject *o = PyList_GetItem($input,i);
- if (PyString_Check(o))
- $1[i] = PyString_AsString(o);
- else {
+ PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>();
+ if (!py_str.IsAllocated()) {
PyErr_SetString(PyExc_TypeError,"list must contain strings");
free($1);
- return NULL;
+ return nullptr;
}
+
+ $1[i] = const_cast<char*>(py_str.GetString().data());
}
$1[i] = 0;
} else if ($input == Py_None) {
@@ -25,29 +27,17 @@
}
}
-%typemap(in) lldb::tid_t {
- using namespace lldb_private;
- if (PythonInteger::Check($input))
- {
- PythonInteger py_int(PyRefType::Borrowed, $input);
- $1 = static_cast<lldb::tid_t>(py_int.GetInteger());
- }
- else
- {
- PyErr_SetString(PyExc_ValueError, "Expecting an integer");
- return nullptr;
- }
-}
-
%typemap(typecheck) char ** {
/* Check if is a list */
$1 = 1;
- if (PyList_Check($input)) {
- int size = PyList_Size($input);
+ using namespace lldb_private;
+ if (PythonList::Check($input)) {
+ PythonList list(PyRefType::Borrowed, $input);
+ int size = list.GetSize();
int i = 0;
for (i = 0; i < size; i++) {
- PyObject *o = PyList_GetItem($input,i);
- if (!PyString_Check(o)) { $1 = 0; }
+ PythonString s = list.GetItemAtIndex(i).AsType<PythonString>();
+ if (!s.IsAllocated()) { $1 = 0; }
}
}
else
@@ -72,63 +62,18 @@
$result = list.release();
}
-%typemap(in) char const ** {
- /* Check if is a list */
- using namespace lldb_private;
- if (PythonList::Check($input)) {
- PythonList py_list(PyRefType::Borrowed, $input);
- int size = py_list.GetSize();
- $1 = (char**)malloc((size+1)*sizeof(char*));
- for (int i = 0; i < size; i++) {
- PythonObject o = py_list.GetItemAtIndex(i);
- if (!PythonString::Check(o.get())) {
- PyErr_SetString(PyExc_TypeError,"list must contain strings");
- free($1);
- return nullptr;
- }
- auto py_str = o.AsType<PythonString>();
- $1[i] = const_cast<char*>(py_str.GetString().data());
- }
-
- $1[size] = 0;
- } else if ($input == Py_None) {
- $1 = nullptr;
- } else {
- PyErr_SetString(PyExc_TypeError,"not a list");
- return nullptr;
- }
-}
-
-%typemap(typecheck) char const ** {
- /* Check if is a list */
- $1 = 1;
- if (PyList_Check($input)) {
- int size = PyList_Size($input);
- int i = 0;
- for (i = 0; i < size; i++) {
- PyObject *o = PyList_GetItem($input,i);
- if (!PyString_Check(o)) { $1 = 0; }
- }
+%typemap(in) lldb::tid_t {
+ using namespace lldb_private;
+ if (PythonInteger::Check($input))
+ {
+ PythonInteger py_int(PyRefType::Borrowed, $input);
+ $1 = static_cast<lldb::tid_t>(py_int.GetInteger());
}
else
{
- $1 = ( ($input == Py_None) ? 1 : 0);
- }
-}
-
-%typemap(freearg) char const ** {
- free((char *) $1);
-}
-
-%typemap(out) char const ** {
- int len;
- int i;
- len = 0;
- while ($1[len]) len++;
- $result = PyList_New(len);
- for (i = 0; i < len; i++) {
- PyList_SetItem($result, i, PyString_FromString($1[i]));
+ PyErr_SetString(PyExc_ValueError, "Expecting an integer");
+ return nullptr;
}
}
@@ -148,6 +93,9 @@
}
$1 = (char *) malloc($2);
}
+// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
+// as char data instead of byte data.
+%typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len);
// Return the char buffer. Discarding any previous return result
// See also SBThread::GetStopDescription.
@@ -163,18 +111,29 @@
}
free($1);
}
+// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
+// as char data instead of byte data.
+%typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len);
// typemap for an outgoing buffer
// See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len).
%typemap(in) (const char *cstr, uint32_t cstr_len) {
- if (PyString_Check($input)) {
- $1 = (char *) PyString_AsString($input);
- $2 = PyString_Size($input);
+ using namespace lldb_private;
+ if (PythonString::Check($input)) {
+ PythonString str(PyRefType::Borrowed, $input);
+ $1 = (char*)str.GetString().data();
+ $2 = str.GetSize();
+ }
+ else if(PythonByteArray::Check($input)) {
+ PythonByteArray bytearray(PyRefType::Borrowed, $input);
+ $1 = (char*)bytearray.GetBytes().data();
+ $2 = bytearray.GetSize();
}
- else if(PyByteArray_Check($input)) {
- $1 = (char *) PyByteArray_AsString($input);
- $2 = PyByteArray_Size($input);
+ else if (PythonBytes::Check($input)) {
+ PythonBytes bytes(PyRefType::Borrowed, $input);
+ $1 = (char*)bytes.GetBytes().data();
+ $2 = bytes.GetSize();
}
else {
PyErr_SetString(PyExc_ValueError, "Expecting a string");
@@ -183,13 +142,21 @@
}
// Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len).
%typemap(in) (const char *src, size_t src_len) {
- if (PyString_Check($input)) {
- $1 = (char *) PyString_AsString($input);
- $2 = PyString_Size($input);
+ using namespace lldb_private;
+ if (PythonString::Check($input)) {
+ PythonString str(PyRefType::Borrowed, $input);
+ $1 = (char*)str.GetString().data();
+ $2 = str.GetSize();
}
- else if(PyByteArray_Check($input)) {
- $1 = (char *) PyByteArray_AsString($input);
- $2 = PyByteArray_Size($input);
+ else if(PythonByteArray::Check($input)) {
+ PythonByteArray bytearray(PyRefType::Borrowed, $input);
+ $1 = (char*)bytearray.GetBytes().data();
+ $2 = bytearray.GetSize();
+ }
+ else if (PythonBytes::Check($input)) {
+ PythonBytes bytes(PyRefType::Borrowed, $input);
+ $1 = (char*)bytes.GetBytes().data();
+ $2 = bytes.GetSize();
}
else {
PyErr_SetString(PyExc_ValueError, "Expecting a string");
@@ -198,32 +165,48 @@
}
// And SBProcess::WriteMemory.
%typemap(in) (const void *buf, size_t size) {
- if (PyString_Check($input)) {
- $1 = (void *) PyString_AsString($input);
- $2 = PyString_Size($input);
+ using namespace lldb_private;
+ if (PythonString::Check($input)) {
+ PythonString str(PyRefType::Borrowed, $input);
+ $1 = (void*)str.GetString().data();
+ $2 = str.GetSize();
}
- else if(PyByteArray_Check($input)) {
- $1 = (void *) PyByteArray_AsString($input);
- $2 = PyByteArray_Size($input);
+ else if(PythonByteArray::Check($input)) {
+ PythonByteArray bytearray(PyRefType::Borrowed, $input);
+ $1 = (void*)bytearray.GetBytes().data();
+ $2 = bytearray.GetSize();
+ }
+ else if (PythonBytes::Check($input)) {
+ PythonBytes bytes(PyRefType::Borrowed, $input);
+ $1 = (void*)bytes.GetBytes().data();
+ $2 = bytes.GetSize();
}
else {
- PyErr_SetString(PyExc_ValueError, "Expecting a string");
+ PyErr_SetString(PyExc_ValueError, "Expecting a buffer");
return NULL;
}
}
// For SBDebugger::DispatchInput
%typemap(in) (const void *data, size_t data_len) {
- if (PyString_Check($input)) {
- $1 = static_cast<void *>(PyString_AsString($input));
- $2 = PyString_Size($input);
+ using namespace lldb_private;
+ if (PythonString::Check($input)) {
+ PythonString str(PyRefType::Borrowed, $input);
+ $1 = (void*)str.GetString().data();
+ $2 = str.GetSize();
}
- else if(PyByteArray_Check($input)) {
- $1 = static_cast<void *>(PyByteArray_AsString($input));
- $2 = PyByteArray_Size($input);
+ else if(PythonByteArray::Check($input)) {
+ PythonByteArray bytearray(PyRefType::Borrowed, $input);
+ $1 = (void*)bytearray.GetBytes().data();
+ $2 = bytearray.GetSize();
+ }
+ else if (PythonBytes::Check($input)) {
+ PythonBytes bytes(PyRefType::Borrowed, $input);
+ $1 = (void*)bytes.GetBytes().data();
+ $2 = bytes.GetSize();
}
else {
- PyErr_SetString(PyExc_ValueError, "Expecting a string or byte array");
+ PyErr_SetString(PyExc_ValueError, "Expecting a buffer");
return NULL;
}
}
@@ -254,9 +237,8 @@
$result = Py_None;
Py_INCREF($result);
} else {
- llvm::StringRef ref(static_cast<const char*>($1), result);
- lldb_private::PythonString string(ref);
- $result = string.release();
+ lldb_private::PythonBytes bytes(static_cast<const uint8_t*>($1), result);
+ $result = bytes.release();
}
free($1);
}
@@ -545,22 +527,27 @@
return nullptr;
$1 = file.GetStream();
- }
+ if ($1)
+ file.Clear();
+ }
}
%typemap(out) FILE * {
char mode[4] = {0};
-#ifdef __MACOSX__
+%#ifdef __APPLE__
int i = 0;
- short flags = $1->_flags;
-
- if (flags & __SRD)
- mode[i++] = 'r';
- else if (flags & __SWR)
- mode[i++] = 'w';
- else // if (flags & __SRW)
- mode[i++] = 'a';
-#endif
+ if ($1)
+ {
+ short flags = $1->_flags;
+
+ if (flags & __SRD)
+ mode[i++] = 'r';
+ else if (flags & __SWR)
+ mode[i++] = 'w';
+ else // if (flags & __SRW)
+ mode[i++] = 'a';
+ }
+%#endif
using namespace lldb_private;
File file($1, false);
PythonFile py_file(file, mode);
diff --git a/scripts/Python/python-wrapper.swig b/scripts/Python/python-wrapper.swig
index 5d7bfaa89439..a92102e32838 100644
--- a/scripts/Python/python-wrapper.swig
+++ b/scripts/Python/python-wrapper.swig
@@ -610,7 +610,7 @@ LLDBSwigPythonCallCommand
PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb));
PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(&cmd_retobj_sb));
- if (argc.count == 5 || argc.has_varargs)
+ if (argc.count == 5 || argc.is_bound_method || argc.has_varargs)
pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg, dict);
else
pfunc(debugger_arg, PythonString(args), cmd_retobj_arg, dict);
diff --git a/scripts/Python/use_lldb_suite.py b/scripts/Python/use_lldb_suite.py
index 63a098cea220..f3e358af143b 100644
--- a/scripts/Python/use_lldb_suite.py
+++ b/scripts/Python/use_lldb_suite.py
@@ -17,6 +17,9 @@ def find_lldb_root():
lldb_root = find_lldb_root()
if lldb_root is not None:
import imp
- module = imp.find_module("use_lldb_suite_root", [lldb_root])
- if module is not None:
- imp.load_module("use_lldb_suite_root", *module)
+ fp, pathname, desc = imp.find_module("use_lldb_suite_root", [lldb_root])
+ try:
+ imp.load_module("use_lldb_suite_root", fp, pathname, desc)
+ finally:
+ if fp:
+ fp.close()
diff --git a/scripts/Xcode/build-llvm.py b/scripts/Xcode/build-llvm.py
new file mode 100755
index 000000000000..b594a8cfe17b
--- /dev/null
+++ b/scripts/Xcode/build-llvm.py
@@ -0,0 +1,373 @@
+#!/usr/bin/env python
+
+import errno
+import hashlib
+import fnmatch
+import os
+import platform
+import subprocess
+import sys
+
+from lldbbuild import *
+
+#### SETTINGS ####
+
+def LLVM_HASH_INCLUDES_DIFFS ():
+ return False
+
+# The use of "x = "..."; return x" here is important because tooling looks for
+# it with regexps. Only change how this works if you know what you are doing.
+
+def LLVM_REF ():
+ llvm_ref = "master"
+ return llvm_ref
+
+def CLANG_REF ():
+ clang_ref = "master"
+ return clang_ref
+
+# For use with Xcode-style builds
+
+def XCODE_REPOSITORIES ():
+ return [
+ { 'name': "llvm",
+ 'vcs': VCS.git,
+ 'root': llvm_source_path(),
+ 'url': "http://llvm.org/git/llvm.git",
+ 'ref': LLVM_REF() },
+
+ { 'name': "clang",
+ 'vcs': VCS.git,
+ 'root': clang_source_path(),
+ 'url': "http://llvm.org/git/clang.git",
+ 'ref': CLANG_REF() },
+
+ { 'name': "ninja",
+ 'vcs': VCS.git,
+ 'root': ninja_source_path(),
+ 'url': "https://github.com/ninja-build/ninja.git",
+ 'ref': "master" }
+ ]
+
+def get_c_compiler ():
+ return subprocess.check_output([
+ 'xcrun',
+ '--sdk', 'macosx',
+ '-find', 'clang'
+ ]).rstrip()
+
+def get_cxx_compiler ():
+ return subprocess.check_output([
+ 'xcrun',
+ '--sdk', 'macosx',
+ '-find', 'clang++'
+ ]).rstrip()
+
+# CFLAGS="-isysroot $(xcrun --sdk macosx --show-sdk-path) -mmacosx-version-min=${DARWIN_DEPLOYMENT_VERSION_OSX}" \
+# LDFLAGS="-mmacosx-version-min=${DARWIN_DEPLOYMENT_VERSION_OSX}" \
+
+def get_deployment_target ():
+ return os.environ.get('MACOSX_DEPLOYMENT_TARGET', None)
+
+def get_c_flags ():
+ cflags = ''
+ # sdk_path = subprocess.check_output([
+ # 'xcrun',
+ # '--sdk', 'macosx',
+ # '--show-sdk-path']).rstrip()
+ # cflags += '-isysroot {}'.format(sdk_path)
+
+ deployment_target = get_deployment_target()
+ if deployment_target:
+ # cflags += ' -mmacosx-version-min={}'.format(deployment_target)
+ pass
+
+ return cflags
+
+def get_cxx_flags ():
+ return get_c_flags()
+
+def get_common_linker_flags ():
+ linker_flags = ""
+ deployment_target = get_deployment_target()
+ if deployment_target:
+ # if len(linker_flags) > 0:
+ # linker_flags += ' '
+ # linker_flags += '-mmacosx-version-min={}'.format(deployment_target)
+ pass
+
+ return linker_flags
+
+def get_exe_linker_flags ():
+ return get_common_linker_flags()
+
+def get_shared_linker_flags ():
+ return get_common_linker_flags()
+
+def CMAKE_FLAGS ():
+ return {
+ "Debug": [
+ "-DCMAKE_BUILD_TYPE=RelWithDebInfo",
+ "-DLLVM_ENABLE_ASSERTIONS=ON",
+ ],
+ "DebugClang": [
+ "-DCMAKE_BUILD_TYPE=Debug",
+ "-DLLVM_ENABLE_ASSERTIONS=ON",
+ ],
+ "Release": [
+ "-DCMAKE_BUILD_TYPE=Release",
+ "-DLLVM_ENABLE_ASSERTIONS=ON",
+ ],
+ "BuildAndIntegration": [
+ "-DCMAKE_BUILD_TYPE=Release",
+ "-DLLVM_ENABLE_ASSERTIONS=OFF",
+ ],
+ }
+
+def CMAKE_ENVIRONMENT ():
+ return {
+ }
+
+#### COLLECTING ALL ARCHIVES ####
+
+def collect_archives_in_path (path):
+ files = os.listdir(path)
+ return [os.path.join(path, file) for file in files if file.endswith(".a")]
+
+def archive_list ():
+ paths = library_paths()
+ archive_lists = [collect_archives_in_path(path) for path in paths]
+ return [archive for archive_list in archive_lists for archive in archive_list]
+
+def write_archives_txt ():
+ f = open(archives_txt(), 'w')
+ for archive in archive_list():
+ f.write(archive + "\n")
+ f.close()
+
+#### COLLECTING REPOSITORY MD5S ####
+
+def source_control_status (spec):
+ vcs_for_spec = vcs(spec)
+ if LLVM_HASH_INCLUDES_DIFFS():
+ return vcs_for_spec.status() + vcs_for_spec.diff()
+ else:
+ return vcs_for_spec.status()
+
+def source_control_status_for_specs (specs):
+ statuses = [source_control_status(spec) for spec in specs]
+ return "".join(statuses)
+
+def all_source_control_status ():
+ return source_control_status_for_specs(XCODE_REPOSITORIES())
+
+def md5 (string):
+ m = hashlib.md5()
+ m.update(string)
+ return m.hexdigest()
+
+def all_source_control_status_md5 ():
+ return md5(all_source_control_status())
+
+#### CHECKING OUT AND BUILDING LLVM ####
+
+def apply_patches(spec):
+ files = os.listdir(os.path.join(lldb_source_path(), 'scripts'))
+ patches = [f for f in files if fnmatch.fnmatch(f, spec['name'] + '.*.diff')]
+ for p in patches:
+ run_in_directory(["patch", "-p0", "-i", os.path.join(lldb_source_path(), 'scripts', p)], spec['root'])
+
+def check_out_if_needed(spec):
+ if not os.path.isdir(spec['root']):
+ vcs(spec).check_out()
+ apply_patches(spec)
+
+def all_check_out_if_needed ():
+ map (check_out_if_needed, XCODE_REPOSITORIES())
+
+def should_build_llvm ():
+ if build_type() == BuildType.Xcode:
+ # TODO use md5 sums
+ return True
+
+def do_symlink (source_path, link_path):
+ print "Symlinking " + source_path + " to " + link_path
+ if not os.path.exists(link_path):
+ os.symlink(source_path, link_path)
+
+def setup_source_symlink (repo):
+ source_path = repo["root"]
+ link_path = os.path.join(lldb_source_path(), os.path.basename(source_path))
+ do_symlink(source_path, link_path)
+
+def setup_source_symlinks ():
+ map(setup_source_symlink, XCODE_REPOSITORIES())
+
+def setup_build_symlink ():
+ # We don't use the build symlinks in llvm.org Xcode-based builds.
+ if build_type() != BuildType.Xcode:
+ source_path = package_build_path()
+ link_path = expected_package_build_path()
+ do_symlink(source_path, link_path)
+
+def should_run_cmake (cmake_build_dir):
+ # We need to run cmake if our llvm build directory doesn't yet exist.
+ if not os.path.exists(cmake_build_dir):
+ return True
+
+ # Wee also need to run cmake if for some reason we don't have a ninja
+ # build file. (Perhaps the cmake invocation failed, which this current
+ # build may have fixed).
+ ninja_path = os.path.join(cmake_build_dir, "build.ninja")
+ return not os.path.exists(ninja_path)
+
+def cmake_environment ():
+ cmake_env = join_dicts(os.environ, CMAKE_ENVIRONMENT())
+ return cmake_env
+
+def is_executable(path):
+ return os.path.isfile(path) and os.access(path, os.X_OK)
+
+def find_executable_in_paths (program, paths_to_check):
+ program_dir, program_name = os.path.split(program)
+ if program_dir:
+ if is_executable(program):
+ return program
+ else:
+ for path_dir in paths_to_check:
+ path_dir = path_dir.strip('"')
+ executable_file = os.path.join(path_dir, program)
+ if is_executable(executable_file):
+ return executable_file
+ return None
+
+def find_cmake ():
+ # First check the system PATH env var for cmake
+ cmake_binary = find_executable_in_paths("cmake", os.environ["PATH"].split(os.pathsep))
+ if cmake_binary:
+ # We found it there, use it.
+ return cmake_binary
+
+ # Check a few more common spots. Xcode launched from Finder
+ # will have the default environment, and may not have
+ # all the normal places present.
+ extra_cmake_dirs = [
+ "/usr/local/bin",
+ "/opt/local/bin",
+ os.path.join(os.path.expanduser("~"), "bin")
+ ]
+
+ if platform.system() == "Darwin":
+ # Add locations where an official CMake.app package may be installed.
+ extra_cmake_dirs.extend([
+ os.path.join(
+ os.path.expanduser("~"),
+ "Applications",
+ "CMake.app",
+ "Contents",
+ "bin"),
+ os.path.join(
+ os.sep,
+ "Applications",
+ "CMake.app",
+ "Contents",
+ "bin")])
+
+ cmake_binary = find_executable_in_paths("cmake", extra_cmake_dirs)
+ if cmake_binary:
+ # We found it in one of the usual places. Use that.
+ return cmake_binary
+
+ # We couldn't find cmake. Tell the user what to do.
+ raise Exception(
+ "could not find cmake in PATH ({}) or in any of these locations ({}), "
+ "please install cmake or add a link to it in one of those locations".format(
+ os.environ["PATH"],
+ extra_cmake_dirs))
+
+def cmake_flags ():
+ cmake_flags = CMAKE_FLAGS()[lldb_configuration()]
+ cmake_flags += [
+ "-GNinja",
+ "-DCMAKE_C_COMPILER={}".format(get_c_compiler()),
+ "-DCMAKE_CXX_COMPILER={}".format(get_cxx_compiler()),
+ "-DCMAKE_INSTALL_PREFIX={}".format(expected_package_build_path_for("llvm")),
+ "-DCMAKE_C_FLAGS={}".format(get_c_flags()),
+ "-DCMAKE_CXX_FLAGS={}".format(get_cxx_flags()),
+ "-DCMAKE_EXE_LINKER_FLAGS={}".format(get_exe_linker_flags()),
+ "-DCMAKE_SHARED_LINKER_FLAGS={}".format(get_shared_linker_flags())
+ ]
+ deployment_target = get_deployment_target()
+ if deployment_target:
+ cmake_flags.append("-DCMAKE_OSX_DEPLOYMENT_TARGET={}".format(deployment_target))
+ return cmake_flags
+
+def run_cmake (cmake_build_dir, ninja_binary_path):
+ cmake_binary = find_cmake()
+ print "found cmake binary: using \"{}\"".format(cmake_binary)
+
+ command_line = [cmake_binary] + cmake_flags() + [
+ "-DCMAKE_MAKE_PROGRAM={}".format(ninja_binary_path),
+ llvm_source_path()]
+ print "running cmake like so: ({}) in dir ({})".format(command_line, cmake_build_dir)
+
+ subprocess.check_call(command_line, cwd=cmake_build_dir, env=cmake_environment())
+
+def create_directories_as_needed (path):
+ try:
+ os.makedirs(path)
+ except OSError as error:
+ # An error indicating that the directory exists already is fine.
+ # Anything else should be passed along.
+ if error.errno != errno.EEXIST:
+ raise error
+
+def run_cmake_if_needed (ninja_binary_path):
+ cmake_build_dir = package_build_path()
+ if should_run_cmake(cmake_build_dir):
+ # Create the build directory as needed
+ create_directories_as_needed (cmake_build_dir)
+ run_cmake(cmake_build_dir, ninja_binary_path)
+
+def build_ninja_if_needed ():
+ # First check if ninja is in our path. If so, there's nothing to do.
+ ninja_binary_path = find_executable_in_paths("ninja", os.environ["PATH"].split(os.pathsep))
+ if ninja_binary_path:
+ # It's on the path. cmake will find it. We're good.
+ print "found ninja here: \"{}\"".format(ninja_binary_path)
+ return ninja_binary_path
+
+ # Figure out if we need to build it.
+ ninja_build_dir = ninja_source_path()
+ ninja_binary_path = os.path.join(ninja_build_dir, "ninja")
+ if not is_executable(ninja_binary_path):
+ # Build ninja
+ command_line = ["python", "configure.py", "--bootstrap"]
+ print "building ninja like so: ({}) in dir ({})".format(command_line, ninja_build_dir)
+ subprocess.check_call(command_line, cwd=ninja_build_dir, env=os.environ)
+
+ return ninja_binary_path
+
+def join_dicts (dict1, dict2):
+ d = dict1.copy()
+ d.update(dict2)
+ return d
+
+def build_llvm (ninja_binary_path):
+ cmake_build_dir = package_build_path()
+ subprocess.check_call([ninja_binary_path], cwd=cmake_build_dir, env=cmake_environment())
+
+def build_llvm_if_needed ():
+ if should_build_llvm():
+ ninja_binary_path = build_ninja_if_needed()
+ run_cmake_if_needed(ninja_binary_path)
+ build_llvm(ninja_binary_path)
+ setup_build_symlink()
+
+#### MAIN LOGIC ####
+
+all_check_out_if_needed()
+build_llvm_if_needed()
+write_archives_txt()
+
+sys.exit(0)
diff --git a/scripts/Xcode/lldbbuild.py b/scripts/Xcode/lldbbuild.py
new file mode 100644
index 000000000000..bb43315dc29d
--- /dev/null
+++ b/scripts/Xcode/lldbbuild.py
@@ -0,0 +1,135 @@
+import os
+import subprocess
+
+#### UTILITIES ####
+
+def enum (*sequential, **named):
+ enums = dict(zip(sequential, range(len(sequential))), **named)
+ return type('Enum', (), enums)
+
+#### SETTINGS ####
+
+#### INTERFACE TO THE XCODEPROJ ####
+
+def lldb_source_path ():
+ return os.environ.get('SRCROOT')
+
+def expected_llvm_build_path ():
+ if build_type() == BuildType.Xcode:
+ return package_build_path()
+ else:
+ return os.path.join(os.environ.get('LLDB_PATH_TO_LLVM_BUILD'), package_build_dir_name("llvm"))
+
+def archives_txt ():
+ return os.path.join(expected_package_build_path(), "archives.txt")
+
+def expected_package_build_path ():
+ return os.path.abspath(os.path.join(expected_llvm_build_path(), ".."))
+
+def architecture ():
+ platform_name = os.environ.get('RC_PLATFORM_NAME')
+ if not platform_name:
+ platform_name = os.environ.get('PLATFORM_NAME')
+ platform_arch = os.environ.get('ARCHS').split()[-1]
+ return platform_name + "-" + platform_arch
+
+def lldb_configuration ():
+ return os.environ.get('CONFIGURATION')
+
+def llvm_configuration ():
+ return os.environ.get('LLVM_CONFIGURATION')
+
+def llvm_build_dirtree ():
+ return os.environ.get('LLVM_BUILD_DIRTREE')
+
+# Edit the code below when adding build styles.
+
+BuildType = enum('Xcode') # (Debug,DebugClang,Release)
+
+def build_type ():
+ return BuildType.Xcode
+
+#### VCS UTILITIES ####
+
+VCS = enum('git',
+ 'svn')
+
+def run_in_directory(args, path):
+ return subprocess.check_output(args, cwd=path)
+
+class Git:
+ def __init__ (self, spec):
+ self.spec = spec
+ def status (self):
+ return run_in_directory(["git", "branch", "-v"], self.spec['root'])
+ def diff (self):
+ return run_in_directory(["git", "diff"], self.spec['root'])
+ def check_out (self):
+ run_in_directory(["git", "clone", "--depth=1", self.spec['url'], self.spec['root']], lldb_source_path())
+ run_in_directory(["git", "fetch", "--all"], self.spec['root'])
+ run_in_directory(["git", "checkout", self.spec['ref']], self.spec['root'])
+
+class SVN:
+ def __init__ (self, spec):
+ self.spec = spec
+ def status (self):
+ return run_in_directory(["svn", "info"], self.spec['root'])
+ def diff (self):
+ return run_in_directory(["svn", "diff"], self.spec['root'])
+ # TODO implement check_out
+
+def vcs (spec):
+ if spec['vcs'] == VCS.git:
+ return Git(spec)
+ elif spec['vcs'] == VCS.svn:
+ return SVN(spec)
+ else:
+ return None
+
+#### SOURCE PATHS ####
+
+def llvm_source_path ():
+ if build_type() == BuildType.Xcode:
+ return os.path.join(lldb_source_path(), "llvm")
+
+def clang_source_path ():
+ if build_type() == BuildType.Xcode:
+ return os.path.join(llvm_source_path(), "tools", "clang")
+
+def ninja_source_path ():
+ if build_type() == BuildType.Xcode:
+ return os.path.join(lldb_source_path(), "ninja")
+
+#### BUILD PATHS ####
+
+def packages ():
+ return ["llvm"]
+
+def package_build_dir_name (package):
+ return package + "-" + architecture()
+
+def expected_package_build_path_for (package):
+ if build_type() == BuildType.Xcode:
+ if package != "llvm":
+ raise("On Xcode build, we only support the llvm package: requested {}".format(package))
+ return package_build_path()
+ return os.path.join(expected_package_build_path(), package_build_dir_name(package))
+
+def expected_package_build_paths ():
+ return [expected_package_build_path_for(package) for package in packages()]
+
+def library_path (build_path):
+ return build_path + "/lib"
+
+def library_paths ():
+ if build_type() == BuildType.Xcode:
+ package_build_paths = [package_build_path()]
+ else:
+ package_build_paths = expected_package_build_paths()
+ return [library_path(build_path) for build_path in package_build_paths]
+
+def package_build_path ():
+ return os.path.join(
+ llvm_build_dirtree(),
+ os.environ["LLVM_CONFIGURATION"],
+ os.environ["CURRENT_ARCH"])
diff --git a/scripts/package-clang-headers.py b/scripts/Xcode/package-clang-headers.py
index b28ad0d343ec..55ecc90d357b 100644
--- a/scripts/package-clang-headers.py
+++ b/scripts/Xcode/package-clang-headers.py
@@ -14,12 +14,14 @@ import re
import shutil
import sys
+import lldbbuild
+
if len(sys.argv) != 3:
print "usage: " + sys.argv[0] + " TARGET_DIR LLVM_BUILD_DIR"
sys.exit(1)
target_dir = sys.argv[1]
-llvm_build_dir = sys.argv[2]
+llvm_build_dir = lldbbuild.expected_package_build_path_for("llvm")
if not os.path.isdir(target_dir):
print target_dir + " doesn't exist"
diff --git a/scripts/build-llvm.pl b/scripts/build-llvm.pl
deleted file mode 100644
index f7a60d8d3d3e..000000000000
--- a/scripts/build-llvm.pl
+++ /dev/null
@@ -1,407 +0,0 @@
-#!/usr/bin/perl
-
-# This script will take a number ($ENV{SCRIPT_INPUT_FILE_COUNT}) of static archive files
-# and pull them apart into object files. These object files will be placed in a directory
-# named the same as the archive itself without the extension. Each object file will then
-# get renamed to start with the archive name and a '-' character (for archive.a(object.o)
-# the object file would becomde archive-object.o. Then all object files are re-made into
-# a single static library. This can help avoid name collisions when different archive
-# files might contain object files with the same name.
-
-use strict;
-use Cwd 'abs_path';
-use File::Basename;
-use File::Glob ':glob';
-use File::Slurp;
-use List::Util qw[min max];
-use Digest::MD5 qw(md5_hex);
-
-our $llvm_srcroot = $ENV{SCRIPT_INPUT_FILE_0};
-our $llvm_dstroot = $ENV{SCRIPT_INPUT_FILE_1};
-our $archive_filelist_file = $ENV{SCRIPT_INPUT_FILE_2};
-
-our $llvm_configuration = $ENV{LLVM_CONFIGURATION};
-
-our $llvm_revision = "HEAD";
-our $clang_revision = "HEAD";
-our $compiler_rt_revision = "HEAD";
-
-our $SRCROOT = "$ENV{SRCROOT}";
-our @archs = split (/\s+/, $ENV{ARCHS});
-my $os_release = 11;
-
-my $original_env_path = $ENV{PATH};
-
-my $common_configure_options = "--disable-terminfo";
-
-our %llvm_config_info = (
- 'Debug' => { configure_options => '--disable-optimized --disable-assertions --enable-cxx11 --enable-libcpp', make_options => 'DEBUG_SYMBOLS=1'},
- 'Debug+Asserts' => { configure_options => '--disable-optimized --enable-assertions --enable-cxx11 --enable-libcpp' , make_options => 'DEBUG_SYMBOLS=1'},
- 'Release' => { configure_options => '--enable-optimized --disable-assertions --enable-cxx11 --enable-libcpp' , make_options => ''},
- 'Release+Debug' => { configure_options => '--enable-optimized --disable-assertions --enable-cxx11 --enable-libcpp' , make_options => 'DEBUG_SYMBOLS=1'},
- 'Release+Asserts' => { configure_options => '--enable-optimized --enable-assertions --enable-cxx11 --enable-libcpp' , make_options => ''},
-);
-
-our $llvm_config_href = undef;
-if (exists $llvm_config_info{"$llvm_configuration"})
-{
- $llvm_config_href = $llvm_config_info{$llvm_configuration};
-}
-else
-{
- die "Unsupported LLVM configuration: '$llvm_configuration'\n";
-}
-our @llvm_repositories = (
- abs_path("$llvm_srcroot"),
- abs_path("$llvm_srcroot/tools/clang"),
-# abs_path("$llvm_srcroot/projects/compiler-rt")
-);
-
-if (-e "$llvm_srcroot/lib")
-{
- print "Using existing llvm sources in: '$llvm_srcroot'\n";
- print "Using standard LLVM build directory:\n SRC = '$llvm_srcroot'\n DST = '$llvm_dstroot'\n";
-}
-else
-{
- print "Checking out llvm sources from revision $llvm_revision...\n";
- do_command ("cd '$SRCROOT' && svn co --quiet --revision $llvm_revision http://llvm.org/svn/llvm-project/llvm/trunk llvm", "checking out llvm from repository", 1);
- print "Checking out clang sources from revision $clang_revision...\n";
- do_command ("cd '$llvm_srcroot/tools' && svn co --quiet --revision $clang_revision http://llvm.org/svn/llvm-project/cfe/trunk clang", "checking out clang from repository", 1);
-# print "Checking out compiler-rt sources from revision $compiler_rt_revision...\n";
-# do_command ("cd '$llvm_srcroot/projects' && svn co --quiet --revision $compiler_rt_revision http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt", "checking out compiler-rt from repository", 1);
- print "Applying any local patches to LLVM/Clang...";
-
- my @llvm_patches = bsd_glob("$ENV{SRCROOT}/scripts/llvm.*.diff");
- foreach my $patch (@llvm_patches)
- {
- do_command ("cd '$llvm_srcroot' && patch -p0 < $patch");
- }
-
- my @clang_patches = bsd_glob("$ENV{SRCROOT}/scripts/clang.*.diff");
- foreach my $patch (@clang_patches)
- {
- do_command ("cd '$llvm_srcroot/tools/clang' && patch -p0 < $patch");
- }
-
-# my @compiler_rt_patches = bsd_glob("$ENV{SRCROOT}/scripts/compiler-rt.*.diff");
-# foreach my $patch (@compiler_rt_patches)
-# {
-# do_command ("cd '$llvm_srcroot/projects/compiler-rt' && patch -p0 < $patch");
-# }
-}
-
-# Get our options
-
-our $debug = 1;
-
-sub parallel_guess
-{
- my $cpus = `sysctl -n hw.ncpu`;
- chomp ($cpus);
- my $memsize = `sysctl -n hw.memsize`;
- chomp ($memsize);
- my $max_cpus_by_memory = int($memsize / (750 * 1024 * 1024));
- return min($max_cpus_by_memory, $cpus);
-}
-
-sub build_llvm
-{
- #my $extra_svn_options = $debug ? "" : "--quiet";
- # Make the llvm build directory
- my $arch_idx = 0;
-
- # Calculate if the current source digest so we can compare it to each architecture
- # build folder
- my @llvm_md5_strings;
- foreach my $repo (@llvm_repositories)
- {
- if (-d "$repo/.svn")
- {
- push(@llvm_md5_strings, `cd '$repo'; svn info`);
- push(@llvm_md5_strings, `cd '$repo'; svn diff`);
- }
- elsif (-d "$repo/.git")
- {
- push(@llvm_md5_strings, `cd '$repo'; git branch -v`);
- push(@llvm_md5_strings, `cd '$repo'; git diff`);
- }
- }
-
- # open my $md5_data_file, '>', "/tmp/a.txt" or die "Can't open $! for writing...\n";
- # foreach my $md5_string (@llvm_md5_strings)
- # {
- # print $md5_data_file $md5_string;
- # }
- # close ($md5_data_file);
-
- #print "LLVM MD5 will be generated from:\n";
- #print @llvm_md5_strings;
- my $llvm_hex_digest = md5_hex(@llvm_md5_strings);
- my $did_make = 0;
-
- #print "llvm MD5: $llvm_hex_digest\n";
-
- my @archive_dirs;
-
- foreach my $arch (@archs)
- {
- my $llvm_dstroot_arch = "${llvm_dstroot}/${arch}";
-
- # if the arch destination root exists we have already built it
- my $do_configure = 0;
- my $do_make = 0;
- my $is_arm = $arch =~ /^arm/;
- my $save_arch_digest = 1;
- my $arch_digest_file = "$llvm_dstroot_arch/md5";
- my $llvm_dstroot_arch_archive_dir = "$llvm_dstroot_arch/$llvm_configuration/lib";
-
- push @archive_dirs, $llvm_dstroot_arch_archive_dir;
-
- print "LLVM architecture root for ${arch} exists at '$llvm_dstroot_arch'...";
- if (-e $llvm_dstroot_arch)
- {
- print "YES\n";
- $do_configure = !-e "$llvm_dstroot_arch/config.log";
-
- my @archive_modtimes;
- if ($do_make == 0)
- {
- if (-e $arch_digest_file)
- {
- my $arch_hex_digest = read_file($arch_digest_file);
- if ($arch_hex_digest eq $llvm_hex_digest)
- {
- # No sources have been changed or updated
- $save_arch_digest = 0;
- }
- else
- {
- # Sources have changed, or svn has been updated
- print "Sources have changed, rebuilding...\n";
- $do_make = 1;
- }
- }
- else
- {
- # No MD5 digest, we need to make
- print "Missing MD5 digest file '$arch_digest_file', rebuilding...\n";
- $do_make = 1;
- }
-
- if ($do_make == 0)
- {
- if (-e $archive_filelist_file)
- {
- # the final archive exists, check the modification times on all .a files that
- # make the final archive to make sure we don't need to rebuild
- my $archive_filelist_file_modtime = (stat($archive_filelist_file))[9];
-
- our @archive_files = glob "$llvm_dstroot_arch_archive_dir/*.a";
-
- for my $llvm_lib (@archive_files)
- {
- if (-e $llvm_lib)
- {
- if ($archive_filelist_file_modtime < (stat($llvm_lib))[9])
- {
- print "'$llvm_dstroot_arch/$llvm_lib' is newer than '$archive_filelist_file', rebuilding...\n";
- $do_make = 1;
- last;
- }
- }
- }
- }
- else
- {
- $do_make = 1;
- }
- }
- }
- }
- else
- {
- print "NO\n";
- do_command ("mkdir -p '$llvm_dstroot_arch'", "making llvm build directory '$llvm_dstroot_arch'", 1);
- $do_configure = 1;
- $do_make = 1;
-
- if ($is_arm)
- {
- my $llvm_dstroot_arch_bin = "${llvm_dstroot_arch}/bin";
- if (!-d $llvm_dstroot_arch_bin)
- {
- do_command ("mkdir -p '$llvm_dstroot_arch_bin'", "making llvm build arch bin directory '$llvm_dstroot_arch_bin'", 1);
- my @tools = ("ar", "nm", "strip", "lipo", "ld", "as");
- my $script_mode = 0755;
- my $prog;
- for $prog (@tools)
- {
- chomp(my $actual_prog_path = `xcrun -sdk '$ENV{SDKROOT}' -find ${prog}`);
- symlink($actual_prog_path, "$llvm_dstroot_arch_bin/${prog}");
- my $script_prog_path = "$llvm_dstroot_arch_bin/arm-apple-darwin${os_release}-${prog}";
- open (SCRIPT, ">$script_prog_path") or die "Can't open $! for writing...\n";
- print SCRIPT "#!/bin/sh\nexec '$actual_prog_path' \"\$\@\"\n";
- close (SCRIPT);
- chmod($script_mode, $script_prog_path);
- }
- # Tools that must have the "-arch" and "-sysroot" specified
- my @arch_sysroot_tools = ("clang", "clang++", "gcc", "g++");
- for $prog (@arch_sysroot_tools)
- {
- chomp(my $actual_prog_path = `xcrun -sdk '$ENV{SDKROOT}' -find ${prog}`);
- symlink($actual_prog_path, "$llvm_dstroot_arch_bin/${prog}");
- my $script_prog_path = "$llvm_dstroot_arch_bin/arm-apple-darwin${os_release}-${prog}";
- open (SCRIPT, ">$script_prog_path") or die "Can't open $! for writing...\n";
- print SCRIPT "#!/bin/sh\nexec '$actual_prog_path' -arch ${arch} -isysroot '$ENV{SDKROOT}' \"\$\@\"\n";
- close (SCRIPT);
- chmod($script_mode, $script_prog_path);
- }
- my $new_path = "$original_env_path:$llvm_dstroot_arch_bin";
- print "Setting new environment PATH = '$new_path'\n";
- $ENV{PATH} = $new_path;
- }
- }
- }
-
- if ($save_arch_digest)
- {
- write_file($arch_digest_file, \$llvm_hex_digest);
- }
-
- if ($do_configure)
- {
- # Build llvm and clang
- print "Configuring clang ($arch) in '$llvm_dstroot_arch'...\n";
- my $lldb_configuration_options = "--enable-targets=x86_64,arm,arm64 $common_configure_options $llvm_config_href->{configure_options}";
-
- # We're configuring llvm/clang with --enable-cxx11 and --enable-libcpp but llvm/configure doesn't
- # pick up the right C++ standard library. If we have a MACOSX_DEPLOYMENT_TARGET of 10.7 or 10.8
- # (or are using actually building on those releases), we need to specify "-stdlib=libc++" at link
- # time or llvm/configure will not see <atomic> as available and error out (v. llvm r199313).
- $ENV{LDFLAGS} = $ENV{LDFLAGS} . " -stdlib=libc++";
-
- if ($is_arm)
- {
- $lldb_configuration_options .= " --host=arm-apple-darwin${os_release} --target=arm-apple-darwin${os_release} --build=i686-apple-darwin${os_release} --program-prefix=\"\"";
- }
- else
- {
- $lldb_configuration_options .= " --build=$arch-apple-darwin${os_release}";
- }
- if ($is_arm)
- {
- # Unset "SDKROOT" for ARM builds
- do_command ("cd '$llvm_dstroot_arch' && unset SDKROOT && '$llvm_srcroot/configure' $lldb_configuration_options",
- "configuring llvm build", 1);
- }
- else
- {
- do_command ("cd '$llvm_dstroot_arch' && '$llvm_srcroot/configure' $lldb_configuration_options",
- "configuring llvm build", 1);
- }
- }
-
- if ($do_make)
- {
- $did_make = 1;
- # Build llvm and clang
- my $num_cpus = parallel_guess();
- print "Building clang using $num_cpus cpus ($arch)...\n";
- my $extra_make_flags = '';
- if ($is_arm)
- {
- $extra_make_flags = "UNIVERSAL=1 UNIVERSAL_ARCH=${arch} UNIVERSAL_SDK_PATH='$ENV{SDKROOT}' SDKROOT=";
- }
- do_command ("cd '$llvm_dstroot_arch' && make -j$num_cpus clang-only VERBOSE=1 $llvm_config_href->{make_options} PROJECT_NAME='llvm' $extra_make_flags", "making llvm and clang", 1);
- do_command ("cd '$llvm_dstroot_arch' && make -j$num_cpus tools-only VERBOSE=1 $llvm_config_href->{make_options} PROJECT_NAME='llvm' $extra_make_flags EDIS_VERSION=1", "making libedis", 1);
-
- }
-
- ++$arch_idx;
- }
-
- # If we did any makes update the archive filenames file with any .a files from
- # each architectures "lib" folder...
- if ($did_make)
- {
- open my $fh, '>', $archive_filelist_file or die "Can't open $! for writing...\n";
- foreach my $archive_dir (@archive_dirs)
- {
- append_all_archive_files ($archive_dir, $fh);
- }
- close($fh);
- }
-}
-
-#----------------------------------------------------------------------
-# quote the path if needed and realpath it if the -r option was
-# specified
-#----------------------------------------------------------------------
-sub finalize_path
-{
- my $path = shift;
- # Realpath all paths that don't start with "/"
- $path =~ /^[^\/]/ and $path = abs_path($path);
-
- # Quote the path if asked to, or if there are special shell characters
- # in the path name
- my $has_double_quotes = $path =~ /["]/;
- my $has_single_quotes = $path =~ /[']/;
- my $needs_quotes = $path =~ /[ \$\&\*'"]/;
- if ($needs_quotes)
- {
- # escape and double quotes in the path
- $has_double_quotes and $path =~ s/"/\\"/g;
- $path = "\"$path\"";
- }
- return $path;
-}
-
-sub do_command
-{
- my $cmd = shift;
- my $description = @_ ? shift : "command";
- my $die_on_fail = @_ ? shift : undef;
- $debug and print "% $cmd\n";
- system ($cmd);
- if ($? == -1)
- {
- $debug and printf ("error: %s failed to execute: $!\n", $description);
- $die_on_fail and $? and exit(1);
- return $?;
- }
- elsif ($? & 127)
- {
- $debug and printf("error: %s child died with signal %d, %s coredump\n",
- $description,
- ($? & 127),
- ($? & 128) ? 'with' : 'without');
- $die_on_fail and $? and exit(1);
- return $?;
- }
- else
- {
- my $exit = $? >> 8;
- if ($exit)
- {
- $debug and printf("error: %s child exited with value %d\n", $description, $exit);
- $die_on_fail and exit(1);
- }
- return $exit;
- }
-}
-
-sub append_all_archive_files
-{
- my $archive_dir = shift;
- my $fh = shift;
-
- our @archive_files = glob "$archive_dir/*.a";
- for my $archive_fullpath (@archive_files)
- {
- print $fh "$archive_fullpath\n";
- }
-}
-
-build_llvm();
diff --git a/scripts/finishSwigWrapperClasses.py b/scripts/finishSwigWrapperClasses.py
index 8d7d19ef1bdf..cce160df68e7 100644
--- a/scripts/finishSwigWrapperClasses.py
+++ b/scripts/finishSwigWrapperClasses.py
@@ -72,6 +72,8 @@ Args: -h (optional) Print help information on this program.\n\
be installed. Where non-Darwin systems want to put\n\
the .py and .so files so that Python can find them\n\
automatically. Python install directory.\n\
+ --lldbLibDir (optional) The name of the directory containing liblldb.so.\n\
+ \"lib\" by default.\n\
--cmakeBuildConfiguration= (optional) Is the build configuration(Debug, Release, RelWithDebugInfo)\n\
used to determine where the bin and lib directories are \n\
created for a Windows build.\n\
@@ -80,7 +82,7 @@ Args: -h (optional) Print help information on this program.\n\
\n\
Usage:\n\
finishSwigWrapperClasses.py --srcRoot=ADirPath --targetDir=ADirPath\n\
- --cfgBldDir=ADirPath --prefix=ADirPath -m -d\n\
+ --cfgBldDir=ADirPath --prefix=ADirPath --lldbLibDir=ADirPath -m -d\n\
\n\
" #TAG_PROGRAM_HELP_INFO
@@ -158,7 +160,7 @@ def validate_arguments(vArgv):
nResult = 0
strListArgs = "hdm" # Format "hiox:" = -h -i -o -x <arg>
listLongArgs = ["srcRoot=", "targetDir=", "cfgBldDir=", "prefix=", "cmakeBuildConfiguration=",
- "argsFile"]
+ "lldbLibDir=", "argsFile"]
dictArgReq = { "-h": "o", # o = optional, m = mandatory
"-d": "o",
"-m": "o",
@@ -167,6 +169,7 @@ def validate_arguments(vArgv):
"--cfgBldDir": "o",
"--prefix": "o",
"--cmakeBuildConfiguration": "o",
+ "--lldbLibDir": "o",
"--argsFile": "o" }
# Check for mandatory parameters
@@ -337,11 +340,13 @@ def main(vArgv):
--cmakeBuildConfiguration= (optional) Is the build configuration(Debug, Release, RelWithDebugInfo)\n\
used to determine where the bin and lib directories are \n\
created for a Windows build.\n\
+ --lldbLibDir= The name of the directory containing liblldb.so.
+ (optional) "lib" by default.
--argsFile= The args are read from a file instead of the
command line. Other command line args are ignored.
Usage:
finishSwigWrapperClasses.py --srcRoot=ADirPath --targetDir=ADirPath
- --cfgBldDir=ADirPath --prefix=ADirPath -m -d
+ --cfgBldDir=ADirPath --prefix=ADirPath --lldbLibDir=ADirPath -m -d
Results: 0 Success
-1 Error - invalid parameters passed.
diff --git a/scripts/interface/SBCommandReturnObject.i b/scripts/interface/SBCommandReturnObject.i
index 5ade97bebfec..ae32b79b5834 100644
--- a/scripts/interface/SBCommandReturnObject.i
+++ b/scripts/interface/SBCommandReturnObject.i
@@ -84,11 +84,17 @@ public:
bool
GetDescription (lldb::SBStream &description);
- void
- SetImmediateOutputFile (FILE *fh);
-
- void
- SetImmediateErrorFile (FILE *fh);
+
+ // wrapping here so that lldb takes ownership of the
+ // new FILE* created inside of the swig interface
+ %extend {
+ void SetImmediateOutputFile(FILE *fh) {
+ self->SetImmediateOutputFile(fh, true);
+ }
+ void SetImmediateErrorFile(FILE *fh) {
+ self->SetImmediateErrorFile(fh, true);
+ }
+ }
void
PutCString(const char* string, int len);
diff --git a/scripts/interface/SBDebugger.i b/scripts/interface/SBDebugger.i
index 89b2882aeb91..db774d350e9c 100644
--- a/scripts/interface/SBDebugger.i
+++ b/scripts/interface/SBDebugger.i
@@ -105,6 +105,16 @@ if target:
else:
print('Unexpected process state: %s, killing process...' % debugger.StateAsCString (state))
process.Kill()
+
+Sometimes you need to create an empty target that will get filled in later. The most common use for this
+is to attach to a process by name or pid where you don't know the executable up front. The most convenient way
+to do this is:
+
+target = debugger.CreateTarget('')
+error = lldb.SBError()
+process = target.AttachToProcessWithName(debugger.GetListener(), 'PROCESS_NAME', False, error)
+
+or the equivalent arguments for AttachToProcessWithID.
") SBDebugger;
class SBDebugger
{
diff --git a/scripts/interface/SBExpressionOptions.i b/scripts/interface/SBExpressionOptions.i
index 1f423cf47e42..cb61dd9d9632 100644
--- a/scripts/interface/SBExpressionOptions.i
+++ b/scripts/interface/SBExpressionOptions.i
@@ -118,6 +118,20 @@ public:
%feature("docstring", "Sets the prefix to use for this expression. This prefix gets inserted after the 'target.expr-prefix' prefix contents, but before the wrapped expression function body.") SetPrefix;
void
SetPrefix (const char *prefix);
+
+ %feature("docstring", "Sets whether to auto-apply fix-it hints to the expression being evaluated.") SetAutoApplyFixIts;
+ void
+ SetAutoApplyFixIts(bool b = true);
+
+ %feature("docstring", "Gets whether to auto-apply fix-it hints to an expression.") GetAutoApplyFixIts;
+ bool
+ GetAutoApplyFixIts();
+
+ bool
+ GetTopLevel();
+
+ void
+ SetTopLevel(bool b = true);
protected:
diff --git a/scripts/interface/SBFileSpec.i b/scripts/interface/SBFileSpec.i
index c153f2bd86f6..a0e5da21187d 100644
--- a/scripts/interface/SBFileSpec.i
+++ b/scripts/interface/SBFileSpec.i
@@ -72,7 +72,10 @@ public:
bool
GetDescription (lldb::SBStream &description) const;
-
+
+ void
+ AppendPathComponent (const char *file_or_directory);
+
%pythoncode %{
def __get_fullpath__(self):
spec_dir = self.GetDirectory()
diff --git a/scripts/interface/SBHostOS.i b/scripts/interface/SBHostOS.i
index d9f42160bf09..ed2e8b0477b1 100644
--- a/scripts/interface/SBHostOS.i
+++ b/scripts/interface/SBHostOS.i
@@ -22,6 +22,9 @@ public:
static lldb::SBFileSpec
GetLLDBPath (lldb::PathType path_type);
+ static lldb::SBFileSpec
+ GetUserHomeDirectory ();
+
static void
ThreadCreated (const char *name);
diff --git a/scripts/interface/SBMemoryRegionInfo.i b/scripts/interface/SBMemoryRegionInfo.i
new file mode 100644
index 000000000000..d68770802618
--- /dev/null
+++ b/scripts/interface/SBMemoryRegionInfo.i
@@ -0,0 +1,58 @@
+//===-- SWIG Interface for SBMemoryRegionInfo -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+%feature("docstring",
+"API clients can get information about memory regions in processes."
+) SBMemoryRegionInfo;
+
+class SBMemoryRegionInfo
+{
+public:
+
+ SBMemoryRegionInfo ();
+
+ SBMemoryRegionInfo (const lldb::SBMemoryRegionInfo &rhs);
+
+ ~SBMemoryRegionInfo ();
+
+ void
+ Clear();
+
+ lldb::addr_t
+ GetRegionBase ();
+
+ lldb::addr_t
+ GetRegionEnd ();
+
+ bool
+ IsReadable ();
+
+ bool
+ IsWritable ();
+
+ bool
+ IsExecutable ();
+
+ bool
+ IsMapped ();
+
+ bool
+ operator == (const lldb::SBMemoryRegionInfo &rhs) const;
+
+ bool
+ operator != (const lldb::SBMemoryRegionInfo &rhs) const;
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+};
+
+} // namespace lldb
diff --git a/scripts/interface/SBMemoryRegionInfoList.i b/scripts/interface/SBMemoryRegionInfoList.i
new file mode 100644
index 000000000000..f46241145540
--- /dev/null
+++ b/scripts/interface/SBMemoryRegionInfoList.i
@@ -0,0 +1,38 @@
+//===-- SBMemoryRegionInfoList.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+class SBMemoryRegionInfoList
+{
+public:
+
+ SBMemoryRegionInfoList ();
+
+ SBMemoryRegionInfoList (const lldb::SBMemoryRegionInfoList &rhs);
+
+ ~SBMemoryRegionInfoList ();
+
+ uint32_t
+ GetSize () const;
+
+ bool
+ GetMemoryRegionAtIndex (uint32_t idx, SBMemoryRegionInfo &region_info);
+
+ void
+ Append (lldb::SBMemoryRegionInfo &region);
+
+ void
+ Append (lldb::SBMemoryRegionInfoList &region_list);
+
+ void
+ Clear ();
+};
+
+} // namespace lldb
diff --git a/scripts/interface/SBProcess.i b/scripts/interface/SBProcess.i
index 1571ebc4cb68..d9de9d087685 100644
--- a/scripts/interface/SBProcess.i
+++ b/scripts/interface/SBProcess.i
@@ -296,7 +296,7 @@ public:
") ReadCStringFromMemory;
size_t
- ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error);
+ ReadCStringFromMemory (addr_t addr, void *char_buf, size_t size, lldb::SBError &error);
%feature("autodoc", "
Reads an unsigned integer from memory given a byte size and an address.
@@ -401,6 +401,12 @@ public:
lldb::SBError
SaveCore(const char *file_name);
+ lldb::SBError
+ GetMemoryRegionInfo(lldb::addr_t load_addr, lldb::SBMemoryRegionInfo &region_info);
+
+ lldb::SBMemoryRegionInfoList
+ GetMemoryRegions();
+
%pythoncode %{
def __get_is_alive__(self):
'''Returns "True" if the process is currently alive, "False" otherwise'''
@@ -422,7 +428,7 @@ public:
return True
return False
- def __get_is_running__(self):
+ def __get_is_stopped__(self):
'''Returns "True" if the process is currently stopped, "False" otherwise'''
state = self.GetState()
if state == eStateStopped or state == eStateCrashed or state == eStateSuspended:
@@ -468,8 +474,8 @@ public:
__swig_getmethods__["is_running"] = __get_is_running__
if _newclass: is_running = property(__get_is_running__, None, doc='''A read only property that returns a boolean value that indicates if this process is currently running.''')
- __swig_getmethods__["is_stopped"] = __get_is_running__
- if _newclass: is_stopped = property(__get_is_running__, None, doc='''A read only property that returns a boolean value that indicates if this process is currently stopped.''')
+ __swig_getmethods__["is_stopped"] = __get_is_stopped__
+ if _newclass: is_stopped = property(__get_is_stopped__, None, doc='''A read only property that returns a boolean value that indicates if this process is currently stopped.''')
__swig_getmethods__["id"] = GetProcessID
if _newclass: id = property(GetProcessID, None, doc='''A read only property that returns the process ID as an integer.''')
diff --git a/scripts/interface/SBTarget.i b/scripts/interface/SBTarget.i
index 74e470d4b3fa..6198c35fbd7b 100644
--- a/scripts/interface/SBTarget.i
+++ b/scripts/interface/SBTarget.i
@@ -586,6 +586,9 @@ public:
BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line);
lldb::SBBreakpoint
+ BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line, lldb::addr_t offset);
+
+ lldb::SBBreakpoint
BreakpointCreateByName (const char *symbol_name, const char *module_name = NULL);
lldb::SBBreakpoint
@@ -601,18 +604,59 @@ public:
const SBFileSpecList &module_list,
const SBFileSpecList &comp_unit_list);
+%typemap(in) (const char **symbol_name, uint32_t num_names) {
+ using namespace lldb_private;
+ /* Check if is a list */
+ if (PythonList::Check($input)) {
+ PythonList list(PyRefType::Borrowed, $input);
+ $2 = list.GetSize();
+ int i = 0;
+ $1 = (char**)malloc(($2+1)*sizeof(char*));
+ for (i = 0; i < $2; i++) {
+ PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>();
+ if (!py_str.IsAllocated()) {
+ PyErr_SetString(PyExc_TypeError,"list must contain strings and blubby");
+ free($1);
+ return nullptr;
+ }
+
+ $1[i] = const_cast<char*>(py_str.GetString().data());
+ }
+ $1[i] = 0;
+ } else if ($input == Py_None) {
+ $1 = NULL;
+ } else {
+ PyErr_SetString(PyExc_TypeError,"not a list");
+ return NULL;
+ }
+}
+
+//%typecheck(SWIG_TYPECHECK_STRING_ARRAY) (const char *symbol_name[], uint32_t num_names) {
+// $1 = 1;
+// $2 = 1;
+//}
+
+ lldb::SBBreakpoint
+ BreakpointCreateByNames (const char **symbol_name,
+ uint32_t num_names,
+ uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &comp_unit_list);
+
lldb::SBBreakpoint
- BreakpointCreateByNames (const char *symbol_name[],
+ BreakpointCreateByNames (const char **symbol_name,
uint32_t num_names,
uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
+ lldb::LanguageType symbol_language,
const SBFileSpecList &module_list,
const SBFileSpecList &comp_unit_list);
lldb::SBBreakpoint
- BreakpointCreateByNames (const char *symbol_name[],
+ BreakpointCreateByNames (const char **symbol_name,
uint32_t num_names,
uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
lldb::LanguageType symbol_language,
+ lldb::addr_t offset,
const SBFileSpecList &module_list,
const SBFileSpecList &comp_unit_list);
@@ -632,6 +676,12 @@ public:
BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpecList &module_list, const lldb::SBFileSpecList &file_list);
lldb::SBBreakpoint
+ BreakpointCreateBySourceRegex (const char *source_regex,
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &source_file,
+ const SBStringList &func_names);
+
+ lldb::SBBreakpoint
BreakpointCreateForException (lldb::LanguageType language,
bool catch_bp,
bool throw_bp);
diff --git a/scripts/interface/SBThread.i b/scripts/interface/SBThread.i
index f2b27565d489..082805f42fd0 100644
--- a/scripts/interface/SBThread.i
+++ b/scripts/interface/SBThread.i
@@ -118,6 +118,15 @@ public:
") GetStopReasonExtendedInfoAsJSON;
bool
GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream);
+
+ %feature("autodoc", "
+ Returns a collection of historical stack traces that are significant to the
+ current stop reason. Used by ThreadSanitizer, where we provide various stack
+ traces that were involved in a data race or other type of detected issue.
+ ") GetStopReasonExtendedBacktraces;
+ SBThreadCollection
+ GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type);
+
%feature("autodoc", "
Pass only an (int)length and expect to get a Python string describing the
@@ -206,6 +215,17 @@ public:
void
StepInto (const char *target_name, lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
+ %feature("autodoc", "
+ Step the current thread from the current source line to the line given by end_line, stopping if
+ the thread steps into the function given by target_name. If target_name is None, then stepping will stop
+ in any of the places we would normally stop.
+ ") StepInto;
+ void
+ StepInto (const char *target_name,
+ uint32_t end_line,
+ SBError &error,
+ lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
+
void
StepOut ();
@@ -239,6 +259,14 @@ public:
SBError
ReturnFromFrame (SBFrame &frame, SBValue &return_value);
+ %feature("autodoc", "
+ Unwind the stack frames from the innermost expression evaluation.
+ This API is equivalent to 'thread return -x'.
+ ") UnwindInnermostExpression;
+
+ SBError
+ UnwindInnermostExpression();
+
%feature("docstring", "
//--------------------------------------------------------------------------
/// LLDB currently supports process centric debugging which means when any
diff --git a/scripts/interface/SBValue.i b/scripts/interface/SBValue.i
index 5049fd05794d..ef9fe3c74851 100644
--- a/scripts/interface/SBValue.i
+++ b/scripts/interface/SBValue.i
@@ -157,6 +157,12 @@ public:
bool
IsSynthetic ();
+
+ bool
+ IsSyntheticChildrenGenerated ();
+
+ void
+ SetSyntheticChildrenGenerated (bool);
const char *
GetLocation ();
@@ -533,6 +539,23 @@ public:
__swig_getmethods__["path"] = get_expr_path
if _newclass: path = property(get_expr_path, None, doc='''A read only property that returns the expression path that one can use to reach this value in an expression.''')
+
+ def synthetic_child_from_expression(self, name, expr, options=None):
+ if options is None: options = lldb.SBExpressionOptions()
+ child = self.CreateValueFromExpression(name, expr, options)
+ child.SetSyntheticChildrenGenerated(True)
+ return child
+
+ def synthetic_child_from_data(self, name, data, type):
+ child = self.CreateValueFromData(name, data, type)
+ child.SetSyntheticChildrenGenerated(True)
+ return child
+
+ def synthetic_child_from_address(self, name, addr, type):
+ child = self.CreateValueFromAddress(name, addr, type)
+ child.SetSyntheticChildrenGenerated(True)
+ return child
+
%}
};
diff --git a/scripts/lldb.swig b/scripts/lldb.swig
index 1d333540728c..ee34da30fc16 100644
--- a/scripts/lldb.swig
+++ b/scripts/lldb.swig
@@ -83,6 +83,8 @@ import six
#include "lldb/API/SBLaunchInfo.h"
#include "lldb/API/SBLineEntry.h"
#include "lldb/API/SBListener.h"
+#include "lldb/API/SBMemoryRegionInfo.h"
+#include "lldb/API/SBMemoryRegionInfoList.h"
#include "lldb/API/SBModule.h"
#include "lldb/API/SBModuleSpec.h"
#include "lldb/API/SBPlatform.h"
@@ -163,6 +165,8 @@ import six
%include "./interface/SBLaunchInfo.i"
%include "./interface/SBLineEntry.i"
%include "./interface/SBListener.i"
+%include "./interface/SBMemoryRegionInfo.i"
+%include "./interface/SBMemoryRegionInfoList.i"
%include "./interface/SBModule.i"
%include "./interface/SBModuleSpec.i"
%include "./interface/SBPlatform.i"
diff --git a/scripts/prepare_bindings.py b/scripts/prepare_bindings.py
index 3165f232e5ec..6d70f5bf421b 100755
--- a/scripts/prepare_bindings.py
+++ b/scripts/prepare_bindings.py
@@ -152,6 +152,11 @@ def process_args(args):
"Specifies the build dir where the language binding "
"should be placed"))
+ parser.add_argument(
+ "--target-platform",
+ help=(
+ "Specifies the platform we are building for."
+ "Should be the same as what platform.system() returns."))
# Process args.
options = parser.parse_args(args)
diff --git a/scripts/use_lldb_suite.py b/scripts/use_lldb_suite.py
index 63a098cea220..f3e358af143b 100644
--- a/scripts/use_lldb_suite.py
+++ b/scripts/use_lldb_suite.py
@@ -17,6 +17,9 @@ def find_lldb_root():
lldb_root = find_lldb_root()
if lldb_root is not None:
import imp
- module = imp.find_module("use_lldb_suite_root", [lldb_root])
- if module is not None:
- imp.load_module("use_lldb_suite_root", *module)
+ fp, pathname, desc = imp.find_module("use_lldb_suite_root", [lldb_root])
+ try:
+ imp.load_module("use_lldb_suite_root", fp, pathname, desc)
+ finally:
+ if fp:
+ fp.close()
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();
}
}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 1397c664d758..5c34932b1f49 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -38,11 +38,15 @@ set(LLDB_TEST_COMMON_ARGS
${CMAKE_BINARY_DIR}/bin/lldb${CMAKE_EXECUTABLE_SUFFIX}
-s
${CMAKE_BINARY_DIR}/lldb-test-traces
+ -S nm
-u CXXFLAGS
-u CFLAGS
)
if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
+ # All tests are currently flaky on Windows, so rerun them all once when they fail.
+ set(LLDB_TEST_COMMON_ARGS ${LLDB_TEST_COMMON_ARGS} --rerun-all-issues)
+
set(LLDB_TEST_DEBUG_TEST_CRASHES
0
CACHE BOOL "(Windows only) Enables debugging of tests in the test suite by showing the crash dialog when lldb crashes")
diff --git a/test/use_lldb_suite.py b/test/use_lldb_suite.py
index 63a098cea220..f3e358af143b 100644
--- a/test/use_lldb_suite.py
+++ b/test/use_lldb_suite.py
@@ -17,6 +17,9 @@ def find_lldb_root():
lldb_root = find_lldb_root()
if lldb_root is not None:
import imp
- module = imp.find_module("use_lldb_suite_root", [lldb_root])
- if module is not None:
- imp.load_module("use_lldb_suite_root", *module)
+ fp, pathname, desc = imp.find_module("use_lldb_suite_root", [lldb_root])
+ try:
+ imp.load_module("use_lldb_suite_root", fp, pathname, desc)
+ finally:
+ if fp:
+ fp.close()
diff --git a/tools/Makefile b/tools/Makefile
deleted file mode 100644
index 2588d87dc98a..000000000000
--- a/tools/Makefile
+++ /dev/null
@@ -1,30 +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 := ..
-include $(LLDB_LEVEL)/../../Makefile.config
-
-DIRS :=
-
-# enable lldb-gdbserver for supported platforms
-ifneq (,$(strip $(filter $(HOST_OS), FreeBSD Linux NetBSD GNU/kFreeBSD)))
-DIRS += lldb-server
-endif
-
-ifeq ($(HOST_OS),Darwin)
-DIRS += debugserver
-endif
-
-ifeq ($(ENABLE_WERROR),0)
-DIRS += lldb-mi
-endif
-
-DIRS += driver
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/tools/compact-unwind/compact-unwind-dumper.c b/tools/compact-unwind/compact-unwind-dumper.c
index d6bd72d93027..f70f602326bf 100644
--- a/tools/compact-unwind/compact-unwind-dumper.c
+++ b/tools/compact-unwind/compact-unwind-dumper.c
@@ -14,6 +14,50 @@
#include <stdio.h>
#include <mach-o/nlist.h>
+
+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,
+};
+
+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,
+};
+
#define EXTRACT_BITS(value, mask) \
( (value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask)))-1) )
@@ -196,12 +240,14 @@ scan_macho_load_commands (struct baton *baton)
if (is_64bit)
{
struct section_64 sect;
+ memset (&sect, 0, sizeof (struct section_64));
memcpy (&sect, offset, sizeof (struct section_64));
baton->compact_unwind_start = baton->mach_header_start + sect.offset;
}
else
{
struct section sect;
+ memset (&sect, 0, sizeof (struct section));
memcpy (&sect, offset, sizeof (struct section));
baton->compact_unwind_start = baton->mach_header_start + sect.offset;
}
@@ -211,12 +257,14 @@ scan_macho_load_commands (struct baton *baton)
if (is_64bit)
{
struct section_64 sect;
+ memset (&sect, 0, sizeof (struct section_64));
memcpy (&sect, offset, sizeof (struct section_64));
baton->eh_section_file_address = sect.addr;
}
else
{
struct section sect;
+ memset (&sect, 0, sizeof (struct section));
memcpy (&sect, offset, sizeof (struct section));
baton->eh_section_file_address = sect.addr;
}
@@ -226,6 +274,7 @@ scan_macho_load_commands (struct baton *baton)
if (is_64bit)
{
struct section_64 sect;
+ memset (&sect, 0, sizeof (struct section_64));
memcpy (&sect, offset, sizeof (struct section_64));
baton->text_section_vmaddr = sect.addr;
baton->text_section_file_offset = sect.offset;
@@ -233,6 +282,7 @@ scan_macho_load_commands (struct baton *baton)
else
{
struct section sect;
+ memset (&sect, 0, sizeof (struct section));
memcpy (&sect, offset, sizeof (struct section));
baton->text_section_vmaddr = sect.addr;
}
@@ -283,6 +333,7 @@ scan_macho_load_commands (struct baton *baton)
for (int i = 0; i < local_syms_count; i++)
{
struct nlist_64 nlist;
+ memset (&nlist, 0, sizeof (struct nlist_64));
if (is_64bit)
{
memcpy (&nlist, local_syms + (i * nlist_size), sizeof (struct nlist_64));
@@ -290,6 +341,7 @@ scan_macho_load_commands (struct baton *baton)
else
{
struct nlist nlist_32;
+ memset (&nlist_32, 0, sizeof (struct nlist));
memcpy (&nlist_32, local_syms + (i * nlist_size), sizeof (struct nlist));
nlist.n_un.n_strx = nlist_32.n_un.n_strx;
nlist.n_type = nlist_32.n_type;
@@ -304,6 +356,8 @@ scan_macho_load_commands (struct baton *baton)
&& nlist.n_value != baton->text_segment_vmaddr)
{
baton->symbols[baton->symbols_count].file_address = nlist.n_value;
+ if (baton->cputype == CPU_TYPE_ARM)
+ baton->symbols[baton->symbols_count].file_address = baton->symbols[baton->symbols_count].file_address & ~1;
baton->symbols[baton->symbols_count].name = string_table + nlist.n_un.n_strx;
baton->symbols_count++;
}
@@ -312,6 +366,7 @@ scan_macho_load_commands (struct baton *baton)
for (int i = 0; i < exported_syms_count; i++)
{
struct nlist_64 nlist;
+ memset (&nlist, 0, sizeof (struct nlist_64));
if (is_64bit)
{
memcpy (&nlist, exported_syms + (i * nlist_size), sizeof (struct nlist_64));
@@ -333,6 +388,8 @@ scan_macho_load_commands (struct baton *baton)
&& nlist.n_value != baton->text_segment_vmaddr)
{
baton->symbols[baton->symbols_count].file_address = nlist.n_value;
+ if (baton->cputype == CPU_TYPE_ARM)
+ baton->symbols[baton->symbols_count].file_address = baton->symbols[baton->symbols_count].file_address & ~1;
baton->symbols[baton->symbols_count].name = string_table + nlist.n_un.n_strx;
baton->symbols_count++;
}
@@ -388,6 +445,8 @@ scan_macho_load_commands (struct baton *baton)
{
struct symbol search_key;
search_key.file_address = baton->function_start_addresses[i];
+ if (baton->cputype == CPU_TYPE_ARM)
+ search_key.file_address = search_key.file_address & ~1;
struct symbol *sym = bsearch (&search_key, baton->symbols, baton->symbols_count, sizeof (struct symbol), symbol_compare);
if (sym == NULL)
unnamed_functions_to_add++;
@@ -401,6 +460,8 @@ scan_macho_load_commands (struct baton *baton)
{
struct symbol search_key;
search_key.file_address = baton->function_start_addresses[i];
+ if (baton->cputype == CPU_TYPE_ARM)
+ search_key.file_address = search_key.file_address & ~1;
struct symbol *sym = bsearch (&search_key, baton->symbols, baton->symbols_count, sizeof (struct symbol), symbol_compare);
if (sym == NULL)
{
@@ -901,6 +962,282 @@ print_encoding_i386 (struct baton baton, uint8_t *function_start, uint32_t encod
}
}
+void
+print_encoding_arm64 (struct baton baton, uint8_t *function_start, uint32_t encoding)
+{
+ const int wordsize = 8;
+ int mode = encoding & UNWIND_ARM64_MODE_MASK;
+ switch (mode)
+ {
+ case UNWIND_ARM64_MODE_FRAME:
+ {
+ printf ("frame func: CFA is fp+%d ", 16);
+ printf (" pc=[CFA-8] fp=[CFA-16]");
+ int reg_pairs_saved_count = 1;
+ uint32_t saved_register_bits = encoding & 0xfff;
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X19_X20_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf (" x19=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf (" x20=[CFA%d]", cfa_offset);
+ 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;
+ printf (" x21=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf (" x22=[CFA%d]", cfa_offset);
+ 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;
+ printf (" x23=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf (" x24=[CFA%d]", cfa_offset);
+ 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;
+ printf (" x25=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf (" x26=[CFA%d]", cfa_offset);
+ 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;
+ printf (" x27=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf (" x28=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
+ }
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D8_D9_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf (" d8=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf (" d9=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
+ }
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D10_D11_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf (" d10=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf (" d11=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
+ }
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D12_D13_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf (" d12=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf (" d13=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
+ }
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D14_D15_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf (" d14=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf (" d15=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
+ }
+
+ }
+ break;
+
+ case UNWIND_ARM64_MODE_FRAMELESS:
+ {
+ uint32_t stack_size = encoding & UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK;
+ printf ("frameless function: stack size %d ", stack_size * 16);
+
+ }
+ break;
+
+ case UNWIND_ARM64_MODE_DWARF:
+ {
+ uint32_t dwarf_offset = encoding & UNWIND_ARM64_DWARF_SECTION_OFFSET;
+ printf ("DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64 ")",
+ dwarf_offset, dwarf_offset + baton.eh_section_file_address);
+ }
+ break;
+
+ case 0:
+ {
+ printf (" no unwind information");
+ }
+ break;
+ }
+}
+
+void
+print_encoding_armv7 (struct baton baton, uint8_t *function_start, uint32_t encoding)
+{
+ const int wordsize = 4;
+ int mode = encoding & UNWIND_ARM_MODE_MASK;
+ switch (mode)
+ {
+ case UNWIND_ARM_MODE_FRAME_D:
+ case UNWIND_ARM_MODE_FRAME:
+ {
+ int stack_adjust = EXTRACT_BITS (encoding, UNWIND_ARM_FRAME_STACK_ADJUST_MASK) * wordsize;
+
+ printf ("frame func: CFA is fp+%d ", (2 * wordsize) + stack_adjust);
+ int cfa_offset = -stack_adjust;
+
+ cfa_offset -= wordsize;
+ printf (" pc=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf (" fp=[CFA%d]", cfa_offset);
+
+ uint32_t saved_register_bits = encoding & 0xff;
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R6)
+ {
+ cfa_offset -= wordsize;
+ printf (" r6=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R5)
+ {
+ cfa_offset -= wordsize;
+ printf (" r5=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R4)
+ {
+ cfa_offset -= wordsize;
+ printf (" r4=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R12)
+ {
+ cfa_offset -= wordsize;
+ printf (" r12=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R11)
+ {
+ cfa_offset -= wordsize;
+ printf (" r11=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R10)
+ {
+ cfa_offset -= wordsize;
+ printf (" r10=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R9)
+ {
+ cfa_offset -= wordsize;
+ printf (" r9=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R8)
+ {
+ cfa_offset -= wordsize;
+ printf (" r8=[CFA%d]", cfa_offset);
+ }
+
+ if (mode == UNWIND_ARM_MODE_FRAME_D)
+ {
+ uint32_t d_reg_bits = EXTRACT_BITS (encoding, UNWIND_ARM_FRAME_D_REG_COUNT_MASK);
+ switch (d_reg_bits)
+ {
+ case 0:
+ // vpush {d8}
+ cfa_offset -= 8;
+ printf (" d8=[CFA%d]", cfa_offset);
+ break;
+ case 1:
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ printf (" d10=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf (" d8=[CFA%d]", cfa_offset);
+ break;
+ case 2:
+ // vpush {d12}
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ printf (" d12=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf (" d10=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf (" d8=[CFA%d]", cfa_offset);
+ break;
+ case 3:
+ // vpush {d14}
+ // vpush {d12}
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ printf (" d14=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf (" d12=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf (" d10=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf (" d8=[CFA%d]", cfa_offset);
+ break;
+ case 4:
+ // vpush {d14}
+ // vpush {d12}
+ // sp = (sp - 24) & (-16);
+ // vst {d8, d9, d10}
+ printf (" d14, d12, d10, d9, d8");
+ break;
+ case 5:
+ // vpush {d14}
+ // sp = (sp - 40) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12}
+ printf (" d14, d11, d10, d9, d8, d12");
+ break;
+ case 6:
+ // sp = (sp - 56) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12, d13, d14}
+ printf (" d11, d10, d9, d8, d14, d13, d12");
+ break;
+ case 7:
+ // sp = (sp - 64) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12, d13, d14, d15}
+ printf (" d11, d10, d9, d8, d15, d14, d13, d12");
+ break;
+ }
+ }
+ }
+ break;
+
+ case UNWIND_ARM_MODE_DWARF:
+ {
+ uint32_t dwarf_offset = encoding & UNWIND_ARM_DWARF_SECTION_OFFSET;
+ printf ("DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64 ")",
+ dwarf_offset, dwarf_offset + baton.eh_section_file_address);
+ }
+ break;
+
+ case 0:
+ {
+ printf (" no unwind information");
+ }
+ break;
+ }
+}
+
+
+
void print_encoding (struct baton baton, uint8_t *function_start, uint32_t encoding)
{
@@ -913,6 +1250,14 @@ void print_encoding (struct baton baton, uint8_t *function_start, uint32_t encod
{
print_encoding_i386 (baton, function_start, encoding);
}
+ else if (baton.cputype == CPU_TYPE_ARM64)
+ {
+ print_encoding_arm64 (baton, function_start, encoding);
+ }
+ else if (baton.cputype == CPU_TYPE_ARM)
+ {
+ print_encoding_armv7 (baton, function_start, encoding);
+ }
else
{
printf (" -- unsupported encoding arch -- ");
@@ -935,6 +1280,9 @@ print_function_encoding (struct baton baton, uint32_t idx, uint32_t encoding, ui
uint64_t file_address = baton.first_level_index_entry.functionOffset + entry_func_offset + baton.text_segment_vmaddr;
+ if (baton.cputype == CPU_TYPE_ARM)
+ file_address = file_address & ~1;
+
printf (" func [%d] offset %d (file addr 0x%" PRIx64 ")%s, encoding is 0x%x",
idx, entry_func_offset,
file_address,
diff --git a/tools/debugserver/Makefile b/tools/debugserver/Makefile
deleted file mode 100644
index 0284ea42f407..000000000000
--- a/tools/debugserver/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-##===- tools/debugserver/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 := ../..
-
-DIRS := source
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/tools/debugserver/debugserver.xcodeproj/project.pbxproj
index 2f7a557bf0b9..295a2bf4fa17 100644
--- a/tools/debugserver/debugserver.xcodeproj/project.pbxproj
+++ b/tools/debugserver/debugserver.xcodeproj/project.pbxproj
@@ -163,7 +163,7 @@
26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplX86_64.cpp; sourceTree = "<group>"; };
26CF99A31142EB7400011AAB /* DNBArchImplX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBArchImplX86_64.h; sourceTree = "<group>"; };
26E6B9DA0D1329010037ECDD /* RNBDefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBDefs.h; sourceTree = "<group>"; };
- 456F67721AD46CE9002850C2 /* debugserver */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = debugserver; sourceTree = BUILT_PRODUCTS_DIR; };
+ 456F67721AD46CE9002850C2 /* debugserver-nonui */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "debugserver-nonui"; sourceTree = BUILT_PRODUCTS_DIR; };
4971AE7013D10F4F00649E37 /* HasAVX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HasAVX.h; sourceTree = "<group>"; };
4971AE7113D10F4F00649E37 /* HasAVX.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = HasAVX.s; sourceTree = "<group>"; };
49F530111331519C008956F6 /* MachRegisterStatesI386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesI386.h; sourceTree = "<group>"; };
@@ -216,7 +216,7 @@
isa = PBXGroup;
children = (
26CE0594115C31C20022F371 /* debugserver */,
- 456F67721AD46CE9002850C2 /* debugserver */,
+ 456F67721AD46CE9002850C2 /* debugserver-nonui */,
);
name = Products;
sourceTree = "<group>";
@@ -438,7 +438,7 @@
);
name = "debugserver-mini";
productName = "lldb-debugserver";
- productReference = 456F67721AD46CE9002850C2 /* debugserver */;
+ productReference = 456F67721AD46CE9002850C2 /* debugserver-nonui */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
@@ -594,7 +594,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
@@ -634,7 +634,7 @@
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEAD_CODE_STRIPPING = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
@@ -673,7 +673,7 @@
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEAD_CODE_STRIPPING = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
@@ -708,7 +708,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
"FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
@@ -809,7 +809,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
"FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
"$(SDKROOT)/System/Library/PrivateFrameworks",
@@ -909,7 +909,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
"FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
@@ -920,7 +920,6 @@
GCC_C_LANGUAGE_STANDARD = c99;
GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_RELEASE;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
INSTALL_PATH = /usr/bin;
LLDB_COMPRESSION_CFLAGS = "";
"LLDB_COMPRESSION_CFLAGS[sdk=appletvos*]" = "-DHAVE_LIBCOMPRESSION=1";
@@ -1018,7 +1017,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
"FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
@@ -1037,7 +1036,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- INSTALL_PATH = /usr/bin;
+ INSTALL_PATH = /usr/local/bin;
LLDB_COMPRESSION_CFLAGS = "";
"LLDB_COMPRESSION_CFLAGS[sdk=macosx10.11]" = "-DHAVE_LIBCOMPRESSION=1";
LLDB_COMPRESSION_LDFLAGS = "";
@@ -1055,6 +1054,7 @@
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
"-Wparentheses",
"-DOS_OBJECT_USE_OBJC=0",
+ "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = "";
@@ -1070,7 +1070,7 @@
"$(LLDB_ENERGY_LFLAGS)",
);
OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = debugserver;
+ PRODUCT_NAME = "debugserver-nonui";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
"PROVISIONING_PROFILE[sdk=macosx*]" = "";
SDKROOT = macosx.internal;
@@ -1097,7 +1097,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
"FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
"$(SDKROOT)/System/Library/PrivateFrameworks",
@@ -1109,7 +1109,7 @@
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_DEBUG;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- INSTALL_PATH = /usr/bin;
+ INSTALL_PATH = /usr/local/bin;
LLDB_DEBUGSERVER = 1;
LLDB_ENERGY_CFLAGS = "";
"LLDB_ENERGY_CFLAGS[sdk=macosx.internal]" = "-DLLDB_ENERGY";
@@ -1123,6 +1123,7 @@
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
"-Wparentheses",
"-DOS_OBJECT_USE_OBJC=0",
+ "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = "";
@@ -1141,7 +1142,7 @@
"$(LLDB_ZLIB_LDFLAGS)",
);
OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = debugserver;
+ PRODUCT_NAME = "debugserver-nonui";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
"PROVISIONING_PROFILE[sdk=macosx*]" = "";
SDKROOT = macosx.internal;
@@ -1165,7 +1166,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
"FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
@@ -1177,7 +1178,7 @@
GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_RELEASE;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
- INSTALL_PATH = /usr/bin;
+ INSTALL_PATH = /usr/local/bin;
LLDB_DEBUGSERVER = 1;
LLDB_ENERGY_CFLAGS = "";
"LLDB_ENERGY_CFLAGS[sdk=macosx.internal]" = "-DLLDB_ENERGY";
@@ -1187,10 +1188,12 @@
OTHER_CFLAGS = (
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
);
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
"-Wparentheses",
"-DOS_OBJECT_USE_OBJC=0",
+ "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = "";
@@ -1210,7 +1213,7 @@
"$(LLDB_ZLIB_LDFLAGS)",
);
OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = debugserver;
+ PRODUCT_NAME = "debugserver-nonui";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
"PROVISIONING_PROFILE[sdk=macosx*]" = "";
SDKROOT = macosx.internal;
@@ -1233,7 +1236,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
"FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
@@ -1245,8 +1248,8 @@
GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_BUILDANDINTEGRATION;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
- INSTALL_PATH = /usr/bin;
- "INSTALL_PATH[sdk=iphoneos*]" = /Developer/usr/bin/;
+ INSTALL_PATH = /usr/local/bin;
+ "INSTALL_PATH[sdk=iphoneos*]" = /usr/local/bin;
LLDB_DEBUGSERVER = 1;
LLDB_ENERGY_CFLAGS = "";
"LLDB_ENERGY_CFLAGS[sdk=macosx*]" = "-DLLDB_ENERGY";
@@ -1256,10 +1259,12 @@
OTHER_CFLAGS = (
"-Wparentheses",
"$(LLDB_ENERGY_CFLAGS)",
+ "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
);
"OTHER_CFLAGS[sdk=iphoneos*]" = (
"-Wparentheses",
"-DOS_OBJECT_USE_OBJC=0",
+ "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
@@ -1274,7 +1279,7 @@
"$(LLDB_ENERGY_LFLAGS)",
);
OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = debugserver;
+ PRODUCT_NAME = "debugserver-nonui";
SDKROOT = macosx.internal;
SKIP_INSTALL = YES;
"SKIP_INSTALL[sdk=iphoneos*]" = NO;
@@ -1302,7 +1307,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
@@ -1334,7 +1339,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
"FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
"$(SDKROOT)/System/Library/PrivateFrameworks",
@@ -1440,7 +1445,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
@@ -1472,7 +1477,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
"FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
"$(SDKROOT)/System/Library/PrivateFrameworks",
@@ -1570,7 +1575,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
"FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
"$(SDKROOT)/System/Library/PrivateFrameworks",
@@ -1582,7 +1587,7 @@
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_DEBUG;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- INSTALL_PATH = /usr/bin;
+ INSTALL_PATH = /usr/local/bin;
LLDB_DEBUGSERVER = 1;
LLDB_ENERGY_CFLAGS = "";
"LLDB_ENERGY_CFLAGS[sdk=macosx.internal]" = "-DLLDB_ENERGY";
@@ -1592,10 +1597,12 @@
OTHER_CFLAGS = (
"-Wparentheses",
"$(LLDB_ENERGY_CFLAGS)",
+ "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
);
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
"-Wparentheses",
"-DOS_OBJECT_USE_OBJC=0",
+ "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
@@ -1610,7 +1617,7 @@
"$(LLDB_ENERGY_LFLAGS)",
);
OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = debugserver;
+ PRODUCT_NAME = "debugserver-nonui";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
"PROVISIONING_PROFILE[sdk=macosx*]" = "";
SDKROOT = macosx.internal;
@@ -1626,14 +1633,14 @@
94BA9B361B1A7C5700035A23 /* CustomSwift-Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- PRODUCT_NAME = "lldb-debugserver";
+ PRODUCT_NAME = "lldb-debugserver-nonui";
};
name = "CustomSwift-Debug";
};
94BA9B371B1A7C5700035A23 /* CustomSwift-Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- PRODUCT_NAME = "lldb-debugserver";
+ PRODUCT_NAME = "lldb-debugserver-nonui";
};
name = "CustomSwift-Release";
};
@@ -1655,7 +1662,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
@@ -1687,7 +1694,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
"FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
"$(SDKROOT)/System/Library/PrivateFrameworks",
@@ -1782,7 +1789,7 @@
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEAD_CODE_STRIPPING = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
@@ -1816,7 +1823,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 350.99.0;
+ CURRENT_PROJECT_VERSION = 360.99.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
"FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
diff --git a/tools/debugserver/source/DNB.cpp b/tools/debugserver/source/DNB.cpp
index 03c85df441de..bb3603649199 100644
--- a/tools/debugserver/source/DNB.cpp
+++ b/tools/debugserver/source/DNB.cpp
@@ -360,21 +360,13 @@ DNBProcessLaunch (const char *path,
char *err_str,
size_t err_len)
{
- DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, working_dir=%s, stdin=%s, stdout=%s, stderr=%s, no-stdio=%i, launch_flavor = %u, disable_aslr = %d, err = %p, err_len = %llu) called...",
- __FUNCTION__,
- path,
- argv,
- envp,
- working_directory,
- stdin_path,
- stdout_path,
- stderr_path,
- no_stdio,
- launch_flavor,
- disable_aslr,
- err_str,
- (uint64_t)err_len);
-
+ DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, working_dir=%s, stdin=%s, stdout=%s, "
+ "stderr=%s, no-stdio=%i, launch_flavor = %u, disable_aslr = %d, err = %p, err_len = "
+ "%llu) called...",
+ __FUNCTION__, path, static_cast<void *>(argv), static_cast<void *>(envp), working_directory,
+ stdin_path, stdout_path, stderr_path, no_stdio, launch_flavor, disable_aslr,
+ static_cast<void *>(err_str), static_cast<uint64_t>(err_len));
+
if (err_str && err_len > 0)
err_str[0] = '\0';
struct stat path_stat;
@@ -548,7 +540,6 @@ DNBProcessAttach (nub_process_t attach_pid, struct timespec *timeout, char *err_
switch (pid_state)
{
- default:
case eStateInvalid:
case eStateUnloaded:
case eStateAttaching:
@@ -1092,6 +1083,39 @@ DNBGetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image_list_addr
return JSONGenerator::ObjectSP();
}
+JSONGenerator::ObjectSP
+DNBGetAllLoadedLibrariesInfos (nub_process_t pid)
+{
+ MachProcessSP procSP;
+ if (GetProcessSP (pid, procSP))
+ {
+ return procSP->GetAllLoadedLibrariesInfos (pid);
+ }
+ return JSONGenerator::ObjectSP();
+}
+
+JSONGenerator::ObjectSP
+DNBGetLibrariesInfoForAddresses (nub_process_t pid, std::vector<uint64_t> &macho_addresses)
+{
+ MachProcessSP procSP;
+ if (GetProcessSP (pid, procSP))
+ {
+ return procSP->GetLibrariesInfoForAddresses (pid, macho_addresses);
+ }
+ return JSONGenerator::ObjectSP();
+}
+
+JSONGenerator::ObjectSP
+DNBGetSharedCacheInfo (nub_process_t pid)
+{
+ MachProcessSP procSP;
+ if (GetProcessSP (pid, procSP))
+ {
+ return procSP->GetSharedCacheInfo (pid);
+ }
+ return JSONGenerator::ObjectSP();
+}
+
const char *
diff --git a/tools/debugserver/source/DNB.h b/tools/debugserver/source/DNB.h
index 7b186d38b32a..fbaf5e348133 100644
--- a/tools/debugserver/source/DNB.h
+++ b/tools/debugserver/source/DNB.h
@@ -144,6 +144,10 @@ nub_addr_t DNBGetPThreadT (nub_process_t pid, nub_thread_t
nub_addr_t DNBGetDispatchQueueT (nub_process_t pid, nub_thread_t tid);
nub_addr_t DNBGetTSDAddressForThread (nub_process_t pid, nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size);
JSONGenerator::ObjectSP DNBGetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count);
+JSONGenerator::ObjectSP DNBGetAllLoadedLibrariesInfos (nub_process_t pid);
+JSONGenerator::ObjectSP DNBGetLibrariesInfoForAddresses (nub_process_t pid, std::vector<uint64_t> &macho_addresses);
+JSONGenerator::ObjectSP DNBGetSharedCacheInfo (nub_process_t pid);
+
//
//----------------------------------------------------------------------
// Breakpoint functions
diff --git a/tools/debugserver/source/DNBDataRef.cpp b/tools/debugserver/source/DNBDataRef.cpp
index 53e9881dfb94..d52f28ee2fb9 100644
--- a/tools/debugserver/source/DNBDataRef.cpp
+++ b/tools/debugserver/source/DNBDataRef.cpp
@@ -250,7 +250,7 @@ DNBDataRef::Get_ULEB128 (offset_t *offset_ptr) const
{
bytecount++;
byte = *src++;
- result |= (byte & 0x7f) << shift;
+ result |= (uint64_t)(byte & 0x7f) << shift;
shift += 7;
if ((byte & 0x80) == 0)
break;
@@ -283,7 +283,7 @@ DNBDataRef::Get_SLEB128 (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;
@@ -362,7 +362,6 @@ DNBDataRef::Dump
// the snprintf call each time through this loop
switch (type)
{
- default:
case TypeUInt8: str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %2.2x", Get8(&offset)); break;
case TypeChar:
{
diff --git a/tools/debugserver/source/MacOSX/CMakeLists.txt b/tools/debugserver/source/MacOSX/CMakeLists.txt
index d319cb7b0bab..96cff0a22fc4 100644
--- a/tools/debugserver/source/MacOSX/CMakeLists.txt
+++ b/tools/debugserver/source/MacOSX/CMakeLists.txt
@@ -59,29 +59,31 @@ set_source_files_properties(
target_link_libraries(debugserver ${DEBUGSERVER_USED_LIBS})
-# Sign the debugserver binary
-set (CODESIGN_IDENTITY lldb_codesign)
-execute_process(
- COMMAND xcrun -f codesign_allocate
- OUTPUT_STRIP_TRAILING_WHITESPACE
- OUTPUT_VARIABLE CODESIGN_ALLOCATE
- )
-# Older cmake versions don't support "-E env".
-if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 3.2)
- add_custom_command(TARGET debugserver
- POST_BUILD
- # Note: --entitlements option removed, as it causes errors when debugging.
- # was: COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --entitlements ${CMAKE_CURRENT_SOURCE_DIR}/../debugserver-entitlements.plist --force --sign ${CODESIGN_IDENTITY} debugserver
- COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --force --sign ${CODESIGN_IDENTITY} debugserver
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
- )
-else()
- add_custom_command(TARGET debugserver
- POST_BUILD
- # Note: --entitlements option removed (see comment above).
- COMMAND ${CMAKE_COMMAND} -E env CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --force --sign ${CODESIGN_IDENTITY} debugserver
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
- )
+set(LLDB_CODESIGN_IDENTITY "lldb_codesign"
+ CACHE STRING "Identity used for code signing. Set to empty string to skip the signing step.")
+if (NOT ("${LLDB_CODESIGN_IDENTITY}" STREQUAL ""))
+ execute_process(
+ COMMAND xcrun -f codesign_allocate
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE CODESIGN_ALLOCATE
+ )
+ # Older cmake versions don't support "-E env".
+ if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 3.2)
+ add_custom_command(TARGET debugserver
+ POST_BUILD
+ # Note: --entitlements option removed, as it causes errors when debugging.
+ # was: COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --entitlements ${CMAKE_CURRENT_SOURCE_DIR}/../debugserver-entitlements.plist --force --sign ${LLDB_CODESIGN_IDENTITY} debugserver
+ COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --force --sign ${LLDB_CODESIGN_IDENTITY} debugserver
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
+ )
+ else()
+ add_custom_command(TARGET debugserver
+ POST_BUILD
+ # Note: --entitlements option removed (see comment above).
+ COMMAND ${CMAKE_COMMAND} -E env CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --force --sign ${LLDB_CODESIGN_IDENTITY} debugserver
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
+ )
+ endif()
endif()
install(TARGETS debugserver
diff --git a/tools/debugserver/source/MacOSX/MachException.cpp b/tools/debugserver/source/MacOSX/MachException.cpp
index b7245796ae4c..0b5459e3a189 100644
--- a/tools/debugserver/source/MacOSX/MachException.cpp
+++ b/tools/debugserver/source/MacOSX/MachException.cpp
@@ -436,7 +436,6 @@ MachException::Message::Reply(MachProcess *process, int signal)
if (state.task_port == process->Task().TaskPort())
{
DNBLogThreaded("error: mach_msg() returned an error when replying to a mach exception: error = %u", err.Error());
- abort ();
}
else
{
diff --git a/tools/debugserver/source/MacOSX/MachProcess.h b/tools/debugserver/source/MacOSX/MachProcess.h
index 3be0b2dbabb3..094c13b8f0a8 100644
--- a/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/tools/debugserver/source/MacOSX/MachProcess.h
@@ -15,8 +15,10 @@
#define __MachProcess_h__
#include <mach/mach.h>
+#include <mach-o/loader.h>
#include <sys/signal.h>
#include <pthread.h>
+#include <uuid/uuid.h>
#include <vector>
#include <CoreFoundation/CoreFoundation.h>
@@ -46,6 +48,45 @@ public:
MachProcess ();
~MachProcess ();
+ // A structure that can hold everything debugserver needs to know from
+ // a binary's Mach-O header / load commands.
+
+ struct mach_o_segment
+ {
+ std::string name;
+ uint64_t vmaddr;
+ uint64_t vmsize;
+ uint64_t fileoff;
+ uint64_t filesize;
+ uint64_t maxprot;
+ uint64_t initprot;
+ uint64_t nsects;
+ uint64_t flags;
+ };
+
+ struct mach_o_information
+ {
+ struct mach_header_64 mach_header;
+ std::vector<struct mach_o_segment> segments;
+ uuid_t uuid;
+ std::string min_version_os_name;
+ std::string min_version_os_version;
+ };
+
+ struct binary_image_information
+ {
+ std::string filename;
+ uint64_t load_address;
+ uint64_t mod_date; // may not be available - 0 if so
+ struct mach_o_information macho_info;
+
+ binary_image_information () :
+ filename (),
+ load_address (INVALID_NUB_ADDRESS),
+ mod_date (0)
+ { }
+ };
+
//----------------------------------------------------------------------
// Child process control
//----------------------------------------------------------------------
@@ -193,7 +234,15 @@ public:
nub_addr_t GetPThreadT (nub_thread_t tid);
nub_addr_t GetDispatchQueueT (nub_thread_t tid);
nub_addr_t GetTSDAddressForThread (nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size);
+
+
+ bool GetMachOInformationFromMemory (nub_addr_t mach_o_header_addr, int wordsize, struct mach_o_information &inf);
+ JSONGenerator::ObjectSP FormatDynamicLibrariesIntoJSON (const std::vector<struct binary_image_information> &image_infos);
+ void GetAllLoadedBinariesViaDYLDSPI (std::vector<struct binary_image_information> &image_infos);
JSONGenerator::ObjectSP GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count);
+ JSONGenerator::ObjectSP GetLibrariesInfoForAddresses (nub_process_t pid, std::vector<uint64_t> &macho_addresses);
+ JSONGenerator::ObjectSP GetAllLoadedLibrariesInfos (nub_process_t pid);
+ JSONGenerator::ObjectSP GetSharedCacheInfo (nub_process_t pid);
nub_size_t GetNumThreads () const;
nub_thread_t GetThreadAtIndex (nub_size_t thread_idx) const;
@@ -358,6 +407,11 @@ private:
// as the sole reason for the process being stopped, we can auto resume
// the process.
bool m_did_exec;
+
+ void * (*m_dyld_process_info_create) (task_t task, uint64_t timestamp, kern_return_t* kernelError);
+ void (*m_dyld_process_info_for_each_image) (void* info, void (^callback)(uint64_t machHeaderAddress, const uuid_t uuid, const char* path));
+ void (*m_dyld_process_info_release) (void* info);
+ void (*m_dyld_process_info_get_cache) (void* info, void* cacheInfo);
};
diff --git a/tools/debugserver/source/MacOSX/MachProcess.mm b/tools/debugserver/source/MacOSX/MachProcess.mm
index b9e06307a4aa..ab0039edd88f 100644
--- a/tools/debugserver/source/MacOSX/MachProcess.mm
+++ b/tools/debugserver/source/MacOSX/MachProcess.mm
@@ -12,8 +12,10 @@
//===----------------------------------------------------------------------===//
#include "DNB.h"
+#include <dlfcn.h>
#include <inttypes.h>
#include <mach/mach.h>
+#include <mach/task.h>
#include <signal.h>
#include <spawn.h>
#include <sys/fcntl.h>
@@ -417,8 +419,17 @@ MachProcess::MachProcess() :
m_image_infos_baton(NULL),
m_sent_interrupt_signo (0),
m_auto_resume_signo (0),
- m_did_exec (false)
+ m_did_exec (false),
+ m_dyld_process_info_create (nullptr),
+ m_dyld_process_info_for_each_image (nullptr),
+ m_dyld_process_info_release (nullptr),
+ m_dyld_process_info_get_cache (nullptr)
{
+ m_dyld_process_info_create = (void * (*) (task_t task, uint64_t timestamp, kern_return_t* kernelError)) dlsym (RTLD_DEFAULT, "_dyld_process_info_create");
+ m_dyld_process_info_for_each_image = (void (*)(void *info, void (^)(uint64_t machHeaderAddress, const uuid_t uuid, const char* path))) dlsym (RTLD_DEFAULT, "_dyld_process_info_for_each_image");
+ m_dyld_process_info_release = (void (*) (void* info)) dlsym (RTLD_DEFAULT, "_dyld_process_info_release");
+ m_dyld_process_info_get_cache = (void (*) (void* info, void* cacheInfo)) dlsym (RTLD_DEFAULT, "_dyld_process_info_get_cache");
+
DNBLogThreadedIf(LOG_PROCESS | LOG_VERBOSE, "%s", __PRETTY_FUNCTION__);
}
@@ -520,8 +531,232 @@ MachProcess::GetTSDAddressForThread (nub_thread_t tid, uint64_t plo_pthread_tsd_
return m_thread_list.GetTSDAddressForThread (tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size);
}
+// Given an address, read the mach-o header and load commands out of memory to fill in
+// the mach_o_information "inf" object.
+//
+// Returns false if there was an error in reading this mach-o file header/load commands.
+
+bool
+MachProcess::GetMachOInformationFromMemory (nub_addr_t mach_o_header_addr, int wordsize, struct mach_o_information &inf)
+{
+ uint64_t load_cmds_p;
+ if (wordsize == 4)
+ {
+ struct mach_header header;
+ if (ReadMemory (mach_o_header_addr, sizeof (struct mach_header), &header) != sizeof (struct mach_header))
+ {
+ return false;
+ }
+ load_cmds_p = mach_o_header_addr + sizeof (struct mach_header);
+ inf.mach_header.magic = header.magic;
+ inf.mach_header.cputype = header.cputype;
+ // high byte of cpusubtype is used for "capability bits", v. CPU_SUBTYPE_MASK, CPU_SUBTYPE_LIB64 in machine.h
+ inf.mach_header.cpusubtype = header.cpusubtype & 0x00ffffff;
+ inf.mach_header.filetype = header.filetype;
+ inf.mach_header.ncmds = header.ncmds;
+ inf.mach_header.sizeofcmds = header.sizeofcmds;
+ inf.mach_header.flags = header.flags;
+ }
+ else
+ {
+ struct mach_header_64 header;
+ if (ReadMemory (mach_o_header_addr, sizeof (struct mach_header_64), &header) != sizeof (struct mach_header_64))
+ {
+ return false;
+ }
+ load_cmds_p = mach_o_header_addr + sizeof (struct mach_header_64);
+ inf.mach_header.magic = header.magic;
+ inf.mach_header.cputype = header.cputype;
+ // high byte of cpusubtype is used for "capability bits", v. CPU_SUBTYPE_MASK, CPU_SUBTYPE_LIB64 in machine.h
+ inf.mach_header.cpusubtype = header.cpusubtype & 0x00ffffff;
+ inf.mach_header.filetype = header.filetype;
+ inf.mach_header.ncmds = header.ncmds;
+ inf.mach_header.sizeofcmds = header.sizeofcmds;
+ inf.mach_header.flags = header.flags;
+ }
+ for (uint32_t j = 0; j < inf.mach_header.ncmds; j++)
+ {
+ struct load_command lc;
+ if (ReadMemory (load_cmds_p, sizeof (struct load_command), &lc) != sizeof (struct load_command))
+ {
+ return false;
+ }
+ if (lc.cmd == LC_SEGMENT)
+ {
+ struct segment_command seg;
+ if (ReadMemory (load_cmds_p, sizeof (struct segment_command), &seg) != sizeof (struct segment_command))
+ {
+ return false;
+ }
+ struct mach_o_segment this_seg;
+ char name[17];
+ ::memset (name, 0, sizeof (name));
+ memcpy (name, seg.segname, sizeof (seg.segname));
+ this_seg.name = name;
+ this_seg.vmaddr = seg.vmaddr;
+ this_seg.vmsize = seg.vmsize;
+ this_seg.fileoff = seg.fileoff;
+ this_seg.filesize = seg.filesize;
+ this_seg.maxprot = seg.maxprot;
+ this_seg.initprot = seg.initprot;
+ this_seg.nsects = seg.nsects;
+ this_seg.flags = seg.flags;
+ inf.segments.push_back(this_seg);
+ }
+ if (lc.cmd == LC_SEGMENT_64)
+ {
+ struct segment_command_64 seg;
+ if (ReadMemory (load_cmds_p, sizeof (struct segment_command_64), &seg) != sizeof (struct segment_command_64))
+ {
+ return false;
+ }
+ struct mach_o_segment this_seg;
+ char name[17];
+ ::memset (name, 0, sizeof (name));
+ memcpy (name, seg.segname, sizeof (seg.segname));
+ this_seg.name = name;
+ this_seg.vmaddr = seg.vmaddr;
+ this_seg.vmsize = seg.vmsize;
+ this_seg.fileoff = seg.fileoff;
+ this_seg.filesize = seg.filesize;
+ this_seg.maxprot = seg.maxprot;
+ this_seg.initprot = seg.initprot;
+ this_seg.nsects = seg.nsects;
+ this_seg.flags = seg.flags;
+ inf.segments.push_back(this_seg);
+ }
+ if (lc.cmd == LC_UUID)
+ {
+ struct uuid_command uuidcmd;
+ if (ReadMemory (load_cmds_p, sizeof (struct uuid_command), &uuidcmd) == sizeof (struct uuid_command))
+ uuid_copy (inf.uuid, uuidcmd.uuid);
+ }
+ bool lc_cmd_known = lc.cmd == LC_VERSION_MIN_IPHONEOS || lc.cmd == LC_VERSION_MIN_MACOSX;
+#if defined(LC_VERSION_MIN_TVOS)
+ lc_cmd_known |= lc.cmd == LC_VERSION_MIN_TVOS;
+#endif
+#if defined(LC_VERSION_MIN_WATCHOS)
+ lc_cmd_known |= lc.cmd == LC_VERSION_MIN_WATCHOS;
+#endif
+ if (lc_cmd_known)
+ {
+ struct version_min_command vers_cmd;
+ if (ReadMemory (load_cmds_p, sizeof (struct version_min_command), &vers_cmd) != sizeof (struct version_min_command))
+ {
+ return false;
+ }
+ switch (lc.cmd)
+ {
+ case LC_VERSION_MIN_IPHONEOS:
+ inf.min_version_os_name = "iphoneos";
+ break;
+ case LC_VERSION_MIN_MACOSX:
+ inf.min_version_os_name = "macosx";
+ break;
+#if defined(LC_VERSION_MIN_TVOS)
+ case LC_VERSION_MIN_TVOS:
+ inf.min_version_os_name = "tvos";
+ break;
+#endif
+#if defined(LC_VERSION_MIN_WATCHOS)
+ case LC_VERSION_MIN_WATCHOS:
+ inf.min_version_os_name = "watchos";
+ break;
+#endif
+ default:
+ return false;
+ }
+ uint32_t xxxx = vers_cmd.sdk >> 16;
+ uint32_t yy = (vers_cmd.sdk >> 8) & 0xffu;
+ uint32_t zz = vers_cmd.sdk & 0xffu;
+ inf.min_version_os_version = "";
+ inf.min_version_os_version += std::to_string(xxxx);
+ inf.min_version_os_version += ".";
+ inf.min_version_os_version += std::to_string(yy);
+ if (zz != 0)
+ {
+ inf.min_version_os_version += ".";
+ inf.min_version_os_version += std::to_string(zz);
+ }
+ }
+ load_cmds_p += lc.cmdsize;
+ }
+ return true;
+}
+
+// Given completely filled in array of binary_image_information structures, create a JSONGenerator object
+// with all the details we want to send to lldb.
+JSONGenerator::ObjectSP
+MachProcess::FormatDynamicLibrariesIntoJSON (const std::vector<struct binary_image_information> &image_infos)
+{
+
+ JSONGenerator::ArraySP image_infos_array_sp (new JSONGenerator::Array());
+
+ const size_t image_count = image_infos.size();
+
+ for (size_t i = 0; i < image_count; i++)
+ {
+ JSONGenerator::DictionarySP image_info_dict_sp (new JSONGenerator::Dictionary());
+ image_info_dict_sp->AddIntegerItem ("load_address", image_infos[i].load_address);
+ image_info_dict_sp->AddIntegerItem ("mod_date", image_infos[i].mod_date);
+ image_info_dict_sp->AddStringItem ("pathname", image_infos[i].filename);
+
+ uuid_string_t uuidstr;
+ uuid_unparse_upper (image_infos[i].macho_info.uuid, uuidstr);
+ image_info_dict_sp->AddStringItem ("uuid", uuidstr);
+
+ if (image_infos[i].macho_info.min_version_os_name.empty() == false
+ && image_infos[i].macho_info.min_version_os_version.empty() == false)
+ {
+ image_info_dict_sp->AddStringItem ("min_version_os_name", image_infos[i].macho_info.min_version_os_name);
+ image_info_dict_sp->AddStringItem ("min_version_os_sdk", image_infos[i].macho_info.min_version_os_version);
+ }
+
+ JSONGenerator::DictionarySP mach_header_dict_sp (new JSONGenerator::Dictionary());
+ mach_header_dict_sp->AddIntegerItem ("magic", image_infos[i].macho_info.mach_header.magic);
+ mach_header_dict_sp->AddIntegerItem ("cputype", (uint32_t) image_infos[i].macho_info.mach_header.cputype);
+ mach_header_dict_sp->AddIntegerItem ("cpusubtype", (uint32_t) image_infos[i].macho_info.mach_header.cpusubtype);
+ mach_header_dict_sp->AddIntegerItem ("filetype", image_infos[i].macho_info.mach_header.filetype);
+
+// DynamicLoaderMacOSX doesn't currently need these fields, so don't send them.
+// mach_header_dict_sp->AddIntegerItem ("ncmds", image_infos[i].macho_info.mach_header.ncmds);
+// mach_header_dict_sp->AddIntegerItem ("sizeofcmds", image_infos[i].macho_info.mach_header.sizeofcmds);
+// mach_header_dict_sp->AddIntegerItem ("flags", image_infos[i].macho_info.mach_header.flags);
+ image_info_dict_sp->AddItem ("mach_header", mach_header_dict_sp);
+
+ JSONGenerator::ArraySP segments_sp (new JSONGenerator::Array());
+ for (size_t j = 0; j < image_infos[i].macho_info.segments.size(); j++)
+ {
+ JSONGenerator::DictionarySP segment_sp (new JSONGenerator::Dictionary());
+ segment_sp->AddStringItem ("name", image_infos[i].macho_info.segments[j].name);
+ segment_sp->AddIntegerItem ("vmaddr", image_infos[i].macho_info.segments[j].vmaddr);
+ segment_sp->AddIntegerItem ("vmsize", image_infos[i].macho_info.segments[j].vmsize);
+ segment_sp->AddIntegerItem ("fileoff", image_infos[i].macho_info.segments[j].fileoff);
+ segment_sp->AddIntegerItem ("filesize", image_infos[i].macho_info.segments[j].filesize);
+ segment_sp->AddIntegerItem ("maxprot", image_infos[i].macho_info.segments[j].maxprot);
+
+// DynamicLoaderMacOSX doesn't currently need these fields, so don't send them.
+// segment_sp->AddIntegerItem ("initprot", image_infos[i].macho_info.segments[j].initprot);
+// segment_sp->AddIntegerItem ("nsects", image_infos[i].macho_info.segments[j].nsects);
+// segment_sp->AddIntegerItem ("flags", image_infos[i].macho_info.segments[j].flags);
+ segments_sp->AddItem (segment_sp);
+ }
+ image_info_dict_sp->AddItem ("segments", segments_sp);
+
+ image_infos_array_sp->AddItem (image_info_dict_sp);
+ }
+ JSONGenerator::DictionarySP reply_sp (new JSONGenerator::Dictionary());;
+ reply_sp->AddItem ("images", image_infos_array_sp);
+ return reply_sp;
+}
+
+// Get the shared library information using the old (pre-macOS 10.12, pre-iOS 10, pre-tvOS 10, pre-watchOS 3)
+// code path. We'll be given the address of an array of structures in the form
+// {void* load_addr, void* mod_date, void* pathname}
+//
+// In macOS 10.12 etc and newer, we'll use SPI calls into dyld to gather this information.
JSONGenerator::ObjectSP
MachProcess::GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count)
{
@@ -536,29 +771,7 @@ MachProcess::GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image
if (processInfo.kp_proc.p_flag & P_LP64)
pointer_size = 8;
- struct segment
- {
- std::string name;
- uint64_t vmaddr;
- uint64_t vmsize;
- uint64_t fileoff;
- uint64_t filesize;
- uint64_t maxprot;
- uint64_t initprot;
- uint64_t nsects;
- uint64_t flags;
- };
-
- struct image_info
- {
- uint64_t load_address;
- std::string pathname;
- uint64_t mod_date;
- struct mach_header_64 mach_header;
- std::vector<struct segment> segments;
- uuid_t uuid;
- };
- std::vector<image_info> image_infos;
+ std::vector<struct binary_image_information> image_infos;
size_t image_infos_size = image_count * 3 * pointer_size;
uint8_t *image_info_buf = (uint8_t *) malloc (image_infos_size);
@@ -577,7 +790,7 @@ MachProcess::GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image
for (size_t i = 0; i < image_count; i++)
{
- struct image_info info;
+ struct binary_image_information info;
nub_addr_t pathname_address;
if (pointer_size == 4)
{
@@ -604,13 +817,13 @@ MachProcess::GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image
pathname_address = pathname_address_64;
}
char strbuf[17];
- info.pathname = "";
+ info.filename = "";
uint64_t pathname_ptr = pathname_address;
bool still_reading = true;
while (still_reading && ReadMemory (pathname_ptr, sizeof (strbuf) - 1, strbuf) == sizeof (strbuf) - 1)
{
strbuf[sizeof(strbuf) - 1] = '\0';
- info.pathname += strbuf;
+ info.filename += strbuf;
pathname_ptr += sizeof (strbuf) - 1;
// Stop if we found nul byte indicating the end of the string
for (size_t i = 0; i < sizeof(strbuf) - 1; i++)
@@ -622,7 +835,7 @@ MachProcess::GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image
}
}
}
- uuid_clear (info.uuid);
+ uuid_clear (info.macho_info.uuid);
image_infos.push_back (info);
}
if (image_infos.size() == 0)
@@ -630,157 +843,161 @@ MachProcess::GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image
return reply_sp;
}
+ free (image_info_buf);
//// Second, read the mach header / load commands for all the dylibs
-
for (size_t i = 0; i < image_count; i++)
{
- uint64_t load_cmds_p;
- if (pointer_size == 4)
- {
- struct mach_header header;
- if (ReadMemory (image_infos[i].load_address, sizeof (struct mach_header), &header) != sizeof (struct mach_header))
- {
- return reply_sp;
- }
- load_cmds_p = image_infos[i].load_address + sizeof (struct mach_header);
- image_infos[i].mach_header.magic = header.magic;
- image_infos[i].mach_header.cputype = header.cputype;
- image_infos[i].mach_header.cpusubtype = header.cpusubtype;
- image_infos[i].mach_header.filetype = header.filetype;
- image_infos[i].mach_header.ncmds = header.ncmds;
- image_infos[i].mach_header.sizeofcmds = header.sizeofcmds;
- image_infos[i].mach_header.flags = header.flags;
- }
- else
- {
- struct mach_header_64 header;
- if (ReadMemory (image_infos[i].load_address, sizeof (struct mach_header_64), &header) != sizeof (struct mach_header_64))
- {
- return reply_sp;
- }
- load_cmds_p = image_infos[i].load_address + sizeof (struct mach_header_64);
- image_infos[i].mach_header.magic = header.magic;
- image_infos[i].mach_header.cputype = header.cputype;
- image_infos[i].mach_header.cpusubtype = header.cpusubtype;
- image_infos[i].mach_header.filetype = header.filetype;
- image_infos[i].mach_header.ncmds = header.ncmds;
- image_infos[i].mach_header.sizeofcmds = header.sizeofcmds;
- image_infos[i].mach_header.flags = header.flags;
- }
- for (uint32_t j = 0; j < image_infos[i].mach_header.ncmds; j++)
+ if (!GetMachOInformationFromMemory (image_infos[i].load_address, pointer_size, image_infos[i].macho_info))
{
- struct load_command lc;
- if (ReadMemory (load_cmds_p, sizeof (struct load_command), &lc) != sizeof (struct load_command))
- {
- return reply_sp;
- }
- if (lc.cmd == LC_SEGMENT)
- {
- struct segment_command seg;
- if (ReadMemory (load_cmds_p, sizeof (struct segment_command), &seg) != sizeof (struct segment_command))
- {
- return reply_sp;
- }
- struct segment this_seg;
- char name[17];
- ::memset (name, 0, sizeof (name));
- memcpy (name, seg.segname, sizeof (seg.segname));
- this_seg.name = name;
- this_seg.vmaddr = seg.vmaddr;
- this_seg.vmsize = seg.vmsize;
- this_seg.fileoff = seg.fileoff;
- this_seg.filesize = seg.filesize;
- this_seg.maxprot = seg.maxprot;
- this_seg.initprot = seg.initprot;
- this_seg.nsects = seg.nsects;
- this_seg.flags = seg.flags;
- image_infos[i].segments.push_back(this_seg);
- }
- if (lc.cmd == LC_SEGMENT_64)
- {
- struct segment_command_64 seg;
- if (ReadMemory (load_cmds_p, sizeof (struct segment_command_64), &seg) != sizeof (struct segment_command_64))
- {
- return reply_sp;
- }
- struct segment this_seg;
- char name[17];
- ::memset (name, 0, sizeof (name));
- memcpy (name, seg.segname, sizeof (seg.segname));
- this_seg.name = name;
- this_seg.vmaddr = seg.vmaddr;
- this_seg.vmsize = seg.vmsize;
- this_seg.fileoff = seg.fileoff;
- this_seg.filesize = seg.filesize;
- this_seg.maxprot = seg.maxprot;
- this_seg.initprot = seg.initprot;
- this_seg.nsects = seg.nsects;
- this_seg.flags = seg.flags;
- image_infos[i].segments.push_back(this_seg);
- }
- if (lc.cmd == LC_UUID)
- {
- struct uuid_command uuidcmd;
- if (ReadMemory (load_cmds_p, sizeof (struct uuid_command), &uuidcmd) == sizeof (struct uuid_command))
- uuid_copy (image_infos[i].uuid, uuidcmd.uuid);
- }
- load_cmds_p += lc.cmdsize;
+ return reply_sp;
}
}
- //// Thrid, format all of the above in the JSONGenerator object.
+ //// Third, format all of the above in the JSONGenerator object.
- JSONGenerator::ArraySP image_infos_array_sp (new JSONGenerator::Array());
+ return FormatDynamicLibrariesIntoJSON (image_infos);
+ }
+
+ return reply_sp;
+}
+
+// From dyld SPI header dyld_process_info.h
+typedef void* dyld_process_info;
+struct dyld_process_cache_info
+{
+ uuid_t cacheUUID; // UUID of cache used by process
+ uint64_t cacheBaseAddress; // load address of dyld shared cache
+ bool noCache; // process is running without a dyld cache
+ bool privateCache; // process is using a private copy of its dyld cache
+};
+
+
+// Use the dyld SPI present in macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer to get
+// the load address, uuid, and filenames of all the libraries.
+// This only fills in those three fields in the 'struct binary_image_information' - call
+// GetMachOInformationFromMemory to fill in the mach-o header/load command details.
+void
+MachProcess::GetAllLoadedBinariesViaDYLDSPI (std::vector<struct binary_image_information> &image_infos)
+{
+ kern_return_t kern_ret;
+ if (m_dyld_process_info_create)
+ {
+ dyld_process_info info = m_dyld_process_info_create (m_task.TaskPort(), 0, &kern_ret);
+ if (info)
+ {
+ m_dyld_process_info_for_each_image (info, ^(uint64_t mach_header_addr, const uuid_t uuid, const char *path) {
+ struct binary_image_information image;
+ image.filename = path;
+ uuid_copy (image.macho_info.uuid, uuid);
+ image.load_address = mach_header_addr;
+ image_infos.push_back (image);
+ });
+ m_dyld_process_info_release (info);
+ }
+ }
+}
+
+// Fetch information about all shared libraries using the dyld SPIs that exist in
+// macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer.
+JSONGenerator::ObjectSP
+MachProcess::GetAllLoadedLibrariesInfos (nub_process_t pid)
+{
+ JSONGenerator::DictionarySP reply_sp;
+
+ int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
+ struct kinfo_proc processInfo;
+ size_t bufsize = sizeof(processInfo);
+ if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, &bufsize, NULL, 0) == 0 && bufsize > 0)
+ {
+ uint32_t pointer_size = 4;
+ if (processInfo.kp_proc.p_flag & P_LP64)
+ pointer_size = 8;
+
+ std::vector<struct binary_image_information> image_infos;
+ GetAllLoadedBinariesViaDYLDSPI (image_infos);
+ const size_t image_count = image_infos.size();
for (size_t i = 0; i < image_count; i++)
{
- JSONGenerator::DictionarySP image_info_dict_sp (new JSONGenerator::Dictionary());
- image_info_dict_sp->AddIntegerItem ("load_address", image_infos[i].load_address);
- image_info_dict_sp->AddIntegerItem ("mod_date", image_infos[i].mod_date);
- image_info_dict_sp->AddStringItem ("pathname", image_infos[i].pathname);
+ GetMachOInformationFromMemory (image_infos[i].load_address, pointer_size, image_infos[i].macho_info);
+ }
+ return FormatDynamicLibrariesIntoJSON (image_infos);
+ }
+ return reply_sp;
+}
- uuid_string_t uuidstr;
- uuid_unparse_upper (image_infos[i].uuid, uuidstr);
- image_info_dict_sp->AddStringItem ("uuid", uuidstr);
+// Fetch information about the shared libraries at the given load addresses using the
+// dyld SPIs that exist in macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer.
+JSONGenerator::ObjectSP
+MachProcess::GetLibrariesInfoForAddresses (nub_process_t pid, std::vector<uint64_t> &macho_addresses)
+{
+ JSONGenerator::DictionarySP reply_sp;
- JSONGenerator::DictionarySP mach_header_dict_sp (new JSONGenerator::Dictionary());
- mach_header_dict_sp->AddIntegerItem ("magic", image_infos[i].mach_header.magic);
- mach_header_dict_sp->AddIntegerItem ("cputype", image_infos[i].mach_header.cputype);
- mach_header_dict_sp->AddIntegerItem ("cpusubtype", image_infos[i].mach_header.cpusubtype);
- mach_header_dict_sp->AddIntegerItem ("filetype", image_infos[i].mach_header.filetype);
+ int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
+ struct kinfo_proc processInfo;
+ size_t bufsize = sizeof(processInfo);
+ if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, &bufsize, NULL, 0) == 0 && bufsize > 0)
+ {
+ uint32_t pointer_size = 4;
+ if (processInfo.kp_proc.p_flag & P_LP64)
+ pointer_size = 8;
-// DynamicLoaderMacOSX doesn't currently need these fields, so don't send them.
-// mach_header_dict_sp->AddIntegerItem ("ncmds", image_infos[i].mach_header.ncmds);
-// mach_header_dict_sp->AddIntegerItem ("sizeofcmds", image_infos[i].mach_header.sizeofcmds);
-// mach_header_dict_sp->AddIntegerItem ("flags", image_infos[i].mach_header.flags);
- image_info_dict_sp->AddItem ("mach_header", mach_header_dict_sp);
+ std::vector<struct binary_image_information> all_image_infos;
+ GetAllLoadedBinariesViaDYLDSPI (all_image_infos);
- JSONGenerator::ArraySP segments_sp (new JSONGenerator::Array());
- for (size_t j = 0; j < image_infos[i].segments.size(); j++)
+ std::vector<struct binary_image_information> image_infos;
+ const size_t macho_addresses_count = macho_addresses.size();
+ const size_t all_image_infos_count = all_image_infos.size();
+ for (size_t i = 0; i < macho_addresses_count; i++)
+ {
+ for (size_t j = 0; j < all_image_infos_count; j++)
{
- JSONGenerator::DictionarySP segment_sp (new JSONGenerator::Dictionary());
- segment_sp->AddStringItem ("name", image_infos[i].segments[j].name);
- segment_sp->AddIntegerItem ("vmaddr", image_infos[i].segments[j].vmaddr);
- segment_sp->AddIntegerItem ("vmsize", image_infos[i].segments[j].vmsize);
- segment_sp->AddIntegerItem ("fileoff", image_infos[i].segments[j].fileoff);
- segment_sp->AddIntegerItem ("filesize", image_infos[i].segments[j].filesize);
- segment_sp->AddIntegerItem ("maxprot", image_infos[i].segments[j].maxprot);
-
-// DynamicLoaderMacOSX doesn't currently need these fields, so don't send them.
-// segment_sp->AddIntegerItem ("initprot", image_infos[i].segments[j].initprot);
-// segment_sp->AddIntegerItem ("nsects", image_infos[i].segments[j].nsects);
-// segment_sp->AddIntegerItem ("flags", image_infos[i].segments[j].flags);
- segments_sp->AddItem (segment_sp);
+ if (all_image_infos[j].load_address == macho_addresses[i])
+ {
+ image_infos.push_back (all_image_infos[j]);
+ }
}
- image_info_dict_sp->AddItem ("segments", segments_sp);
+ }
- image_infos_array_sp->AddItem (image_info_dict_sp);
+ const size_t image_infos_count = image_infos.size();
+ for (size_t i = 0; i < image_infos_count; i++)
+ {
+ GetMachOInformationFromMemory (image_infos[i].load_address, pointer_size, image_infos[i].macho_info);
+ }
+ return FormatDynamicLibrariesIntoJSON (image_infos);
+ }
+ return reply_sp;
+}
+
+// From dyld's internal podyld_process_info.h:
+
+JSONGenerator::ObjectSP
+MachProcess::GetSharedCacheInfo (nub_process_t pid)
+{
+ JSONGenerator::DictionarySP reply_sp (new JSONGenerator::Dictionary());;
+ kern_return_t kern_ret;
+ if (m_dyld_process_info_create && m_dyld_process_info_get_cache)
+ {
+ dyld_process_info info = m_dyld_process_info_create (m_task.TaskPort(), 0, &kern_ret);
+ if (info)
+ {
+ struct dyld_process_cache_info shared_cache_info;
+ m_dyld_process_info_get_cache (info, &shared_cache_info);
+
+ reply_sp->AddIntegerItem ("shared_cache_base_address", shared_cache_info.cacheBaseAddress);
+
+ uuid_string_t uuidstr;
+ uuid_unparse_upper (shared_cache_info.cacheUUID, uuidstr);
+ reply_sp->AddStringItem ("shared_cache_uuid", uuidstr);
+
+ reply_sp->AddBooleanItem ("no_shared_cache", shared_cache_info.noCache);
+ reply_sp->AddBooleanItem ("shared_cache_private_cache", shared_cache_info.privateCache);
+
+ m_dyld_process_info_release (info);
}
- reply_sp.reset (new JSONGenerator::Dictionary());
- reply_sp->AddItem ("images", image_infos_array_sp);
}
return reply_sp;
}
@@ -1048,6 +1265,7 @@ MachProcess::Interrupt()
if (Signal (m_sent_interrupt_signo))
{
DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Interrupt() - sent %i signal to interrupt process", m_sent_interrupt_signo);
+ return true;
}
else
{
@@ -2274,9 +2492,9 @@ MachProcess::GetGenealogyImageInfo (size_t idx)
bool
MachProcess::GetOSVersionNumbers (uint64_t *major, uint64_t *minor, uint64_t *patch)
{
- bool success = false;
-
-#if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101000)
+#if defined (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101000)
+ return false;
+#else
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSOperatingSystemVersion vers = [[NSProcessInfo processInfo] operatingSystemVersion];
@@ -2287,12 +2505,10 @@ MachProcess::GetOSVersionNumbers (uint64_t *major, uint64_t *minor, uint64_t *pa
if (patch)
*patch = vers.patchVersion;
- success = true;
-
[pool drain];
+
+ return true;
#endif
-
- return success;
}
// Do the process specific setup for attach. If this returns NULL, then there's no
diff --git a/tools/debugserver/source/MacOSX/MachTask.h b/tools/debugserver/source/MacOSX/MachTask.h
index 96b991478c78..d8021e8f7fe3 100644
--- a/tools/debugserver/source/MacOSX/MachTask.h
+++ b/tools/debugserver/source/MacOSX/MachTask.h
@@ -93,26 +93,6 @@ public:
const MachProcess * Process () const { return m_process; }
nub_size_t PageSize ();
-
- bool HasMallocLoggingEnabled ();
-
- // enumerate the malloc records for a given address (starting with Mac OS X 10.6 Snow Leopard it should include
- // all allocations that *include* address, rather than just those *starting* at address)
- bool EnumerateMallocRecords (mach_vm_address_t address,
- MachMallocEvent *event_buffer,
- uint32_t buffer_size,
- uint32_t *count);
-
- // enumerate every malloc record generated by this task, no matter what the address
- bool EnumerateMallocRecords (MachMallocEvent *event_buffer,
- uint32_t buffer_size,
- uint32_t *count);
-
- // given a malloc event, report every stack frame that led to this event
- bool EnumerateMallocFrames (MachMallocEventId event_id,
- mach_vm_address_t *function_addresses_buffer,
- uint32_t buffer_size,
- uint32_t *count);
protected:
MachProcess * m_process; // The mach process that owns this MachTask
diff --git a/tools/debugserver/source/MacOSX/MachTask.mm b/tools/debugserver/source/MacOSX/MachTask.mm
index 9c725663d559..cc1d6a38ec05 100644
--- a/tools/debugserver/source/MacOSX/MachTask.mm
+++ b/tools/debugserver/source/MacOSX/MachTask.mm
@@ -40,7 +40,6 @@
#include "DNBLog.h"
#include "MachProcess.h"
#include "DNBDataRef.h"
-#include "stack_logging.h"
#ifdef WITH_SPRINGBOARD
@@ -1053,90 +1052,6 @@ MachTask::DeallocateMemory (nub_addr_t addr)
return false;
}
-static void foundStackLog(mach_stack_logging_record_t record, void *context) {
- *((bool*)context) = true;
-}
-
-bool
-MachTask::HasMallocLoggingEnabled ()
-{
- bool found = false;
-
- __mach_stack_logging_enumerate_records(m_task, 0x0, foundStackLog, &found);
- return found;
-}
-
-struct history_enumerator_impl_data
-{
- MachMallocEvent *buffer;
- uint32_t *position;
- uint32_t count;
-};
-
-static void history_enumerator_impl(mach_stack_logging_record_t record, void* enum_obj)
-{
- history_enumerator_impl_data *data = (history_enumerator_impl_data*)enum_obj;
-
- if (*data->position >= data->count)
- return;
-
- data->buffer[*data->position].m_base_address = record.address;
- data->buffer[*data->position].m_size = record.argument;
- data->buffer[*data->position].m_event_id = record.stack_identifier;
- data->buffer[*data->position].m_event_type = record.type_flags == stack_logging_type_alloc ? eMachMallocEventTypeAlloc :
- record.type_flags == stack_logging_type_dealloc ? eMachMallocEventTypeDealloc :
- eMachMallocEventTypeOther;
- *data->position+=1;
-}
-
-bool
-MachTask::EnumerateMallocRecords (MachMallocEvent *event_buffer,
- uint32_t buffer_size,
- uint32_t *count)
-{
- return EnumerateMallocRecords(0,
- event_buffer,
- buffer_size,
- count);
-}
-
-bool
-MachTask::EnumerateMallocRecords (mach_vm_address_t address,
- MachMallocEvent *event_buffer,
- uint32_t buffer_size,
- uint32_t *count)
-{
- if (!event_buffer || !count)
- return false;
-
- if (buffer_size == 0)
- return false;
-
- *count = 0;
- history_enumerator_impl_data data = { event_buffer, count, buffer_size };
- __mach_stack_logging_enumerate_records(m_task, address, history_enumerator_impl, &data);
- return (*count > 0);
-}
-
-bool
-MachTask::EnumerateMallocFrames (MachMallocEventId event_id,
- mach_vm_address_t *function_addresses_buffer,
- uint32_t buffer_size,
- uint32_t *count)
-{
- if (!function_addresses_buffer || !count)
- return false;
-
- if (buffer_size == 0)
- return false;
-
- __mach_stack_logging_frames_for_uniqued_stack(m_task, event_id, &function_addresses_buffer[0], buffer_size, count);
- *count -= 1;
- if (function_addresses_buffer[*count-1] < PageSize())
- *count -= 1;
- return (*count > 0);
-}
-
nub_size_t
MachTask::PageSize ()
{
diff --git a/tools/debugserver/source/MacOSX/Makefile b/tools/debugserver/source/MacOSX/Makefile
deleted file mode 100644
index d047444a9c81..000000000000
--- a/tools/debugserver/source/MacOSX/Makefile
+++ /dev/null
@@ -1,54 +0,0 @@
-##===- tools/debugserver/source/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 := ../../../..
-
-DIRS := i386 x86_64
-
-TOOLNAME = debugserver
-
-CODESIGN_TOOLS := 1
-
-TOOL_CODESIGN_IDENTITY := lldb_codesign
-
-LLVMLibsOptions += -llldbDebugserverCommon -llldbUtility -llldbDebugserverMacOSX_I386 -llldbDebugserverMacOSX_X86_64 \
- -framework Foundation -framework CoreFoundation
-
-GENERATED_MACH_SOURCES = $(PROJ_OBJ_DIR)/mach_excServer.c $(PROJ_OBJ_DIR)/mach_excUser.c
-
-SOURCES := CFBundle.cpp \
- CFData.cpp \
- CFString.cpp \
- MachException.cpp \
- MachProcess.cpp \
- MachTask.cpp \
- MachThread.cpp \
- MachThreadList.cpp \
- MachVMMemory.cpp \
- MachVMRegion.cpp
-
-BUILT_SOURCES = $(GENERATED_MACH_SOURCES) $(PROJ_OBJ_DIR)/HasAVX.o
-
-CPP.Flags += -I$(PROJ_OBJ_DIR)/../.. -I$(PROJ_SRC_DIR)/..
-
-LD.Flags += -Wl,-sectcreate,__TEXT,__info_plist,$(PROJ_SRC_DIR)/../../resources/lldb-debugserver-Info.plist
-
-include $(LLDB_LEVEL)/Makefile
-
-ObjectsO += $(PROJ_OBJ_DIR)/HasAVX.o
-
-$(PROJ_OBJ_DIR)/HasAVX.o: $(PROJ_SRC_DIR)/HasAVX.s
- $(Echo) "Compiling HasAVX.s for $(BuildMode) build" $(PIC_FLAG)
- $(CC) $(TargetCommonOpts) $(CompileCommonOpts) -c $< -o $@
-
-ifeq ($(HOST_OS),Darwin)
-LLVMLibsOptions += -Wl,-rpath,@loader_path/../lib/
-endif
-
-$(GENERATED_MACH_SOURCES):
- mig -I$(PROJ_OBJ_DIR)/../.. $(PROJ_SRC_DIR)/dbgnub-mig.defs \ No newline at end of file
diff --git a/tools/debugserver/source/MacOSX/i386/Makefile b/tools/debugserver/source/MacOSX/i386/Makefile
deleted file mode 100644
index f770b19834bb..000000000000
--- a/tools/debugserver/source/MacOSX/i386/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-##===- tools/debugserver/source/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 := lldbDebugserverMacOSX_I386
-BUILD_ARCHIVE = 1
-
-SOURCES := DNBArchImplI386.cpp
-
-include $(LLDB_LEVEL)/Makefile
-
-CPP.Flags += -I$(PROJ_SRC_DIR)/.. -I$(PROJ_SRC_DIR)/../.. -I$(PROJ_OBJ_DIR)/../../.. \ No newline at end of file
diff --git a/tools/debugserver/source/MacOSX/x86_64/Makefile b/tools/debugserver/source/MacOSX/x86_64/Makefile
deleted file mode 100644
index bf488c859242..000000000000
--- a/tools/debugserver/source/MacOSX/x86_64/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-##===- tools/debugserver/source/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 := lldbDebugserverMacOSX_X86_64
-BUILD_ARCHIVE = 1
-
-SOURCES := DNBArchImplX86_64.cpp
-
-include $(LLDB_LEVEL)/Makefile
-
-CPP.Flags += -I$(PROJ_SRC_DIR)/.. -I$(PROJ_SRC_DIR)/../.. -I$(PROJ_OBJ_DIR)/../../.. \ No newline at end of file
diff --git a/tools/debugserver/source/Makefile b/tools/debugserver/source/Makefile
deleted file mode 100644
index 9eaeab4d3827..000000000000
--- a/tools/debugserver/source/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-##===- tools/debugserver/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 := ../../..
-
-LIBRARYNAME := lldbDebugserverCommon
-BUILD_ARCHIVE = 1
-
-SOURCES := debugserver.cpp \
- DNBArch.cpp \
- DNBBreakpoint.cpp \
- DNB.cpp \
- DNBDataRef.cpp \
- DNBError.cpp \
- DNBLog.cpp \
- DNBRegisterInfo.cpp \
- DNBThreadResumeActions.cpp \
- libdebugserver.cpp \
- PseudoTerminal.cpp \
- PThreadEvent.cpp \
- PThreadMutex.cpp \
- RNBContext.cpp \
- RNBRemote.cpp \
- RNBServices.cpp \
- RNBSocket.cpp \
- SysSignal.cpp \
- TTYState.cpp
-
-include $(LLDB_LEVEL)/Makefile
-
-ifeq ($(HOST_OS),Darwin)
-DIRS := MacOSX/i386 MacOSX/x86_64 MacOSX
-CPP.Flags += -I$(PROJ_SRC_DIR)/MacOSX
-CPP.Flags += -I$(PROJ_OBJ_DIR)/..
-BUILT_SOURCES = debugserver_vers.c
-endif
-
-ifeq ($(HOST_OS),Darwin)
-debugserver_vers.c: $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl $(PROJ_SRC_DIR)/../debugserver.xcodeproj/project.pbxproj
- "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl" "$(PROJ_SRC_DIR)/../debugserver.xcodeproj/project.pbxproj" debugserver > debugserver_vers.c
-endif
diff --git a/tools/debugserver/source/RNBDefs.h b/tools/debugserver/source/RNBDefs.h
index 984b91152415..cefa986f8ca7 100644
--- a/tools/debugserver/source/RNBDefs.h
+++ b/tools/debugserver/source/RNBDefs.h
@@ -17,16 +17,27 @@
#include "DNBDefs.h"
#include <memory>
-#define DEBUGSERVER_PROGRAM_NAME "debugserver"
+#define CONCAT2(a,b) a ## b
+#define CONCAT(a,b) CONCAT2(a,b)
+#define STRINGIZE2(x) #x
+#define STRINGIZE(x) STRINGIZE2(x)
+
+#if !defined (DEBUGSERVER_PROGRAM_SYMBOL)
+#define DEBUGSERVER_PROGRAM_SYMBOL debugserver
+#endif
+
+#if !defined (DEBUGSERVER_PROGRAM_NAME)
+#define DEBUGSERVER_PROGRAM_NAME STRINGIZE(DEBUGSERVER_PROGRAM_SYMBOL)
+#endif
#ifndef DEBUGSERVER_VERSION_NUM
-extern "C" const unsigned char debugserverVersionString[];
-#define DEBUGSERVER_VERSION_NUM debugserverVersionNumber
+extern "C" const unsigned char CONCAT(DEBUGSERVER_PROGRAM_SYMBOL, VersionString)[];
+#define DEBUGSERVER_VERSION_NUM CONCAT(DEBUGSERVER_PROGRAM_SYMBOL, VersionNumber)
#endif
#ifndef DEBUGSERVER_VERSION_STR
-extern "C" const double debugserverVersionNumber;
-#define DEBUGSERVER_VERSION_STR debugserverVersionString
+extern "C" const double CONCAT(DEBUGSERVER_PROGRAM_SYMBOL, VersionNumber);
+#define DEBUGSERVER_VERSION_STR CONCAT(DEBUGSERVER_PROGRAM_SYMBOL, VersionString)
#endif
#if defined (__i386__)
diff --git a/tools/debugserver/source/RNBRemote.cpp b/tools/debugserver/source/RNBRemote.cpp
index 6dddb046acc5..30b804316a1d 100644
--- a/tools/debugserver/source/RNBRemote.cpp
+++ b/tools/debugserver/source/RNBRemote.cpp
@@ -284,6 +284,7 @@ RNBRemote::CreatePacketTable ()
t.push_back (Packet (json_query_thread_extended_info,&RNBRemote::HandlePacket_jThreadExtendedInfo , NULL, "jThreadExtendedInfo", "Replies with JSON data of thread extended information."));
t.push_back (Packet (json_query_get_loaded_dynamic_libraries_infos, &RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos, NULL, "jGetLoadedDynamicLibrariesInfos", "Replies with JSON data of all the shared libraries loaded in this process."));
t.push_back (Packet (json_query_threads_info, &RNBRemote::HandlePacket_jThreadsInfo , NULL, "jThreadsInfo", "Replies with JSON data with information about all threads."));
+ t.push_back (Packet (json_query_get_shared_cache_info, &RNBRemote::HandlePacket_jGetSharedCacheInfo, NULL, "jGetSharedCacheInfo", "Replies with JSON data about the location and uuid of the shared cache in the inferior process."));
t.push_back (Packet (start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets"));
t.push_back (Packet (prefix_reg_packets_with_tid, &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specific packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command"));
t.push_back (Packet (set_logging_mode, &RNBRemote::HandlePacket_QSetLogging , NULL, "QSetLogging:", "Check if register packets ('g', 'G', 'p', and 'P' support having the thread ID prefix"));
@@ -1026,7 +1027,6 @@ RNBRemote::ThreadFunctionReadRemoteData(void *arg)
case rnb_success:
break;
- default:
case rnb_err:
DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned error %u", err);
done = true;
@@ -1228,7 +1228,9 @@ RNBRemote::InitializeRegisters (bool force)
register_map_entry_t reg_entry = {
regnum++, // register number starts at zero and goes up with no gaps
reg_data_offset, // Offset into register context data, no gaps between registers
- reg_sets[set].registers[reg] // DNBRegisterInfo
+ reg_sets[set].registers[reg], // DNBRegisterInfo
+ {},
+ {},
};
name_to_regnum[reg_entry.nub_info.name] = reg_entry.debugserver_regnum;
@@ -2571,13 +2573,13 @@ RNBRemote::DispatchQueueOffsets::GetThreadQueueInfo (nub_process_t pid,
nub_addr_t pointer_to_label_address = dispatch_queue_t + dqo_label;
nub_addr_t label_addr = DNBProcessMemoryReadPointer (pid, pointer_to_label_address);
if (label_addr)
- queue_name = std::move(DNBProcessMemoryReadCString (pid, label_addr));
+ queue_name = DNBProcessMemoryReadCString(pid, label_addr);
}
else
{
// libdispatch versions 1-3, dispatch name is a fixed width char array
// in the queue structure.
- queue_name = std::move(DNBProcessMemoryReadCStringFixed(pid, dispatch_queue_t + dqo_label, dqo_label_size));
+ queue_name = DNBProcessMemoryReadCStringFixed(pid, dispatch_queue_t + dqo_label, dqo_label_size);
}
}
}
@@ -3554,13 +3556,6 @@ RNBRemote::HandlePacket_v (const char *p)
}
else if (strstr (p, "vCont") == p)
{
- typedef struct
- {
- nub_thread_t tid;
- char action;
- int signal;
- } vcont_action_t;
-
DNBThreadResumeActions thread_actions;
char *c = (char *)(p += strlen("vCont"));
char *c_end = c + strlen(c);
@@ -4433,6 +4428,7 @@ RNBRemote::HandlePacket_stop_process (const char *p)
{
// If we failed to interrupt the process, then send a stop
// reply packet as the process was probably already stopped
+ DNBLogThreaded ("RNBRemote::HandlePacket_stop_process() sending extra stop reply because DNBProcessInterrupt returned false");
HandlePacket_last_signal (NULL);
}
return rnb_success;
@@ -4645,15 +4641,9 @@ RNBRemote::HandlePacket_qHostInfo (const char *p)
uint64_t major, minor, patch;
if (DNBGetOSVersionNumbers (&major, &minor, &patch))
{
- strm << "osmajor:" << major << ";";
- strm << "osminor:" << minor << ";";
- strm << "ospatch:" << patch << ";";
-
- strm << "version:" << major << "." << minor;
- if (patch != 0)
- {
+ strm << "os_version:" << major << "." << minor;
+ if (patch != UINT64_MAX)
strm << "." << patch;
- }
strm << ";";
}
@@ -5072,6 +5062,122 @@ get_integer_value_for_key_name_from_json (const char *key, const char *json_stri
}
+// A helper function that retrieves a boolean value from
+// a one-level-deep JSON dictionary of key-value pairs. e.g.
+// jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}]
+
+// Returns true if it was able to find the key name, and sets the 'value'
+// argument to the value found.
+
+bool
+get_boolean_value_for_key_name_from_json (const char *key, const char *json_string, bool &value)
+{
+ std::string key_with_quotes = "\"";
+ key_with_quotes += key;
+ key_with_quotes += "\"";
+ const char *c = strstr (json_string, key_with_quotes.c_str());
+ if (c)
+ {
+ c += key_with_quotes.size();
+
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+
+ if (*c == ':')
+ {
+ c++;
+
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+
+ if (strncmp (c, "true", 4) == 0)
+ {
+ value = true;
+ return true;
+ } else if (strncmp (c, "false", 5) == 0)
+ {
+ value = false;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// A helper function that reads an array of uint64_t's from
+// a one-level-deep JSON dictionary of key-value pairs. e.g.
+// jGetLoadedDynamicLibrariesInfos:{"solib_addrs":[31345823,7768020384,7310483024]}]
+
+// Returns true if it was able to find the key name, false if it did not.
+// "ints" will have all integers found in the array appended to it.
+
+bool
+get_array_of_ints_value_for_key_name_from_json (const char *key, const char *json_string, std::vector<uint64_t> &ints)
+{
+ std::string key_with_quotes = "\"";
+ key_with_quotes += key;
+ key_with_quotes += "\"";
+ const char *c = strstr (json_string, key_with_quotes.c_str());
+ if (c)
+ {
+ c += key_with_quotes.size();
+
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+
+ if (*c == ':')
+ {
+ c++;
+
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+
+ if (*c == '[')
+ {
+ c++;
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+ while (1)
+ {
+ if (!isdigit (*c))
+ {
+ return true;
+ }
+
+ errno = 0;
+ char *endptr;
+ uint64_t value = strtoul (c, &endptr, 10);
+ if (errno == 0)
+ {
+ ints.push_back (value);
+ }
+ else
+ {
+ break;
+ }
+ if (endptr == c || endptr == nullptr || *endptr == '\0')
+ {
+ break;
+ }
+ c = endptr;
+
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+ if (*c == ',')
+ c++;
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+ if (*c == ']')
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
JSONGenerator::ObjectSP
RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only)
{
@@ -5499,6 +5605,20 @@ RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p)
return SendPacket ("OK");
}
+// This packet may be called in one of three ways:
+//
+// jGetLoadedDynamicLibrariesInfos:{"image_count":40,"image_list_address":4295244704}
+// Look for an array of the old dyld_all_image_infos style of binary infos at the image_list_address.
+// This an array of {void* load_addr, void* mod_date, void* pathname}
+//
+// jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}
+// Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to get a list of all the
+// libraries loaded
+//
+// jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]}
+// Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to get the information
+// about the libraries loaded at these addresses.
+//
rnb_err_t
RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p)
{
@@ -5516,28 +5636,81 @@ RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p)
{
p += strlen (get_loaded_dynamic_libraries_infos_str);
- nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p);
- nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p);
+ JSONGenerator::ObjectSP json_sp;
+
+ std::vector<uint64_t> macho_addresses;
+ bool fetch_all_solibs = false;
+ if (get_boolean_value_for_key_name_from_json ("fetch_all_solibs", p, fetch_all_solibs) && fetch_all_solibs)
+ {
+ json_sp = DNBGetAllLoadedLibrariesInfos (pid);
+ }
+ else if (get_array_of_ints_value_for_key_name_from_json ("solib_addresses", p, macho_addresses))
+ {
+ json_sp = DNBGetLibrariesInfoForAddresses (pid, macho_addresses);
+ }
+ else
+ {
+ nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p);
+ nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p);
+
+ if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS)
+ {
+ json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count);
+ }
+ }
- if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS)
+ if (json_sp.get())
{
- JSONGenerator::ObjectSP json_sp;
+ std::ostringstream json_str;
+ json_sp->Dump (json_str);
+ if (json_str.str().size() > 0)
+ {
+ std::string json_str_quoted = binary_encode_string (json_str.str());
+ return SendPacket (json_str_quoted.c_str());
+ }
+ else
+ {
+ SendPacket ("E84");
+ }
+ }
+ }
+ return SendPacket ("OK");
+}
- json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count);
+// This packet does not currently take any arguments. So the behavior is
+// jGetSharedCacheInfo:{}
+// send information about the inferior's shared cache
+// jGetSharedCacheInfo:
+// send "OK" to indicate that this packet is supported
+rnb_err_t
+RNBRemote::HandlePacket_jGetSharedCacheInfo (const char *p)
+{
+ nub_process_t pid;
+ // If we haven't run the process yet, return an error.
+ if (!m_ctx.HasValidProcessID())
+ {
+ return SendPacket ("E85");
+ }
+
+ pid = m_ctx.ProcessID();
+
+ const char get_shared_cache_info_str[] = { "jGetSharedCacheInfo:{" };
+ if (strncmp (p, get_shared_cache_info_str, sizeof (get_shared_cache_info_str) - 1) == 0)
+ {
+ JSONGenerator::ObjectSP json_sp = DNBGetSharedCacheInfo (pid);
- if (json_sp.get())
+ if (json_sp.get())
+ {
+ std::ostringstream json_str;
+ json_sp->Dump (json_str);
+ if (json_str.str().size() > 0)
{
- std::ostringstream json_str;
- json_sp->Dump (json_str);
- if (json_str.str().size() > 0)
- {
- std::string json_str_quoted = binary_encode_string (json_str.str());
- return SendPacket (json_str_quoted.c_str());
- }
- else
- {
- SendPacket ("E84");
- }
+ std::string json_str_quoted = binary_encode_string (json_str.str());
+ return SendPacket (json_str_quoted.c_str());
+ }
+ else
+ {
+ SendPacket ("E86");
}
}
}
@@ -5693,7 +5866,7 @@ RNBRemote::HandlePacket_qSymbol (const char *command)
if (*p)
{
// We have a symbol name
- symbol_name = std::move(decode_hex_ascii_string(p));
+ symbol_name = decode_hex_ascii_string(p);
if (!symbol_value_str.empty())
{
nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16);
@@ -5863,7 +6036,7 @@ RNBRemote::HandlePacket_qProcessInfo (const char *p)
DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_MACOSX -> 'ostype:macosx;'");
break;
-#if defined (TARGET_OS_TV) && TARGET_OS_TV == 1
+#if defined (LC_VERSION_MIN_TVOS)
case LC_VERSION_MIN_TVOS:
os_handled = true;
rep << "ostype:tvos;";
@@ -5871,7 +6044,7 @@ RNBRemote::HandlePacket_qProcessInfo (const char *p)
break;
#endif
-#if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
+#if defined (LC_VERSION_MIN_WATCHOS)
case LC_VERSION_MIN_WATCHOS:
os_handled = true;
rep << "ostype:watchos;";
diff --git a/tools/debugserver/source/RNBRemote.h b/tools/debugserver/source/RNBRemote.h
index 68dd8c52ea38..1bf7535e141d 100644
--- a/tools/debugserver/source/RNBRemote.h
+++ b/tools/debugserver/source/RNBRemote.h
@@ -105,6 +105,7 @@ public:
json_query_thread_extended_info,// 'jThreadExtendedInfo'
json_query_get_loaded_dynamic_libraries_infos, // 'jGetLoadedDynamicLibrariesInfos'
json_query_threads_info, // 'jThreadsInfo'
+ json_query_get_shared_cache_info, // 'jGetSharedCacheInfo'
pass_signals_to_inferior, // 'QPassSignals'
start_noack_mode, // 'QStartNoAckMode'
prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID
@@ -194,6 +195,7 @@ public:
rnb_err_t HandlePacket_jThreadExtendedInfo (const char *p);
rnb_err_t HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p);
rnb_err_t HandlePacket_jThreadsInfo (const char *p);
+ rnb_err_t HandlePacket_jGetSharedCacheInfo (const char *p);
rnb_err_t HandlePacket_qThreadExtraInfo (const char *p);
rnb_err_t HandlePacket_qThreadStopInfo (const char *p);
rnb_err_t HandlePacket_qHostInfo (const char *p);
diff --git a/tools/debugserver/source/debugserver.cpp b/tools/debugserver/source/debugserver.cpp
index 78990a671d82..a22f046771d9 100644
--- a/tools/debugserver/source/debugserver.cpp
+++ b/tools/debugserver/source/debugserver.cpp
@@ -824,8 +824,9 @@ FileLogCallback(void *baton, uint32_t flags, const char *format, va_list args)
if (baton == NULL || format == NULL)
return;
- ::vfprintf ((FILE *)baton, format, args);
- ::fprintf ((FILE *)baton, "\n");
+ ::vfprintf((FILE *)baton, format, args);
+ ::fprintf((FILE *)baton, "\n");
+ ::fflush((FILE *)baton);
}
@@ -885,6 +886,10 @@ static struct option g_long_options[] =
int
main (int argc, char *argv[])
{
+ // If debugserver is launched with DYLD_INSERT_LIBRARIES, unset it so we
+ // don't spawn child processes with this enabled.
+ unsetenv("DYLD_INSERT_LIBRARIES");
+
const char *argv_sub_zero = argv[0]; // save a copy of argv[0] for error reporting post-launch
#if defined (__APPLE__)
@@ -1076,7 +1081,7 @@ main (int argc, char *argv[])
case 'K':
g_detach_on_error = false;
-
+ break;
case 'W':
if (optarg && optarg[0])
working_dir.assign(optarg);
diff --git a/tools/driver/Driver.cpp b/tools/driver/Driver.cpp
index 0b72e22c80c8..c057d71a8300 100644
--- a/tools/driver/Driver.cpp
+++ b/tools/driver/Driver.cpp
@@ -27,7 +27,6 @@
#include <string>
-#include <thread>
#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
@@ -37,10 +36,13 @@
#include "lldb/API/SBHostOS.h"
#include "lldb/API/SBLanguageRuntime.h"
#include "lldb/API/SBListener.h"
+#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStringList.h"
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
-#include "lldb/API/SBProcess.h"
+#include "llvm/Support/ConvertUTF.h"
+#include <thread>
#if !defined(__APPLE__)
#include "llvm/Support/DataTypes.h"
@@ -441,13 +443,24 @@ Driver::OptionData::Clear ()
m_script_lang = lldb::eScriptLanguageDefault;
m_initial_commands.clear ();
m_after_file_commands.clear ();
- // If there is a local .lldbinit, source that:
- SBFileSpec local_lldbinit("./.lldbinit", true);
- if (local_lldbinit.Exists())
+
+ // If there is a local .lldbinit, add that to the
+ // list of things to be sourced, if the settings
+ // permit it.
+ SBFileSpec local_lldbinit (".lldbinit", true);
+
+ SBFileSpec homedir_dot_lldb = SBHostOS::GetUserHomeDirectory();
+ homedir_dot_lldb.AppendPathComponent (".lldbinit");
+
+ // Only read .lldbinit in the current working directory
+ // if it's not the same as the .lldbinit in the home
+ // directory (which is already being read in).
+ if (local_lldbinit.Exists()
+ && strcmp (local_lldbinit.GetDirectory(), homedir_dot_lldb.GetDirectory()) != 0)
{
char path[2048];
local_lldbinit.GetPath(path, 2047);
- InitialCmdEntry entry(path, true, true);
+ InitialCmdEntry entry(path, true, true, true);
m_after_file_commands.push_back (entry);
}
@@ -486,18 +499,18 @@ Driver::OptionData::AddInitialCommand (const char *command, CommandPlacement pla
{
SBFileSpec file(command);
if (file.Exists())
- command_set->push_back (InitialCmdEntry(command, is_file));
+ command_set->push_back (InitialCmdEntry(command, is_file, false));
else if (file.ResolveExecutableLocation())
{
char final_path[PATH_MAX];
file.GetPath (final_path, sizeof(final_path));
- command_set->push_back (InitialCmdEntry(final_path, is_file));
+ command_set->push_back (InitialCmdEntry(final_path, is_file, false));
}
else
error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
}
else
- command_set->push_back (InitialCmdEntry(command, is_file));
+ command_set->push_back (InitialCmdEntry(command, is_file, false));
}
void
@@ -550,6 +563,30 @@ Driver::WriteCommandsForSourcing (CommandPlacement placement, SBStream &strm)
const char *command = command_entry.contents.c_str();
if (command_entry.is_file)
{
+ // If this command_entry is a file to be sourced, and it's the ./.lldbinit file (the .lldbinit
+ // file in the current working directory), only read it if target.load-cwd-lldbinit is 'true'.
+ if (command_entry.is_cwd_lldbinit_file_read)
+ {
+ SBStringList strlist = m_debugger.GetInternalVariableValue ("target.load-cwd-lldbinit",
+ m_debugger.GetInstanceName());
+ if (strlist.GetSize() == 1 && strcmp (strlist.GetStringAtIndex(0), "warn") == 0)
+ {
+ FILE *output = m_debugger.GetOutputFileHandle ();
+ ::fprintf (output,
+ "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.\n");
+ return;
+ }
+ if (strlist.GetSize() == 1 && strcmp (strlist.GetStringAtIndex(0), "false") == 0)
+ {
+ return;
+ }
+ }
bool source_quietly = m_option_data.m_source_quietly || command_entry.source_quietly;
strm.Printf("command source -s %i '%s'\n", source_quietly, command);
}
@@ -914,7 +951,8 @@ PrepareCommandsForSourcing (const char *commands_data, size_t commands_size, int
{
fprintf(stderr, "error: write(%i, %p, %" PRIu64 ") failed (errno = %i) "
"when trying to open LLDB commands pipe\n",
- fds[WRITE], commands_data, static_cast<uint64_t>(commands_size), errno);
+ fds[WRITE], static_cast<const void *>(commands_data),
+ static_cast<uint64_t>(commands_size), errno);
}
else if (static_cast<size_t>(nrwr) == commands_size)
{
@@ -999,7 +1037,12 @@ Driver::MainLoop ()
atexit (reset_stdin_termios);
}
+#ifndef _MSC_VER
+ // Disabling stdin buffering with MSVC's 2015 CRT exposes a bug in fgets
+ // which causes it to miss newlines depending on whether there have been an
+ // odd or even number of characters. Bug has been reported to MS via Connect.
::setbuf (stdin, NULL);
+#endif
::setbuf (stdout, NULL);
m_debugger.SetErrorFileHandle (stderr, false);
@@ -1032,7 +1075,7 @@ Driver::MainLoop ()
SBStream commands_stream;
// First source in the commands specified to be run before the file arguments are processed.
- WriteCommandsForSourcing(eCommandPlacementBeforeFile, commands_stream);
+ WriteCommandsForSourcing (eCommandPlacementBeforeFile, commands_stream);
const size_t num_args = m_option_data.m_args.size();
if (num_args > 0)
@@ -1245,7 +1288,9 @@ sigint_handler (int signo)
void
sigtstp_handler (int signo)
{
- g_driver->GetDebugger().SaveInputTerminalState();
+ if (g_driver)
+ g_driver->GetDebugger().SaveInputTerminalState();
+
signal (signo, SIG_DFL);
kill (getpid(), signo);
signal (signo, sigtstp_handler);
@@ -1254,50 +1299,64 @@ sigtstp_handler (int signo)
void
sigcont_handler (int signo)
{
- g_driver->GetDebugger().RestoreInputTerminalState();
+ if (g_driver)
+ g_driver->GetDebugger().RestoreInputTerminalState();
+
signal (signo, SIG_DFL);
kill (getpid(), signo);
signal (signo, sigcont_handler);
}
int
-main (int argc, char const *argv[], const char *envp[])
+#ifdef WIN32
+wmain(int argc, wchar_t const *wargv[])
+#else
+main(int argc, char const *argv[])
+#endif
{
-#ifdef _MSC_VER
- // disable buffering on windows
- setvbuf(stdout, NULL, _IONBF, 0);
- setvbuf(stdin , NULL, _IONBF, 0);
+#ifdef _WIN32
+ // Convert wide arguments to UTF-8
+ std::vector<std::string> argvStrings(argc);
+ std::vector<const char *> argvPointers(argc);
+ for (int i = 0; i != argc; ++i)
+ {
+ llvm::convertWideToUTF8(wargv[i], argvStrings[i]);
+ argvPointers[i] = argvStrings[i].c_str();
+ }
+ const char **argv = argvPointers.data();
#endif
- SBDebugger::Initialize();
-
- SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
+ SBDebugger::Initialize();
- signal (SIGPIPE, SIG_IGN);
- signal (SIGWINCH, sigwinch_handler);
- signal (SIGINT, sigint_handler);
- signal (SIGTSTP, sigtstp_handler);
- signal (SIGCONT, sigcont_handler);
+ SBHostOS::ThreadCreated("<lldb.driver.main-thread>");
- // Create a scope for driver so that the driver object will destroy itself
- // before SBDebugger::Terminate() is called.
- {
- Driver driver;
+ signal(SIGINT, sigint_handler);
+#if !defined(_MSC_VER)
+ signal(SIGPIPE, SIG_IGN);
+ signal(SIGWINCH, sigwinch_handler);
+ signal(SIGTSTP, sigtstp_handler);
+ signal(SIGCONT, sigcont_handler);
+#endif
- bool exiting = false;
- SBError error (driver.ParseArgs (argc, argv, stdout, exiting));
- if (error.Fail())
+ // Create a scope for driver so that the driver object will destroy itself
+ // before SBDebugger::Terminate() is called.
{
- const char *error_cstr = error.GetCString ();
- if (error_cstr)
- ::fprintf (stderr, "error: %s\n", error_cstr);
- }
- else if (!exiting)
- {
- driver.MainLoop ();
+ Driver driver;
+
+ bool exiting = false;
+ SBError error(driver.ParseArgs(argc, argv, stdout, exiting));
+ if (error.Fail())
+ {
+ const char *error_cstr = error.GetCString();
+ if (error_cstr)
+ ::fprintf(stderr, "error: %s\n", error_cstr);
+ }
+ else if (!exiting)
+ {
+ driver.MainLoop();
+ }
}
- }
- SBDebugger::Terminate();
- return 0;
+ SBDebugger::Terminate();
+ return 0;
}
diff --git a/tools/driver/Driver.h b/tools/driver/Driver.h
index 639ac41d7fe6..8ac59240bc26 100644
--- a/tools/driver/Driver.h
+++ b/tools/driver/Driver.h
@@ -81,14 +81,16 @@ public:
struct InitialCmdEntry
{
- InitialCmdEntry (const char *in_contents, bool in_is_file, bool in_quiet = false) :
+ InitialCmdEntry (const char *in_contents, bool in_is_file, bool is_cwd_lldbinit_file_read, bool in_quiet = false) :
contents (in_contents),
is_file (in_is_file),
- source_quietly(in_quiet)
+ is_cwd_lldbinit_file_read (is_cwd_lldbinit_file_read),
+ source_quietly (in_quiet)
{}
std::string contents;
bool is_file;
+ bool is_cwd_lldbinit_file_read; // if this is reading ./.lldbinit - so we may skip if not permitted
bool source_quietly;
};
diff --git a/tools/driver/Makefile b/tools/driver/Makefile
deleted file mode 100644
index 05a245721bde..000000000000
--- a/tools/driver/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-##===- tools/driver/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 := ../..
-
-TOOLNAME = lldb
-
-NO_PEDANTIC = 1
-
-include $(LLDB_LEVEL)/Makefile
-
-ifneq ($(HOST_OS),MingW)
-LLVMLibsOptions += -ledit -llldb -llldbUtility
-else
-LLVMLibsOptions += -llldb -llldbUtility
-CPP.Flags += -DIMPORT_LIBLLDB
-endif
-
-ifeq ($(HOST_OS),Darwin)
- LLVMLibsOptions += -Wl,-rpath,@loader_path/../lib/
- LLVMLibsOptions += -Wl,-sectcreate -Wl,__TEXT -Wl,__info_plist -Wl,"$(PROJ_SRC_DIR)/lldb-Info.plist"
-endif
-
-ifneq (,$(filter $(HOST_OS), Linux GNU/kFreeBSD NetBSD))
- LLVMLibsOptions += -Wl,-rpath,$(LibDir)
-endif
-
-ifeq ($(HOST_OS),FreeBSD)
- CPP.Flags += -I/usr/include/edit #-v
- LLVMLibsOptions += -Wl,-rpath,$(LibDir)
-endif
diff --git a/tools/driver/Platform.cpp b/tools/driver/Platform.cpp
index a49161540872..88c0aa1e95c8 100644
--- a/tools/driver/Platform.cpp
+++ b/tools/driver/Platform.cpp
@@ -16,21 +16,6 @@
#include "Platform.h"
-// the control handler or SIGINT handler
-static sighandler_t _ctrlHandler = NULL;
-
-// the default console control handler
-BOOL
-WINAPI CtrlHandler (DWORD ctrlType)
-{
- if ( _ctrlHandler != NULL )
- {
- _ctrlHandler( 0 );
- return TRUE;
- }
- return FALSE;
-}
-
int
ioctl (int d, int request, ...)
{
@@ -84,29 +69,4 @@ tcgetattr (int fildes, struct termios *termios_p)
return -1;
}
-#ifdef _MSC_VER
-sighandler_t
-signal (int sig, sighandler_t sigFunc)
-{
- switch ( sig )
- {
- case ( SIGINT ):
- {
- _ctrlHandler = sigFunc;
- SetConsoleCtrlHandler( CtrlHandler, TRUE );
- }
- break;
- case ( SIGPIPE ):
- case ( SIGWINCH ):
- case ( SIGTSTP ):
- case ( SIGCONT ):
- // ignore these for now
- break;
- default:
- assert( !"Not implemented!" );
- }
- return 0;
-}
-#endif
-
#endif
diff --git a/tools/driver/Platform.h b/tools/driver/Platform.h
index c42d7e3da9d4..15e21f143bb0 100644
--- a/tools/driver/Platform.h
+++ b/tools/driver/Platform.h
@@ -12,12 +12,11 @@
#if defined( _WIN32 )
- // this will stop signal.h being included
- #define _INC_SIGNAL
#include "lldb/Host/HostGetOpt.h"
#include <io.h>
#if defined( _MSC_VER )
#include <eh.h>
+ #include <signal.h>
#endif
#include <inttypes.h>
#include "lldb/Host/windows/windows.h"
@@ -37,17 +36,6 @@
// ioctls.h
#define TIOCGWINSZ 0x5413
-
- // signal handler function pointer type
- typedef void(*sighandler_t)(int);
-
- // signal.h
- #define SIGINT 2
- // default handler
- #define SIG_DFL ( (sighandler_t) -1 )
- // ignored
- #define SIG_IGN ( (sighandler_t) -2 )
-
// signal.h
#define SIGPIPE 13
#define SIGCONT 18
@@ -80,7 +68,6 @@
};
typedef long pid_t;
#define snprintf _snprintf
- extern sighandler_t signal( int sig, sighandler_t );
#define PATH_MAX MAX_PATH
#endif
diff --git a/tools/driver/lldb-Info.plist b/tools/driver/lldb-Info.plist
index 7c1bfc734a7f..5a68a8b7adb5 100644
--- a/tools/driver/lldb-Info.plist
+++ b/tools/driver/lldb-Info.plist
@@ -11,7 +11,7 @@
<key>CFBundleName</key>
<string>lldb</string>
<key>CFBundleVersion</key>
- <string>2</string>
+ <string>360.99.0</string>
<key>SecTaskAccess</key>
<array>
<string>allowed</string>
diff --git a/tools/lldb-mi/CMakeLists.txt b/tools/lldb-mi/CMakeLists.txt
index 7fd6ed199e9d..79f657a3ddda 100644
--- a/tools/lldb-mi/CMakeLists.txt
+++ b/tools/lldb-mi/CMakeLists.txt
@@ -73,7 +73,6 @@ set(LLDB_MI_SOURCES
MIUtilString.cpp
MIUtilThreadBaseStd.cpp
MIUtilVariant.cpp
- Platform.cpp
)
if ( CMAKE_SYSTEM_NAME MATCHES "Windows" OR CMAKE_SYSTEM_NAME MATCHES "NetBSD" )
@@ -83,8 +82,6 @@ if ( CMAKE_SYSTEM_NAME MATCHES "Windows" OR CMAKE_SYSTEM_NAME MATCHES "NetBSD" )
)
endif ()
-include(../../cmake/LLDBDependencies.cmake)
-
add_lldb_executable(lldb-mi ${LLDB_MI_SOURCES})
target_link_libraries(lldb-mi liblldb)
@@ -92,8 +89,6 @@ if ( NOT CMAKE_SYSTEM_NAME MATCHES "Windows" )
target_link_libraries(lldb-mi pthread)
endif ()
-# TODO: why isn't this done by add_lldb_executable?
-#target_link_libraries(lldb-mi ${LLDB_USED_LIBS})
llvm_config(lldb-mi ${LLVM_LINK_COMPONENTS})
set_target_properties(lldb-mi PROPERTIES VERSION ${LLDB_VERSION})
diff --git a/tools/lldb-mi/MICmdCmdBreak.cpp b/tools/lldb-mi/MICmdCmdBreak.cpp
index e758a3dcccef..7238200dfcac 100644
--- a/tools/lldb-mi/MICmdCmdBreak.cpp
+++ b/tools/lldb-mi/MICmdCmdBreak.cpp
@@ -568,19 +568,9 @@ CMICmdCmdBreakDisable::Acknowledge()
{
if (m_bBrkPtDisabledOk)
{
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", m_nBrkPtId));
- const CMICmnMIValueResult miValueResult("number", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueConst miValueConst2("n");
- const CMICmnMIValueResult miValueResult2("enabled", miValueConst2);
- miValueTuple.Add(miValueResult2);
- const CMICmnMIValueResult miValueResult3("bkpt", miValueTuple);
- const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3);
- bool bOk = CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString());
-
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
m_miResultRecord = miRecordResult;
- return bOk;
+ return MIstatus::success;
}
const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
@@ -683,7 +673,7 @@ CMICmdCmdBreakEnable::Execute()
if (brkPt.IsValid())
{
m_bBrkPtEnabledOk = true;
- brkPt.SetEnabled(false);
+ brkPt.SetEnabled(true);
m_nBrkPtId = nBrk;
}
@@ -704,19 +694,9 @@ CMICmdCmdBreakEnable::Acknowledge()
{
if (m_bBrkPtEnabledOk)
{
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", m_nBrkPtId));
- const CMICmnMIValueResult miValueResult("number", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueConst miValueConst2("y");
- const CMICmnMIValueResult miValueResult2("enabled", miValueConst2);
- miValueTuple.Add(miValueResult2);
- const CMICmnMIValueResult miValueResult3("bkpt", miValueTuple);
- const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3);
- bool bOk = CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString());
-
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
m_miResultRecord = miRecordResult;
- return bOk;
+ return MIstatus::success;
}
const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
diff --git a/tools/lldb-mi/MICmdCmdData.cpp b/tools/lldb-mi/MICmdCmdData.cpp
index 0e0cf12b0080..a46fb5563ce7 100644
--- a/tools/lldb-mi/MICmdCmdData.cpp
+++ b/tools/lldb-mi/MICmdCmdData.cpp
@@ -117,7 +117,8 @@ CMICmdCmdDataEvaluateExpression::Execute()
lldb::SBFrame frame = thread.GetSelectedFrame();
lldb::SBValue value = frame.EvaluateExpression(rExpression.c_str());
- if (!value.IsValid() || value.GetError().Fail())
+ m_Error = value.GetError();
+ if (!value.IsValid() || m_Error.Fail())
value = frame.FindVariable(rExpression.c_str());
const CMICmnLLDBUtilSBValue utilValue(value, true);
if (!utilValue.IsValid() || utilValue.IsValueUnknown())
@@ -177,8 +178,10 @@ CMICmdCmdDataEvaluateExpression::Acknowledge()
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
-
- const CMICmnMIValueConst miValueConst("Could not evaluate expression");
+ CMIUtilString mi_error_msg = "Could not evaluate expression";
+ if (const char* err_msg = m_Error.GetCString())
+ mi_error_msg = err_msg;
+ const CMICmnMIValueConst miValueConst(mi_error_msg.Escape(true));
const CMICmnMIValueResult miValueResult("msg", miValueConst);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
m_miResultRecord = miRecordResult;
diff --git a/tools/lldb-mi/MICmdCmdData.h b/tools/lldb-mi/MICmdCmdData.h
index 028c71387f31..a67fd6beaf72 100644
--- a/tools/lldb-mi/MICmdCmdData.h
+++ b/tools/lldb-mi/MICmdCmdData.h
@@ -32,6 +32,7 @@
// Third party headers:
#include "lldb/API/SBCommandReturnObject.h"
+#include "lldb/API/SBError.h"
// In-house headers:
#include "MICmdBase.h"
@@ -71,6 +72,7 @@ class CMICmdCmdDataEvaluateExpression : public CMICmdBase
private:
bool m_bExpressionValid; // True = yes is valid, false = not valid
bool m_bEvaluatedExpression; // True = yes is expression evaluated, false = failed
+ lldb::SBError m_Error; // Error object, which is examined when m_bEvaluatedExpression is false
CMIUtilString m_strValue;
CMICmnMIValueTuple m_miValueTuple;
bool m_bFoundInvalidChar; // True = yes found unexpected character in the expression, false = all ok
diff --git a/tools/lldb-mi/MICmdCmdThread.cpp b/tools/lldb-mi/MICmdCmdThread.cpp
index 823a3748248c..9435655762a9 100644
--- a/tools/lldb-mi/MICmdCmdThread.cpp
+++ b/tools/lldb-mi/MICmdCmdThread.cpp
@@ -29,9 +29,10 @@
// Throws: None.
//--
CMICmdCmdThreadInfo::CMICmdCmdThreadInfo()
- : m_bSingleThread(false)
- , m_bThreadInvalid(true)
- , m_constStrArgNamedThreadId("thread-id")
+ : m_bSingleThread(false),
+ m_bThreadInvalid(true),
+ m_constStrArgNamedThreadId("thread-id"),
+ m_bHasCurrentThread(false)
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "thread-info";
@@ -124,6 +125,15 @@ CMICmdCmdThreadInfo::Execute()
}
}
+ // -thread-info with multiple threads ends with the current thread id if any
+ if (thread.IsValid())
+ {
+ const CMIUtilString strId(CMIUtilString::Format("%d", thread.GetIndexID()));
+ CMICmnMIValueConst miValueCurrThreadId(strId);
+ m_miValueCurrThreadId = miValueCurrThreadId;
+ m_bHasCurrentThread = true;
+ }
+
return MIstatus::success;
}
@@ -179,7 +189,12 @@ CMICmdCmdThreadInfo::Acknowledge()
++it;
}
- const CMICmnMIValueResult miValueResult("threads", miValueList);
+ CMICmnMIValueResult miValueResult("threads", miValueList);
+ if (m_bHasCurrentThread)
+ {
+ CMIUtilString strCurrThreadId = "current-thread-id";
+ miValueResult.Add(strCurrThreadId, m_miValueCurrThreadId);
+ }
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
m_miResultRecord = miRecordResult;
diff --git a/tools/lldb-mi/MICmdCmdThread.h b/tools/lldb-mi/MICmdCmdThread.h
index 7031eabddc33..e3b0adca613a 100644
--- a/tools/lldb-mi/MICmdCmdThread.h
+++ b/tools/lldb-mi/MICmdCmdThread.h
@@ -60,4 +60,8 @@ class CMICmdCmdThreadInfo : public CMICmdBase
bool m_bThreadInvalid; // True = invalid, false = ok
VecMIValueTuple_t m_vecMIValueTuple;
const CMIUtilString m_constStrArgNamedThreadId;
+
+ // mi value of current-thread-id if multiple threads are requested
+ bool m_bHasCurrentThread;
+ CMICmnMIValue m_miValueCurrThreadId;
};
diff --git a/tools/lldb-mi/MICmdCmdVar.cpp b/tools/lldb-mi/MICmdCmdVar.cpp
index 8e30a2ad0da4..d8e81a44b9d2 100644
--- a/tools/lldb-mi/MICmdCmdVar.cpp
+++ b/tools/lldb-mi/MICmdCmdVar.cpp
@@ -201,9 +201,7 @@ CMICmdCmdVarCreate::Execute()
}
else
{
- lldb::SBStream err;
- if (value.GetError().GetDescription(err))
- m_strValue = err.GetData();
+ m_strValue = value.GetError().GetCString();
}
return MIstatus::success;
diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
index ef99ac9a4207..4ded517a14c6 100644
--- a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
+++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
@@ -18,15 +18,16 @@
#include "lldb/API/SBBreakpointLocation.h"
// In-house headers:
+#include "MICmdData.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmnLLDBDebugger.h"
-#include "MICmnResources.h"
+#include "MICmnLLDBUtilSBValue.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"
#include "MICmnMIValueList.h"
#include "MICmnMIValueTuple.h"
-#include "MICmdData.h"
-#include "MICmnLLDBUtilSBValue.h"
+#include "MICmnResources.h"
+#include "Platform.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebugSessionInfo constructor.
@@ -452,7 +453,12 @@ CMICmnLLDBDebugSessionInfo::MIResponseForVariableInfoInternal(const VariableInfo
{
CMICmnMIValueTuple miValueTuple;
lldb::SBValue value = vwrSBValueList.GetValueAtIndex(i);
- const CMICmnMIValueConst miValueConst(value.GetName());
+ // If one stops inside try block with, which catch clause type is unnamed
+ // (e.g std::exception&) then value name will be nullptr as well as value pointer
+ const char* name = value.GetName();
+ if (name == nullptr)
+ continue;
+ const CMICmnMIValueConst miValueConst(name);
const CMICmnMIValueResult miValueResultName("name", miValueConst);
if (vbMarkArgs && vbIsArgs)
{
@@ -609,7 +615,7 @@ CMICmnLLDBDebugSessionInfo::GetFrameInfo(const lldb::SBFrame &vrFrame, lldb::add
{
lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
- static char pBuffer[MAX_PATH];
+ static char pBuffer[PATH_MAX];
const MIuint nBytes = rFrame.GetLineEntry().GetFileSpec().GetPath(&pBuffer[0], sizeof(pBuffer));
MIunused(nBytes);
CMIUtilString strResolvedPath(&pBuffer[0]);
diff --git a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
index 848529f0b46a..f92595ac494a 100644
--- a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
+++ b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
@@ -770,7 +770,8 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBCommandInterpreter(const lldb::SBEv
// m_pClientDriver->SetExitApplicationFlag();
// vrbYesExit = true;
// return MIstatus::success;
- //} break;
+ //}
+ break;
case lldb::SBCommandInterpreter::eBroadcastBitResetPrompt:
pEventType = "eBroadcastBitResetPrompt";
break;
diff --git a/tools/lldb-mi/MIUtilFileStd.cpp b/tools/lldb-mi/MIUtilFileStd.cpp
index 9e5d10d6ba38..ed80466b2df5 100644
--- a/tools/lldb-mi/MIUtilFileStd.cpp
+++ b/tools/lldb-mi/MIUtilFileStd.cpp
@@ -14,8 +14,11 @@
#include <cerrno>
// In-house headers:
-#include "MIUtilFileStd.h"
#include "MICmnResources.h"
+#include "MIUtilFileStd.h"
+#include "lldb/Host/FileSystem.h"
+
+#include "llvm/Support/ConvertUTF.h"
//++ ------------------------------------------------------------------------------------
// Details: CMIUtilFileStd constructor.
@@ -82,7 +85,14 @@ CMIUtilFileStd::CreateWrite(const CMIUtilString &vFileNamePath, bool &vwrbNewCre
m_pFileHandle = ::fopen(vFileNamePath.c_str(), "wb");
#else
// Open a file with exclusive write and shared read permissions
- m_pFileHandle = ::_fsopen(vFileNamePath.c_str(), "wb", _SH_DENYWR);
+ std::wstring path;
+ if (llvm::ConvertUTF8toWide(vFileNamePath.c_str(), path))
+ m_pFileHandle = ::_wfsopen(path.c_str(), L"wb", _SH_DENYWR);
+ else
+ {
+ errno = EINVAL;
+ m_pFileHandle = nullptr;
+ }
#endif // !defined( _MSC_VER )
if (m_pFileHandle == nullptr)
diff --git a/tools/lldb-mi/Makefile b/tools/lldb-mi/Makefile
deleted file mode 100644
index cdd766633b16..000000000000
--- a/tools/lldb-mi/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-##===- tools/lldb-mi/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 := ../..
-
-TOOLNAME = lldb-mi
-
-NO_PEDANTIC = 1
-
-LLVMLibsOptions += -ledit -llldb -llldbUtility
-LINK_COMPONENTS := support
-
-include $(LLDB_LEVEL)/Makefile
-
-ifeq ($(HOST_OS),Darwin)
- LLVMLibsOptions += -Wl,-rpath,@loader_path/../lib/
- LLVMLibsOptions += -Wl,-sectcreate -Wl,__TEXT -Wl,__info_plist -Wl,"$(PROJ_SRC_DIR)/lldb-Info.plist"
-endif
-
-ifneq (,$(filter $(HOST_OS), Linux GNU/kFreeBSD NetBSD))
- LLVMLibsOptions += -Wl,-rpath,$(LibDir) -lpthread
-endif
-
-ifeq ($(HOST_OS),FreeBSD)
- CPP.Flags += -I/usr/include/edit #-v
- LLVMLibsOptions += -Wl,-rpath,$(LibDir) -lpthread
-endif
diff --git a/tools/lldb-mi/Platform.cpp b/tools/lldb-mi/Platform.cpp
deleted file mode 100644
index 7e2eabf51b42..000000000000
--- a/tools/lldb-mi/Platform.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-//===-- Platform.cpp --------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// this file is only relevant for Visual C++
-#if defined(_MSC_VER)
-
-#include <process.h>
-#include <assert.h>
-
-#include "Platform.h"
-
-// the control handler or SIGINT handler
-static sighandler_t _ctrlHandler = NULL;
-
-// the default console control handler
-BOOL WINAPI CtrlHandler(DWORD ctrlType)
-{
- if (_ctrlHandler != NULL)
- {
- _ctrlHandler(SIGINT);
- return TRUE;
- }
- return FALSE;
-}
-
-sighandler_t
-signal(int sig, sighandler_t sigFunc)
-{
- switch (sig)
- {
- case (SIGINT):
- {
- _ctrlHandler = sigFunc;
- SetConsoleCtrlHandler(CtrlHandler, TRUE);
- }
- break;
- default:
- assert(!"Not implemented!");
- }
- return 0;
-}
-
-#endif
diff --git a/tools/lldb-mi/Platform.h b/tools/lldb-mi/Platform.h
index 093ceac0fb9d..9db8f7a156ce 100644
--- a/tools/lldb-mi/Platform.h
+++ b/tools/lldb-mi/Platform.h
@@ -10,12 +10,10 @@
#if defined(_MSC_VER)
-// this will stop signal.h being included
-#define _INC_SIGNAL
-
#include <io.h>
#include <eh.h>
#include <inttypes.h>
+#include <signal.h>
#include <lldb/Host/windows/Windows.h>
#include <lldb/Host/HostGetOpt.h>
@@ -60,7 +58,7 @@ struct termios
typedef long pid_t;
#define STDIN_FILENO 0
-#define PATH_MAX MAX_PATH
+#define PATH_MAX 32768
#define snprintf _snprintf
extern int ioctl(int d, int request, ...);
@@ -73,7 +71,6 @@ typedef void (*sighandler_t)(int);
// CODETAG_IOR_SIGNALS
// signal.h
-#define SIGINT 2 // Terminal interrupt signal
#define SIGQUIT 3 // Terminal quit signal
#define SIGKILL 9 // Kill (cannot be caught or ignored)
#define SIGPIPE 13 // Write on a pipe with no one to read it
@@ -81,10 +78,6 @@ typedef void (*sighandler_t)(int);
#define SIGTSTP 20 // Terminal stop signal
#define SIGSTOP 23 // Stop executing (cannot be caught or ignored)
#define SIGWINCH 28 // (== SIGVTALRM)
-#define SIG_DFL ((sighandler_t)-1) // Default handler
-#define SIG_IGN ((sighandler_t)-2) // Ignored
-
-extern sighandler_t signal(int sig, sighandler_t);
#else
diff --git a/tools/lldb-server/Makefile b/tools/lldb-server/Makefile
deleted file mode 100644
index 849b313dae8a..000000000000
--- a/tools/lldb-server/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-##===- tools/lldb-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 := ../..
-
-TOOLNAME = lldb-server
-
-LLVMLibsOptions += -llldb -llldbUtility
-
-LINK_COMPONENTS := support
-
-include $(LLDB_LEVEL)/Makefile
-
-ifeq ($(HOST_OS),Darwin)
- LLVMLibsOptions += -Wl,-rpath,@loader_path/../lib/
-endif
-
-ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD GNU/kFreeBSD NetBSD))
- LLVMLibsOptions += -Wl,-rpath,$(LibDir) -lpthread
-endif
diff --git a/tools/lldb-server/lldb-gdbserver.cpp b/tools/lldb-server/lldb-gdbserver.cpp
index df8cb6e68554..b8c59e29eb53 100644
--- a/tools/lldb-server/lldb-gdbserver.cpp
+++ b/tools/lldb-server/lldb-gdbserver.cpp
@@ -32,7 +32,6 @@
#include "lldb/Host/Pipe.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Target/Platform.h"
#include "Acceptor.h"
#include "LLDBServerUtilities.h"
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h"
@@ -62,7 +61,6 @@ static int g_verbose = 0;
static struct option g_long_options[] =
{
{ "debug", no_argument, &g_debug, 1 },
- { "platform", required_argument, NULL, 'p' },
{ "verbose", no_argument, &g_verbose, 1 },
{ "log-file", required_argument, NULL, 'l' },
{ "log-channels", required_argument, NULL, 'c' },
@@ -79,28 +77,9 @@ static struct option g_long_options[] =
//----------------------------------------------------------------------
// Watch for signals
//----------------------------------------------------------------------
-static int g_sigpipe_received = 0;
static int g_sighup_received_count = 0;
#ifndef _WIN32
-
-static void
-signal_handler(int signo)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- fprintf (stderr, "lldb-server:%s received signal %d\n", __FUNCTION__, signo);
- if (log)
- log->Printf ("lldb-server:%s received signal %d", __FUNCTION__, signo);
-
- switch (signo)
- {
- case SIGPIPE:
- g_sigpipe_received = 1;
- break;
- }
-}
-
static void
sighup_handler(MainLoopBase &mainloop)
{
@@ -121,7 +100,6 @@ display_usage (const char *progname, const char* subcommand)
fprintf(stderr, "Usage:\n %s %s "
"[--log-file log-file-name] "
"[--log-channels log-channel-list] "
- "[--platform platform_name] "
"[--setsid] "
"[--named-pipe named-pipe-path] "
"[--native-regs] "
@@ -131,66 +109,6 @@ display_usage (const char *progname, const char* subcommand)
exit(0);
}
-static void
-dump_available_platforms (FILE *output_file)
-{
- fprintf (output_file, "Available platform plugins:\n");
- for (int i = 0; ; ++i)
- {
- const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (i);
- const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (i);
-
- if (!plugin_name || !plugin_desc)
- break;
-
- fprintf (output_file, "%s\t%s\n", plugin_name, plugin_desc);
- }
-
- if ( Platform::GetHostPlatform () )
- {
- // add this since the default platform doesn't necessarily get registered by
- // the plugin name (e.g. 'host' doesn't show up as a
- // registered platform plugin even though it's the default).
- fprintf (output_file, "%s\tDefault platform for this host.\n", Platform::GetHostPlatform ()->GetPluginName ().AsCString ());
- }
-}
-
-static lldb::PlatformSP
-setup_platform (const std::string &platform_name)
-{
- lldb::PlatformSP platform_sp;
-
- if (platform_name.empty())
- {
- printf ("using the default platform: ");
- platform_sp = Platform::GetHostPlatform ();
- printf ("%s\n", platform_sp->GetPluginName ().AsCString ());
- return platform_sp;
- }
-
- Error error;
- platform_sp = Platform::Create (lldb_private::ConstString(platform_name), error);
- if (error.Fail ())
- {
- // the host platform isn't registered with that name (at
- // least, not always. Check if the given name matches
- // the default platform name. If so, use it.
- if ( Platform::GetHostPlatform () && ( Platform::GetHostPlatform ()->GetPluginName () == ConstString (platform_name.c_str()) ) )
- {
- platform_sp = Platform::GetHostPlatform ();
- }
- else
- {
- fprintf (stderr, "error: failed to create platform with name '%s'\n", platform_name.c_str());
- dump_available_platforms (stderr);
- exit (1);
- }
- }
- printf ("using platform: %s\n", platform_name.c_str ());
-
- return platform_sp;
-}
-
void
handle_attach_to_pid (GDBRemoteCommunicationServerLLGS &gdb_server, lldb::pid_t pid)
{
@@ -411,16 +329,9 @@ main_gdbserver (int argc, char *argv[])
MainLoop mainloop;
#ifndef _WIN32
// Setup signal handlers first thing.
- signal (SIGPIPE, signal_handler);
+ signal(SIGPIPE, SIG_IGN);
MainLoop::SignalHandleUP sighup_handle = mainloop.RegisterSignal(SIGHUP, sighup_handler, error);
#endif
-#ifdef __linux__
- // Block delivery of SIGCHLD on linux. NativeProcessLinux will read it using signalfd.
- sigset_t set;
- sigemptyset(&set);
- sigaddset(&set, SIGCHLD);
- pthread_sigmask(SIG_BLOCK, &set, NULL);
-#endif
const char *progname = argv[0];
const char *subcommand = argv[1];
@@ -428,7 +339,6 @@ main_gdbserver (int argc, char *argv[])
argv++;
int long_option_index = 0;
int ch;
- std::string platform_name;
std::string attach_target;
std::string named_pipe_path;
std::string log_file;
@@ -467,11 +377,6 @@ main_gdbserver (int argc, char *argv[])
log_channels = StringRef(optarg);
break;
- case 'p': // platform name
- if (optarg && optarg[0])
- platform_name = optarg;
- break;
-
case 'N': // named pipe
if (optarg && optarg[0])
named_pipe_path = optarg;
@@ -480,6 +385,7 @@ main_gdbserver (int argc, char *argv[])
case 'U': // unnamed pipe
if (optarg && optarg[0])
unnamed_pipe_fd = StringConvert::ToUInt32(optarg, -1);
+ break;
case 'r':
// Do nothing, native regs is the default these days
@@ -531,7 +437,7 @@ main_gdbserver (int argc, char *argv[])
exit(option_error);
}
- if (!LLDBServerUtilities::SetupLogging(log_file, log_channels, 0))
+ if (!LLDBServerUtilities::SetupLogging(log_file, log_channels, LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
return -1;
Log *log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_VERBOSE));
@@ -554,10 +460,7 @@ main_gdbserver (int argc, char *argv[])
exit(255);
}
- // Setup the platform that GDBRemoteCommunicationServerLLGS will use.
- lldb::PlatformSP platform_sp = setup_platform (platform_name);
-
- GDBRemoteCommunicationServerLLGS gdb_server (platform_sp, mainloop);
+ GDBRemoteCommunicationServerLLGS gdb_server(mainloop);
const char *const host_and_port = argv[0];
argc -= 1;
diff --git a/tools/lldb-server/lldb-server.cpp b/tools/lldb-server/lldb-server.cpp
index ec92b094f485..9ece640b2885 100644
--- a/tools/lldb-server/lldb-server.cpp
+++ b/tools/lldb-server/lldb-server.cpp
@@ -9,6 +9,7 @@
#include "lldb/Initialization/SystemLifetimeManager.h"
#include "lldb/Initialization/SystemInitializerCommon.h"
+#include "lldb/lldb-private.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ManagedStatic.h"
@@ -22,9 +23,10 @@ static void
display_usage (const char *progname)
{
fprintf(stderr, "Usage:\n"
+ " %s v[ersion]\n"
" %s g[dbserver] [options]\n"
" %s p[latform] [options]\n"
- "Invoke subcommand for additional help\n", progname, progname);
+ "Invoke subcommand for additional help\n", progname, progname, progname);
exit(0);
}
@@ -57,20 +59,24 @@ main (int argc, char *argv[])
display_usage(progname);
exit(option_error);
}
- else if (argv[1][0] == 'g')
- {
- initialize();
- main_gdbserver(argc, argv);
- terminate();
- }
- else if (argv[1][0] == 'p')
+
+ switch (argv[1][0])
{
- initialize();
- main_platform(argc, argv);
- terminate();
- }
- else {
- display_usage(progname);
- exit(option_error);
+ case 'g':
+ initialize();
+ main_gdbserver(argc, argv);
+ terminate();
+ break;
+ case 'p':
+ initialize();
+ main_platform(argc, argv);
+ terminate();
+ break;
+ case 'v':
+ fprintf(stderr, "%s\n", lldb_private::GetVersion());
+ break;
+ default:
+ display_usage(progname);
+ exit(option_error);
}
}
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index 94031accfec7..bdcb51675a0f 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -18,14 +18,32 @@ function(add_lldb_unittest test_name)
${ARGN}
)
+ add_custom_command(
+ TARGET ${test_name}
+ POST_BUILD
+ COMMAND "${CMAKE_COMMAND}" -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/Inputs)
+
lldb_link_common_libs(${test_name} EXE)
target_link_libraries(${test_name} ${CLANG_USED_LIBS} ${LLDB_SYSTEM_LIBS})
llvm_config(${test_name} ${LLVM_LINK_COMPONENTS})
endfunction()
+function(add_unittest_inputs test_name inputs)
+ foreach (INPUT ${inputs})
+ add_custom_command(
+ TARGET ${test_name}
+ POST_BUILD
+ COMMAND "${CMAKE_COMMAND}" -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Inputs/${INPUT} ${CMAKE_CURRENT_BINARY_DIR}/Inputs
+ COMMENT "Copying ${INPUT} to binary directory.")
+ endforeach()
+endfunction()
+
+add_subdirectory(Core)
add_subdirectory(Editline)
add_subdirectory(Expression)
add_subdirectory(Host)
add_subdirectory(Interpreter)
add_subdirectory(ScriptInterpreter)
+add_subdirectory(Symbol)
+add_subdirectory(SymbolFile)
add_subdirectory(Utility)
diff --git a/unittests/Core/CMakeLists.txt b/unittests/Core/CMakeLists.txt
new file mode 100644
index 000000000000..ad9def181de5
--- /dev/null
+++ b/unittests/Core/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_lldb_unittest(LLDBCoreTests
+ DataExtractorTest.cpp
+ ScalarTest.cpp
+ )
diff --git a/unittests/Core/DataExtractorTest.cpp b/unittests/Core/DataExtractorTest.cpp
new file mode 100644
index 000000000000..f22883875055
--- /dev/null
+++ b/unittests/Core/DataExtractorTest.cpp
@@ -0,0 +1,39 @@
+//===-- DataExtractorTest.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(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
+// Workaround for MSVC standard library bug, which fails to include <thread> when
+// exceptions are disabled.
+#include <eh.h>
+#endif
+
+#include "gtest/gtest.h"
+
+#include "lldb/Core/DataExtractor.h"
+
+using namespace lldb_private;
+
+TEST(DataExtractorTest, GetBitfield)
+{
+ char buffer[] = { 0x01, 0x23, 0x45, 0x67 };
+ DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, sizeof(void *));
+ DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *));
+
+ lldb::offset_t offset;
+
+ offset = 0;
+ ASSERT_EQ(buffer[1], LE.GetMaxU64Bitfield(&offset, sizeof(buffer), 8, 8));
+ offset = 0;
+ ASSERT_EQ(buffer[1], BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 8, 8));
+
+ offset = 0;
+ ASSERT_EQ(buffer[1], LE.GetMaxS64Bitfield(&offset, sizeof(buffer), 8, 8));
+ offset = 0;
+ ASSERT_EQ(buffer[1], BE.GetMaxS64Bitfield(&offset, sizeof(buffer), 8, 8));
+}
diff --git a/unittests/Core/ScalarTest.cpp b/unittests/Core/ScalarTest.cpp
new file mode 100644
index 000000000000..bf85f8e9623b
--- /dev/null
+++ b/unittests/Core/ScalarTest.cpp
@@ -0,0 +1,105 @@
+//===-- ScalarTest.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(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
+// Workaround for MSVC standard library bug, which fails to include <thread> when
+// exceptions are disabled.
+#include <eh.h>
+#endif
+
+#include "gtest/gtest.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Host/Endian.h"
+
+using namespace lldb_private;
+
+TEST(ScalarTest, RightShiftOperator)
+{
+ int a = 0x00001000;
+ int b = 0xFFFFFFFF;
+ int c = 4;
+ Scalar a_scalar(a);
+ Scalar b_scalar(b);
+ Scalar c_scalar(c);
+ ASSERT_EQ(a >> c, a_scalar >> c_scalar);
+ ASSERT_EQ(b >> c, b_scalar >> c_scalar);
+}
+
+TEST(ScalarTest, GetBytes)
+{
+ int a = 0x01020304;
+ long long b = 0x0102030405060708LL;
+ float c = 1234567.89e42;
+ double d = 1234567.89e42;
+ char e[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+ char f[32] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 };
+ Scalar a_scalar(a);
+ Scalar b_scalar(b);
+ Scalar c_scalar(c);
+ Scalar d_scalar(d);
+ Scalar e_scalar;
+ Scalar f_scalar;
+ DataExtractor e_data(e, sizeof(e), endian::InlHostByteOrder(), sizeof(void *));
+ Error e_error = e_scalar.SetValueFromData(e_data, lldb::eEncodingUint, sizeof(e));
+ DataExtractor f_data(f, sizeof(f), endian::InlHostByteOrder(), sizeof(void *));
+ Error f_error = f_scalar.SetValueFromData(f_data, lldb::eEncodingUint, sizeof(f));
+ ASSERT_EQ(0, memcmp(&a, a_scalar.GetBytes(), sizeof(a)));
+ ASSERT_EQ(0, memcmp(&b, b_scalar.GetBytes(), sizeof(b)));
+ ASSERT_EQ(0, memcmp(&c, c_scalar.GetBytes(), sizeof(c)));
+ ASSERT_EQ(0, memcmp(&d, d_scalar.GetBytes(), sizeof(d)));
+ ASSERT_EQ(0, e_error.Fail());
+ ASSERT_EQ(0, memcmp(e, e_scalar.GetBytes(), sizeof(e)));
+ ASSERT_EQ(0, f_error.Fail());
+ ASSERT_EQ(0, memcmp(f, f_scalar.GetBytes(), sizeof(f)));
+}
+
+TEST(ScalarTest, CastOperations)
+{
+ long long a = 0xf1f2f3f4f5f6f7f8LL;
+ Scalar a_scalar(a);
+ ASSERT_EQ((signed char)a, a_scalar.SChar());
+ ASSERT_EQ((unsigned char)a, a_scalar.UChar());
+ ASSERT_EQ((signed short)a, a_scalar.SShort());
+ ASSERT_EQ((unsigned short)a, a_scalar.UShort());
+ ASSERT_EQ((signed int)a, a_scalar.SInt());
+ ASSERT_EQ((unsigned int)a, a_scalar.UInt());
+ ASSERT_EQ((signed long)a, a_scalar.SLong());
+ ASSERT_EQ((unsigned long)a, a_scalar.ULong());
+ ASSERT_EQ((signed long long)a, a_scalar.SLongLong());
+ ASSERT_EQ((unsigned long long)a, a_scalar.ULongLong());
+}
+
+TEST(ScalarTest, ExtractBitfield)
+{
+ uint32_t len = sizeof(long long) * 8;
+
+ long long a1 = 0xf1f2f3f4f5f6f7f8LL;
+ long long b1 = 0xff1f2f3f4f5f6f7fLL;
+ Scalar s_scalar(a1);
+ ASSERT_TRUE(s_scalar.ExtractBitfield(0, 0));
+ ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1)));
+ ASSERT_TRUE(s_scalar.ExtractBitfield(len, 0));
+ ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1)));
+ ASSERT_TRUE(s_scalar.ExtractBitfield(len - 4, 4));
+ ASSERT_EQ(0, memcmp(&b1, s_scalar.GetBytes(), sizeof(b1)));
+
+ unsigned long long a2 = 0xf1f2f3f4f5f6f7f8ULL;
+ unsigned long long b2 = 0x0f1f2f3f4f5f6f7fULL;
+ Scalar u_scalar(a2);
+ ASSERT_TRUE(u_scalar.ExtractBitfield(0, 0));
+ ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2)));
+ ASSERT_TRUE(u_scalar.ExtractBitfield(len, 0));
+ ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2)));
+ ASSERT_TRUE(u_scalar.ExtractBitfield(len - 4, 4));
+ ASSERT_EQ(0, memcmp(&b2, u_scalar.GetBytes(), sizeof(b2)));
+}
diff --git a/unittests/Editline/EditlineTest.cpp b/unittests/Editline/EditlineTest.cpp
index d82ef4c17c77..e2552ffdd3b8 100644
--- a/unittests/Editline/EditlineTest.cpp
+++ b/unittests/Editline/EditlineTest.cpp
@@ -1,4 +1,4 @@
-//===-- EditlineTest.cpp -----------------------------------------*- C++ -*-===//
+//===-- EditlineTest.cpp ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -191,8 +191,9 @@ EditlineAdapter::SendLine (const std::string &line)
eoln,
eoln_length * sizeof (char));
- EXPECT_EQ (eoln_length * sizeof (char), input_bytes_written);
- return eoln_length * sizeof (char) == input_bytes_written;
+ EXPECT_NE(-1, input_bytes_written) << strerror(errno);
+ EXPECT_EQ (eoln_length * sizeof (char), size_t(input_bytes_written));
+ return eoln_length * sizeof (char) == size_t(input_bytes_written);
}
bool
@@ -293,49 +294,55 @@ EditlineAdapter::ConsumeAllOutput ()
}
}
-TEST (EditlineTest, EditlineReceivesSingleLineText)
+class EditlineTestFixture : public ::testing::Test
{
- setenv ("TERM", "vt100", 1);
+private:
+ EditlineAdapter _el_adapter;
+ std::shared_ptr<std::thread> _sp_output_thread;
- // Create an editline.
- EditlineAdapter el_adapter;
- EXPECT_TRUE (el_adapter.IsValid ());
- if (!el_adapter.IsValid ())
- return;
+public:
+ void SetUp()
+ {
+ // We need a TERM set properly for editline to work as expected.
+ setenv("TERM", "vt100", 1);
+
+ // Validate the editline adapter.
+ EXPECT_TRUE(_el_adapter.IsValid());
+ if (!_el_adapter.IsValid())
+ return;
+
+ // Dump output.
+ _sp_output_thread.reset(new std::thread([&] { _el_adapter.ConsumeAllOutput(); }));
+ }
+
+ void TearDown()
+ {
+ _el_adapter.CloseInput();
+ if (_sp_output_thread)
+ _sp_output_thread->join();
+ }
- // Dump output.
- std::thread el_output_thread( [&] { el_adapter.ConsumeAllOutput (); });
+ EditlineAdapter &GetEditlineAdapter() { return _el_adapter; }
+};
+TEST_F(EditlineTestFixture, EditlineReceivesSingleLineText)
+{
// Send it some text via our virtual keyboard.
const std::string input_text ("Hello, world");
- EXPECT_TRUE (el_adapter.SendLine (input_text));
+ EXPECT_TRUE(GetEditlineAdapter().SendLine(input_text));
// Verify editline sees what we put in.
std::string el_reported_line;
bool input_interrupted = false;
- const bool received_line = el_adapter.GetLine (el_reported_line, input_interrupted, TIMEOUT_MILLIS);
+ const bool received_line = GetEditlineAdapter().GetLine(el_reported_line, input_interrupted, TIMEOUT_MILLIS);
EXPECT_TRUE (received_line);
EXPECT_FALSE (input_interrupted);
EXPECT_EQ (input_text, el_reported_line);
-
- el_adapter.CloseInput();
- el_output_thread.join();
}
-TEST (EditlineTest, EditlineReceivesMultiLineText)
+TEST_F(EditlineTestFixture, EditlineReceivesMultiLineText)
{
- setenv ("TERM", "vt100", 1);
-
- // Create an editline.
- EditlineAdapter el_adapter;
- EXPECT_TRUE (el_adapter.IsValid ());
- if (!el_adapter.IsValid ())
- return;
-
- // Stick editline output/error dumpers on separate threads.
- std::thread el_output_thread( [&] { el_adapter.ConsumeAllOutput (); });
-
// Send it some text via our virtual keyboard.
std::vector<std::string> input_lines;
input_lines.push_back ("int foo()");
@@ -344,25 +351,22 @@ TEST (EditlineTest, EditlineReceivesMultiLineText)
input_lines.push_back ("}");
input_lines.push_back ("");
- EXPECT_TRUE (el_adapter.SendLines (input_lines));
+ EXPECT_TRUE(GetEditlineAdapter().SendLines(input_lines));
// Verify editline sees what we put in.
lldb_private::StringList el_reported_lines;
bool input_interrupted = false;
- EXPECT_TRUE (el_adapter.GetLines (el_reported_lines, input_interrupted, TIMEOUT_MILLIS));
+ EXPECT_TRUE(GetEditlineAdapter().GetLines(el_reported_lines, input_interrupted, TIMEOUT_MILLIS));
EXPECT_FALSE (input_interrupted);
// Without any auto indentation support, our output should directly match our input.
EXPECT_EQ (input_lines.size (), el_reported_lines.GetSize ());
if (input_lines.size () == el_reported_lines.GetSize ())
{
- for (auto i = 0; i < input_lines.size(); ++i)
+ for (size_t i = 0; i < input_lines.size(); ++i)
EXPECT_EQ (input_lines[i], el_reported_lines[i]);
}
-
- el_adapter.CloseInput();
- el_output_thread.join();
}
#endif
diff --git a/unittests/Host/CMakeLists.txt b/unittests/Host/CMakeLists.txt
index b4739e113f48..be0450874203 100644
--- a/unittests/Host/CMakeLists.txt
+++ b/unittests/Host/CMakeLists.txt
@@ -1,4 +1,5 @@
add_lldb_unittest(HostTests
+ FileSpecTest.cpp
SocketAddressTest.cpp
SocketTest.cpp
SymbolsTest.cpp
diff --git a/unittests/Host/FileSpecTest.cpp b/unittests/Host/FileSpecTest.cpp
new file mode 100644
index 000000000000..4e619529773f
--- /dev/null
+++ b/unittests/Host/FileSpecTest.cpp
@@ -0,0 +1,111 @@
+//===-- FileSpecTest.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "lldb/Host/FileSpec.h"
+
+using namespace lldb_private;
+
+TEST(FileSpecTest, FileAndDirectoryComponents)
+{
+ FileSpec fs_posix("/foo/bar", false, FileSpec::ePathSyntaxPosix);
+ EXPECT_STREQ("/foo/bar", fs_posix.GetCString());
+ EXPECT_STREQ("/foo", fs_posix.GetDirectory().GetCString());
+ EXPECT_STREQ("bar", fs_posix.GetFilename().GetCString());
+
+ FileSpec fs_windows("F:\\bar", false, FileSpec::ePathSyntaxWindows);
+ EXPECT_STREQ("F:\\bar", fs_windows.GetCString());
+ // EXPECT_STREQ("F:\\", fs_windows.GetDirectory().GetCString()); // It returns "F:/"
+ EXPECT_STREQ("bar", fs_windows.GetFilename().GetCString());
+
+ FileSpec fs_posix_root("/", false, FileSpec::ePathSyntaxPosix);
+ EXPECT_STREQ("/", fs_posix_root.GetCString());
+ EXPECT_EQ(nullptr, fs_posix_root.GetDirectory().GetCString());
+ EXPECT_STREQ("/", fs_posix_root.GetFilename().GetCString());
+
+ FileSpec fs_windows_drive("F:", false, FileSpec::ePathSyntaxWindows);
+ EXPECT_STREQ("F:", fs_windows_drive.GetCString());
+ EXPECT_EQ(nullptr, fs_windows_drive.GetDirectory().GetCString());
+ EXPECT_STREQ("F:", fs_windows_drive.GetFilename().GetCString());
+
+ FileSpec fs_windows_root("F:\\", false, FileSpec::ePathSyntaxWindows);
+ EXPECT_STREQ("F:\\", fs_windows_root.GetCString());
+ EXPECT_STREQ("F:", fs_windows_root.GetDirectory().GetCString());
+ // EXPECT_STREQ("\\", fs_windows_root.GetFilename().GetCString()); // It returns "/"
+
+ FileSpec fs_posix_long("/foo/bar/baz", false, FileSpec::ePathSyntaxPosix);
+ EXPECT_STREQ("/foo/bar/baz", fs_posix_long.GetCString());
+ EXPECT_STREQ("/foo/bar", fs_posix_long.GetDirectory().GetCString());
+ EXPECT_STREQ("baz", fs_posix_long.GetFilename().GetCString());
+
+ FileSpec fs_windows_long("F:\\bar\\baz", false, FileSpec::ePathSyntaxWindows);
+ EXPECT_STREQ("F:\\bar\\baz", fs_windows_long.GetCString());
+ // EXPECT_STREQ("F:\\bar", fs_windows_long.GetDirectory().GetCString()); // It returns "F:/bar"
+ EXPECT_STREQ("baz", fs_windows_long.GetFilename().GetCString());
+
+ FileSpec fs_posix_trailing_slash("/foo/bar/", false, FileSpec::ePathSyntaxPosix);
+ EXPECT_STREQ("/foo/bar/.", fs_posix_trailing_slash.GetCString());
+ EXPECT_STREQ("/foo/bar", fs_posix_trailing_slash.GetDirectory().GetCString());
+ EXPECT_STREQ(".", fs_posix_trailing_slash.GetFilename().GetCString());
+
+ FileSpec fs_windows_trailing_slash("F:\\bar\\", false, FileSpec::ePathSyntaxWindows);
+ EXPECT_STREQ("F:\\bar\\.", fs_windows_trailing_slash.GetCString());
+ // EXPECT_STREQ("F:\\bar", fs_windows_trailing_slash.GetDirectory().GetCString()); // It returns "F:/bar"
+ EXPECT_STREQ(".", fs_windows_trailing_slash.GetFilename().GetCString());
+}
+
+TEST(FileSpecTest, AppendPathComponent)
+{
+ FileSpec fs_posix("/foo", false, FileSpec::ePathSyntaxPosix);
+ fs_posix.AppendPathComponent("bar");
+ EXPECT_STREQ("/foo/bar", fs_posix.GetCString());
+ EXPECT_STREQ("/foo", fs_posix.GetDirectory().GetCString());
+ EXPECT_STREQ("bar", fs_posix.GetFilename().GetCString());
+
+ FileSpec fs_windows("F:\\bar", false, FileSpec::ePathSyntaxWindows);
+ fs_windows.AppendPathComponent("baz");
+ EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetCString());
+ // EXPECT_STREQ("F:\\bar", fs_windows.GetDirectory().GetCString()); // It returns "F:/bar"
+ EXPECT_STREQ("baz", fs_windows.GetFilename().GetCString());
+
+ FileSpec fs_posix_root("/", false, FileSpec::ePathSyntaxPosix);
+ fs_posix_root.AppendPathComponent("bar");
+ EXPECT_STREQ("/bar", fs_posix_root.GetCString());
+ EXPECT_STREQ("/", fs_posix_root.GetDirectory().GetCString());
+ EXPECT_STREQ("bar", fs_posix_root.GetFilename().GetCString());
+
+ FileSpec fs_windows_root("F:\\", false, FileSpec::ePathSyntaxWindows);
+ fs_windows_root.AppendPathComponent("bar");
+ EXPECT_STREQ("F:\\bar", fs_windows_root.GetCString());
+ // EXPECT_STREQ("F:\\", fs_windows_root.GetDirectory().GetCString()); // It returns "F:/"
+ EXPECT_STREQ("bar", fs_windows_root.GetFilename().GetCString());
+}
+
+TEST(FileSpecTest, CopyByAppendingPathComponent)
+{
+ FileSpec fs = FileSpec("/foo", false, FileSpec::ePathSyntaxPosix).CopyByAppendingPathComponent("bar");
+ EXPECT_STREQ("/foo/bar", fs.GetCString());
+ EXPECT_STREQ("/foo", fs.GetDirectory().GetCString());
+ EXPECT_STREQ("bar", fs.GetFilename().GetCString());
+}
+
+TEST(FileSpecTest, Equal)
+{
+ FileSpec backward("C:\\foo\\bar", false, FileSpec::ePathSyntaxWindows);
+ FileSpec forward("C:/foo/bar", false, FileSpec::ePathSyntaxWindows);
+ EXPECT_EQ(forward, backward);
+
+ const bool full_match = true;
+ const bool remove_backup_dots = true;
+ EXPECT_TRUE(FileSpec::Equal(forward, backward, full_match, remove_backup_dots));
+ EXPECT_TRUE(FileSpec::Equal(forward, backward, full_match, !remove_backup_dots));
+ EXPECT_TRUE(FileSpec::Equal(forward, backward, !full_match, remove_backup_dots));
+ EXPECT_TRUE(FileSpec::Equal(forward, backward, !full_match, !remove_backup_dots));
+}
diff --git a/unittests/Host/SocketAddressTest.cpp b/unittests/Host/SocketAddressTest.cpp
index bd6bda13f449..6b27e04ce702 100644
--- a/unittests/Host/SocketAddressTest.cpp
+++ b/unittests/Host/SocketAddressTest.cpp
@@ -33,11 +33,8 @@ TEST_F (SocketAddressTest, Set)
ASSERT_EQ (0, sa.GetPort ());
ASSERT_TRUE (sa.SetToLocalhost (AF_INET6, 1139));
-#ifdef _WIN32
- ASSERT_STREQ ("0:0:0:0:0:0:0:1", sa.GetIPAddress ().c_str ());
-#else
- ASSERT_STREQ ("::1", sa.GetIPAddress ().c_str ());
-#endif
+ ASSERT_TRUE(sa.GetIPAddress() == "::1" || sa.GetIPAddress() == "0:0:0:0:0:0:0:1") << "Address was: "
+ << sa.GetIPAddress();
ASSERT_EQ (1139, sa.GetPort ());
}
diff --git a/unittests/Host/SocketTest.cpp b/unittests/Host/SocketTest.cpp
index ebb2f319a9c5..e3e522744760 100644
--- a/unittests/Host/SocketTest.cpp
+++ b/unittests/Host/SocketTest.cpp
@@ -116,7 +116,11 @@ TEST_F (SocketTest, DecodeHostAndPort)
EXPECT_FALSE (Socket::DecodeHostAndPort ("google.com:-1138", host_str, port_str, port, &error));
EXPECT_TRUE (error.Fail ());
EXPECT_STREQ ("invalid host:port specification: 'google.com:-1138'", error.AsCString ());
-
+
+ EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, port, &error));
+ EXPECT_TRUE(error.Fail());
+ EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", error.AsCString());
+
EXPECT_TRUE (Socket::DecodeHostAndPort ("12345", host_str, port_str, port, &error));
EXPECT_STREQ ("", host_str.c_str ());
EXPECT_STREQ ("12345", port_str.c_str ());
@@ -128,6 +132,12 @@ TEST_F (SocketTest, DecodeHostAndPort)
EXPECT_STREQ ("0", port_str.c_str ());
EXPECT_EQ (0, port);
EXPECT_TRUE (error.Success ());
+
+ EXPECT_TRUE(Socket::DecodeHostAndPort("*:65535", host_str, port_str, port, &error));
+ EXPECT_STREQ("*", host_str.c_str());
+ EXPECT_STREQ("65535", port_str.c_str());
+ EXPECT_EQ(65535, port);
+ EXPECT_TRUE(error.Success());
}
#ifndef LLDB_DISABLE_POSIX
diff --git a/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp b/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
index 605f0233e876..c239a1601b32 100644
--- a/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ b/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -209,14 +209,13 @@ TEST_F(PythonDataObjectsTest, TestPythonBytes)
PyObject *py_bytes = PyBytes_FromString(test_bytes);
EXPECT_TRUE(PythonBytes::Check(py_bytes));
PythonBytes python_bytes(PyRefType::Owned, py_bytes);
- EXPECT_EQ(PyObjectType::Bytes, python_bytes.GetObjectType());
#if PY_MAJOR_VERSION < 3
EXPECT_TRUE(PythonString::Check(py_bytes));
EXPECT_EQ(PyObjectType::String, python_bytes.GetObjectType());
#else
EXPECT_FALSE(PythonString::Check(py_bytes));
- EXPECT_NE(PyObjectType::String, python_bytes.GetObjectType());
+ EXPECT_EQ(PyObjectType::Bytes, python_bytes.GetObjectType());
#endif
llvm::ArrayRef<uint8_t> bytes = python_bytes.GetBytes();
@@ -224,13 +223,26 @@ TEST_F(PythonDataObjectsTest, TestPythonBytes)
EXPECT_EQ(0, ::memcmp(bytes.data(), test_bytes, bytes.size()));
}
+TEST_F(PythonDataObjectsTest, TestPythonByteArray)
+{
+ static const char *test_bytes = "PythonDataObjectsTest::TestPythonByteArray";
+ llvm::StringRef orig_bytes(test_bytes);
+ PyObject *py_bytes = PyByteArray_FromStringAndSize(test_bytes, orig_bytes.size());
+ EXPECT_TRUE(PythonByteArray::Check(py_bytes));
+ PythonByteArray python_bytes(PyRefType::Owned, py_bytes);
+ EXPECT_EQ(PyObjectType::ByteArray, python_bytes.GetObjectType());
+
+ llvm::ArrayRef<uint8_t> after_bytes = python_bytes.GetBytes();
+ EXPECT_EQ(after_bytes.size(), orig_bytes.size());
+ EXPECT_EQ(0, ::memcmp(orig_bytes.data(), test_bytes, orig_bytes.size()));
+}
+
TEST_F(PythonDataObjectsTest, TestPythonString)
{
// Test that strings behave correctly when wrapped by a PythonString.
static const char *test_string = "PythonDataObjectsTest::TestPythonString1";
static const char *test_string2 = "PythonDataObjectsTest::TestPythonString2";
- static const char *test_string3 = "PythonDataObjectsTest::TestPythonString3";
#if PY_MAJOR_VERSION < 3
// Verify that `PythonString` works correctly when given a PyString object.
@@ -252,8 +264,8 @@ TEST_F(PythonDataObjectsTest, TestPythonString)
// Test that creating a `PythonString` object works correctly with the
// string constructor
- PythonString constructed_string(test_string3);
- EXPECT_STREQ(test_string3, constructed_string.GetString().str().c_str());
+ PythonString constructed_string(test_string2);
+ EXPECT_STREQ(test_string2, constructed_string.GetString().str().c_str());
}
TEST_F(PythonDataObjectsTest, TestPythonStringToStr)
@@ -275,7 +287,7 @@ TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredInteger)
{
PythonInteger integer(7);
auto int_sp = integer.CreateStructuredInteger();
- EXPECT_EQ(7, int_sp->GetValue());
+ EXPECT_EQ(7U, int_sp->GetValue());
}
TEST_F(PythonDataObjectsTest, TestPythonStringToStructuredString)
@@ -290,7 +302,7 @@ TEST_F(PythonDataObjectsTest, TestPythonListValueEquality)
{
// Test that a list which is built through the native
// Python API behaves correctly when wrapped by a PythonList.
- static const int list_size = 2;
+ static const unsigned list_size = 2;
static const long long_value0 = 5;
static const char *const string_value1 = "String Index 1";
@@ -302,7 +314,7 @@ TEST_F(PythonDataObjectsTest, TestPythonListValueEquality)
list_items[0].Reset(PythonInteger(long_value0));
list_items[1].Reset(PythonString(string_value1));
- for (int i = 0; i < list_size; ++i)
+ for (unsigned i = 0; i < list_size; ++i)
list.SetItemAtIndex(i, list_items[i]);
EXPECT_EQ(list_size, list.GetSize());
@@ -335,7 +347,7 @@ TEST_F(PythonDataObjectsTest, TestPythonListManipulation)
list.AppendItem(integer);
list.AppendItem(string);
- EXPECT_EQ(2, list.GetSize());
+ EXPECT_EQ(2U, list.GetSize());
// Verify that the values match
PythonObject chk_value1 = list.GetItemAtIndex(0);
@@ -366,17 +378,17 @@ TEST_F(PythonDataObjectsTest, TestPythonListToStructuredList)
auto int_sp = array_sp->GetItemAtIndex(0)->GetAsInteger();
auto string_sp = array_sp->GetItemAtIndex(1)->GetAsString();
- EXPECT_EQ(long_value0, int_sp->GetValue());
+ EXPECT_EQ(long_value0, long(int_sp->GetValue()));
EXPECT_STREQ(string_value1, string_sp->GetValue().c_str());
}
TEST_F(PythonDataObjectsTest, TestPythonTupleSize)
{
PythonTuple tuple(PyInitialValue::Empty);
- EXPECT_EQ(0, tuple.GetSize());
+ EXPECT_EQ(0U, tuple.GetSize());
tuple = PythonTuple(3);
- EXPECT_EQ(3, tuple.GetSize());
+ EXPECT_EQ(3U, tuple.GetSize());
}
TEST_F(PythonDataObjectsTest, TestPythonTupleValues)
@@ -402,7 +414,7 @@ TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList)
PythonString string_value("Test");
PythonObject none_value(PyRefType::Borrowed, Py_None);
PythonTuple tuple{ int_value, string_value, none_value };
- EXPECT_EQ(3, tuple.GetSize());
+ EXPECT_EQ(3U, tuple.GetSize());
EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get());
EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get());
@@ -416,7 +428,7 @@ TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList2)
PythonObject none_value(PyRefType::Borrowed, Py_None);
PythonTuple tuple{ int_value.get(), string_value.get(), none_value.get() };
- EXPECT_EQ(3, tuple.GetSize());
+ EXPECT_EQ(3U, tuple.GetSize());
EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get());
EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get());
@@ -440,7 +452,7 @@ TEST_F(PythonDataObjectsTest, TestPythonDictionaryValueEquality)
{
// Test that a dictionary which is built through the native
// Python API behaves correctly when wrapped by a PythonDictionary.
- static const int dict_entries = 2;
+ static const unsigned dict_entries = 2;
const char *key_0 = "Key 0";
int key_1 = 1;
const int value_0 = 0;
@@ -458,7 +470,7 @@ TEST_F(PythonDataObjectsTest, TestPythonDictionaryValueEquality)
EXPECT_TRUE(PythonDictionary::Check(py_dict));
PythonDictionary dict(PyRefType::Owned, py_dict);
- for (int i = 0; i < dict_entries; ++i)
+ for (unsigned i = 0; i < dict_entries; ++i)
PyDict_SetItem(py_dict, py_keys[i].get(), py_values[i].get());
EXPECT_EQ(dict.GetSize(), dict_entries);
EXPECT_EQ(PyObjectType::Dictionary, dict.GetObjectType());
@@ -480,7 +492,7 @@ TEST_F(PythonDataObjectsTest, TestPythonDictionaryManipulation)
{
// Test that manipulation of a dictionary behaves correctly when wrapped
// by a PythonDictionary.
- static const int dict_entries = 2;
+ static const unsigned dict_entries = 2;
const char *const key_0 = "Key 0";
const char *const key_1 = "Key 1";
@@ -527,7 +539,7 @@ TEST_F(PythonDataObjectsTest, TestPythonDictionaryToStructuredDictionary)
dict.SetItemForKey(PythonString(string_key1), PythonInteger(int_value1));
auto dict_sp = dict.CreateStructuredDictionary();
- EXPECT_EQ(2, dict_sp->GetSize());
+ EXPECT_EQ(2U, dict_sp->GetSize());
EXPECT_TRUE(dict_sp->HasKey(string_key0));
EXPECT_TRUE(dict_sp->HasKey(string_key1));
@@ -536,7 +548,7 @@ TEST_F(PythonDataObjectsTest, TestPythonDictionaryToStructuredDictionary)
auto int_sp = dict_sp->GetValueForKey(string_key1)->GetAsInteger();
EXPECT_STREQ(string_value0, string_sp->GetValue().c_str());
- EXPECT_EQ(int_value1, int_sp->GetValue());
+ EXPECT_EQ(int_value1, long(int_sp->GetValue()));
}
TEST_F(PythonDataObjectsTest, TestPythonCallableCheck)
@@ -560,7 +572,7 @@ TEST_F(PythonDataObjectsTest, TestPythonCallableInvoke)
EXPECT_TRUE(PythonList::Check(result.get()));
auto list_result = result.AsType<PythonList>();
- EXPECT_EQ(3, list_result.GetSize());
+ EXPECT_EQ(3U, list_result.GetSize());
EXPECT_EQ(one.get(), list_result.GetItemAtIndex(0).get());
EXPECT_EQ(two.get(), list_result.GetItemAtIndex(1).get());
EXPECT_EQ(three.get(), list_result.GetItemAtIndex(2).get());
@@ -582,4 +594,4 @@ TEST_F(PythonDataObjectsTest, TestObjectAttributes)
PythonInteger numerator_attr = py_int.GetAttributeValue("numerator").AsType<PythonInteger>();
EXPECT_TRUE(numerator_attr.IsAllocated());
EXPECT_EQ(42, numerator_attr.GetInteger());
-} \ No newline at end of file
+}
diff --git a/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp b/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp
index a0a6f986cef6..ddac220c7954 100644
--- a/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp
+++ b/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp
@@ -171,4 +171,4 @@ TEST_F(PythonExceptionStateTest, TestAutoRestoreChanged)
EXPECT_TRUE(PythonExceptionState::HasErrorOccurred());
PyErr_Clear();
-} \ No newline at end of file
+}
diff --git a/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
index 3d1727dc1c25..5eb1c72598a8 100644
--- a/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ b/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -24,6 +24,7 @@ PythonTestSuite::SetUp()
// ScriptInterpreterPython::Initialize() depends on HostInfo being
// initializedso it can compute the python directory etc.
ScriptInterpreterPython::Initialize();
+ ScriptInterpreterPython::InitializePrivate();
// Although we don't care about concurrency for the purposes of running
// this test suite, Python requires the GIL to be locked even for
diff --git a/unittests/Symbol/CMakeLists.txt b/unittests/Symbol/CMakeLists.txt
new file mode 100644
index 000000000000..ef41f3fd62a8
--- /dev/null
+++ b/unittests/Symbol/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_lldb_unittest(SymbolTests
+ TestClangASTContext.cpp
+ )
diff --git a/unittests/Symbol/TestClangASTContext.cpp b/unittests/Symbol/TestClangASTContext.cpp
new file mode 100644
index 000000000000..3f166ab9cc72
--- /dev/null
+++ b/unittests/Symbol/TestClangASTContext.cpp
@@ -0,0 +1,315 @@
+//===-- TestClangASTContext.cpp ---------------------------------------*- C++ -*-===//
+
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
+#include "lldb/Symbol/Declaration.h"
+#include "lldb/Symbol/GoASTContext.h"
+
+using namespace clang;
+using namespace lldb;
+using namespace lldb_private;
+
+class TestClangASTContext : public testing::Test
+{
+public:
+ static void
+ SetUpTestCase()
+ {
+ HostInfo::Initialize();
+ }
+
+ static void
+ TearDownTestCase()
+ {
+ HostInfo::Terminate();
+ }
+
+ virtual void
+ SetUp() override
+ {
+ std::string triple = HostInfo::GetTargetTriple();
+ m_ast.reset(new ClangASTContext(triple.c_str()));
+ }
+
+ virtual void
+ TearDown() override
+ {
+ m_ast.reset();
+ }
+
+protected:
+ std::unique_ptr<ClangASTContext> m_ast;
+
+ QualType
+ GetBasicQualType(BasicType type) const
+ {
+ return ClangUtil::GetQualType(m_ast->GetBasicTypeFromAST(type));
+ }
+
+ QualType
+ GetBasicQualType(const char *name) const
+ {
+ return ClangUtil::GetQualType(m_ast->GetBuiltinTypeByName(ConstString(name)));
+ }
+};
+
+TEST_F(TestClangASTContext, TestGetBasicTypeFromEnum)
+{
+ clang::ASTContext *context = m_ast->getASTContext();
+
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeBool), context->BoolTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeChar), context->CharTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeChar16), context->Char16Ty));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeChar32), context->Char32Ty));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeDouble), context->DoubleTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeDoubleComplex), context->DoubleComplexTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeFloat), context->FloatTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeFloatComplex), context->FloatComplexTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeHalf), context->HalfTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeInt), context->IntTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeInt128), context->Int128Ty));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeLong), context->LongTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeLongDouble), context->LongDoubleTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeLongDoubleComplex), context->LongDoubleComplexTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeLongLong), context->LongLongTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeNullPtr), context->NullPtrTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeObjCClass), context->getObjCClassType()));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeObjCID), context->getObjCIdType()));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeObjCSel), context->getObjCSelType()));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeShort), context->ShortTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeSignedChar), context->SignedCharTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeUnsignedChar), context->UnsignedCharTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeUnsignedInt), context->UnsignedIntTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeUnsignedInt128), context->UnsignedInt128Ty));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeUnsignedLong), context->UnsignedLongTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeUnsignedLongLong), context->UnsignedLongLongTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeUnsignedShort), context->UnsignedShortTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeVoid), context->VoidTy));
+ EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeWChar), context->WCharTy));
+}
+
+TEST_F(TestClangASTContext, TestGetBasicTypeFromName)
+{
+ EXPECT_EQ(GetBasicQualType(eBasicTypeChar), GetBasicQualType("char"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeSignedChar), GetBasicQualType("signed char"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedChar), GetBasicQualType("unsigned char"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeWChar), GetBasicQualType("wchar_t"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeSignedWChar), GetBasicQualType("signed wchar_t"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedWChar), GetBasicQualType("unsigned wchar_t"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short int"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort), GetBasicQualType("unsigned short"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort), GetBasicQualType("unsigned short int"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("int"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("signed int"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt), GetBasicQualType("unsigned int"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt), GetBasicQualType("unsigned"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long int"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong), GetBasicQualType("unsigned long"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong), GetBasicQualType("unsigned long int"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong), GetBasicQualType("long long"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong), GetBasicQualType("long long int"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong), GetBasicQualType("unsigned long long"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong), GetBasicQualType("unsigned long long int"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeInt128), GetBasicQualType("__int128_t"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt128), GetBasicQualType("__uint128_t"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeVoid), GetBasicQualType("void"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeBool), GetBasicQualType("bool"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeFloat), GetBasicQualType("float"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeDouble), GetBasicQualType("double"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeLongDouble), GetBasicQualType("long double"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeObjCID), GetBasicQualType("id"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeObjCSel), GetBasicQualType("SEL"));
+ EXPECT_EQ(GetBasicQualType(eBasicTypeNullPtr), GetBasicQualType("nullptr"));
+}
+
+void
+VerifyEncodingAndBitSize(clang::ASTContext *context, lldb::Encoding encoding, int bit_size)
+{
+ CompilerType type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(context, encoding, bit_size);
+ EXPECT_TRUE(type.IsValid());
+
+ QualType qtype = ClangUtil::GetQualType(type);
+ EXPECT_FALSE(qtype.isNull());
+ if (qtype.isNull())
+ return;
+
+ uint64_t actual_size = context->getTypeSize(qtype);
+ EXPECT_EQ(bit_size, actual_size);
+
+ const clang::Type *type_ptr = qtype.getTypePtr();
+ EXPECT_NE(nullptr, type_ptr);
+ if (!type_ptr)
+ return;
+
+ EXPECT_TRUE(type_ptr->isBuiltinType());
+ if (encoding == eEncodingSint)
+ EXPECT_TRUE(type_ptr->isSignedIntegerType());
+ else if (encoding == eEncodingUint)
+ EXPECT_TRUE(type_ptr->isUnsignedIntegerType());
+ else if (encoding == eEncodingIEEE754)
+ EXPECT_TRUE(type_ptr->isFloatingType());
+}
+
+TEST_F(TestClangASTContext, TestBuiltinTypeForEncodingAndBitSize)
+{
+ clang::ASTContext *context = m_ast->getASTContext();
+
+ // Make sure we can get types of every possible size in every possible encoding.
+ // We can't make any guarantee about which specific type we get, because the standard
+ // isn't that specific. We only need to make sure the compiler hands us some type that
+ // is both a builtin type and matches the requested bit size.
+ VerifyEncodingAndBitSize(context, eEncodingSint, 8);
+ VerifyEncodingAndBitSize(context, eEncodingSint, 16);
+ VerifyEncodingAndBitSize(context, eEncodingSint, 32);
+ VerifyEncodingAndBitSize(context, eEncodingSint, 64);
+ VerifyEncodingAndBitSize(context, eEncodingSint, 128);
+
+ VerifyEncodingAndBitSize(context, eEncodingUint, 8);
+ VerifyEncodingAndBitSize(context, eEncodingUint, 16);
+ VerifyEncodingAndBitSize(context, eEncodingUint, 32);
+ VerifyEncodingAndBitSize(context, eEncodingUint, 64);
+ VerifyEncodingAndBitSize(context, eEncodingUint, 128);
+
+ VerifyEncodingAndBitSize(context, eEncodingIEEE754, 32);
+ VerifyEncodingAndBitSize(context, eEncodingIEEE754, 64);
+}
+
+TEST_F(TestClangASTContext, TestIsClangType)
+{
+ clang::ASTContext *context = m_ast->getASTContext();
+ lldb::opaque_compiler_type_t bool_ctype = ClangASTContext::GetOpaqueCompilerType(context, lldb::eBasicTypeBool);
+ CompilerType bool_type(m_ast.get(), bool_ctype);
+ CompilerType record_type = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
+ lldb::eLanguageTypeC_plus_plus, nullptr);
+ // Clang builtin type and record type should pass
+ EXPECT_TRUE(ClangUtil::IsClangType(bool_type));
+ EXPECT_TRUE(ClangUtil::IsClangType(record_type));
+
+ // Default constructed type should fail
+ EXPECT_FALSE(ClangUtil::IsClangType(CompilerType()));
+
+ // Go type should fail
+ GoASTContext go_ast;
+ CompilerType go_type(&go_ast, bool_ctype);
+ EXPECT_FALSE(ClangUtil::IsClangType(go_type));
+}
+
+TEST_F(TestClangASTContext, TestRemoveFastQualifiers)
+{
+ CompilerType record_type = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
+ lldb::eLanguageTypeC_plus_plus, nullptr);
+ QualType qt;
+
+ qt = ClangUtil::GetQualType(record_type);
+ EXPECT_EQ(0, qt.getLocalFastQualifiers());
+ record_type = record_type.AddConstModifier();
+ record_type = record_type.AddVolatileModifier();
+ record_type = record_type.AddRestrictModifier();
+ qt = ClangUtil::GetQualType(record_type);
+ EXPECT_NE(0, qt.getLocalFastQualifiers());
+ record_type = ClangUtil::RemoveFastQualifiers(record_type);
+ qt = ClangUtil::GetQualType(record_type);
+ EXPECT_EQ(0, qt.getLocalFastQualifiers());
+}
+
+TEST_F(TestClangASTContext, TestConvertAccessTypeToAccessSpecifier)
+{
+ EXPECT_EQ(AS_none, ClangASTContext::ConvertAccessTypeToAccessSpecifier(eAccessNone));
+ EXPECT_EQ(AS_none, ClangASTContext::ConvertAccessTypeToAccessSpecifier(eAccessPackage));
+ EXPECT_EQ(AS_public, ClangASTContext::ConvertAccessTypeToAccessSpecifier(eAccessPublic));
+ EXPECT_EQ(AS_private, ClangASTContext::ConvertAccessTypeToAccessSpecifier(eAccessPrivate));
+ EXPECT_EQ(AS_protected, ClangASTContext::ConvertAccessTypeToAccessSpecifier(eAccessProtected));
+}
+
+TEST_F(TestClangASTContext, TestUnifyAccessSpecifiers)
+{
+ // Unifying two of the same type should return the same type
+ EXPECT_EQ(AS_public, ClangASTContext::UnifyAccessSpecifiers(AS_public, AS_public));
+ EXPECT_EQ(AS_private, ClangASTContext::UnifyAccessSpecifiers(AS_private, AS_private));
+ EXPECT_EQ(AS_protected, ClangASTContext::UnifyAccessSpecifiers(AS_protected, AS_protected));
+
+ // Otherwise the result should be the strictest of the two.
+ EXPECT_EQ(AS_private, ClangASTContext::UnifyAccessSpecifiers(AS_private, AS_public));
+ EXPECT_EQ(AS_private, ClangASTContext::UnifyAccessSpecifiers(AS_private, AS_protected));
+ EXPECT_EQ(AS_private, ClangASTContext::UnifyAccessSpecifiers(AS_public, AS_private));
+ EXPECT_EQ(AS_private, ClangASTContext::UnifyAccessSpecifiers(AS_protected, AS_private));
+ EXPECT_EQ(AS_protected, ClangASTContext::UnifyAccessSpecifiers(AS_protected, AS_public));
+ EXPECT_EQ(AS_protected, ClangASTContext::UnifyAccessSpecifiers(AS_public, AS_protected));
+
+ // None is stricter than everything (by convention)
+ EXPECT_EQ(AS_none, ClangASTContext::UnifyAccessSpecifiers(AS_none, AS_public));
+ EXPECT_EQ(AS_none, ClangASTContext::UnifyAccessSpecifiers(AS_none, AS_protected));
+ EXPECT_EQ(AS_none, ClangASTContext::UnifyAccessSpecifiers(AS_none, AS_private));
+ EXPECT_EQ(AS_none, ClangASTContext::UnifyAccessSpecifiers(AS_public, AS_none));
+ EXPECT_EQ(AS_none, ClangASTContext::UnifyAccessSpecifiers(AS_protected, AS_none));
+ EXPECT_EQ(AS_none, ClangASTContext::UnifyAccessSpecifiers(AS_private, AS_none));
+}
+
+TEST_F(TestClangASTContext, TestRecordHasFields)
+{
+ CompilerType int_type = ClangASTContext::GetBasicType(m_ast->getASTContext(), eBasicTypeInt);
+
+ // Test that a record with no fields returns false
+ CompilerType empty_base = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct,
+ lldb::eLanguageTypeC_plus_plus, nullptr);
+ ClangASTContext::StartTagDeclarationDefinition(empty_base);
+ ClangASTContext::CompleteTagDeclarationDefinition(empty_base);
+
+ RecordDecl *empty_base_decl = ClangASTContext::GetAsRecordDecl(empty_base);
+ EXPECT_NE(nullptr, empty_base_decl);
+ EXPECT_FALSE(ClangASTContext::RecordHasFields(empty_base_decl));
+
+ // Test that a record with direct fields returns true
+ CompilerType non_empty_base = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "NonEmptyBase",
+ clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
+ ClangASTContext::StartTagDeclarationDefinition(non_empty_base);
+ FieldDecl *non_empty_base_field_decl =
+ m_ast->AddFieldToRecordType(non_empty_base, "MyField", int_type, eAccessPublic, 0);
+ ClangASTContext::CompleteTagDeclarationDefinition(non_empty_base);
+ RecordDecl *non_empty_base_decl = ClangASTContext::GetAsRecordDecl(non_empty_base);
+ EXPECT_NE(nullptr, non_empty_base_decl);
+ EXPECT_NE(nullptr, non_empty_base_field_decl);
+ EXPECT_TRUE(ClangASTContext::RecordHasFields(non_empty_base_decl));
+
+ // Test that a record with no direct fields, but fields in a base returns true
+ CompilerType empty_derived = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "EmptyDerived",
+ clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
+ ClangASTContext::StartTagDeclarationDefinition(empty_derived);
+ CXXBaseSpecifier *non_empty_base_spec =
+ m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(), lldb::eAccessPublic, false, false);
+ bool result = m_ast->SetBaseClassesForClassType(empty_derived.GetOpaqueQualType(), &non_empty_base_spec, 1);
+ ClangASTContext::CompleteTagDeclarationDefinition(empty_derived);
+ EXPECT_TRUE(result);
+ CXXRecordDecl *empty_derived_non_empty_base_cxx_decl = m_ast->GetAsCXXRecordDecl(empty_derived.GetOpaqueQualType());
+ RecordDecl *empty_derived_non_empty_base_decl = ClangASTContext::GetAsRecordDecl(empty_derived);
+ EXPECT_EQ(1, ClangASTContext::GetNumBaseClasses(empty_derived_non_empty_base_cxx_decl, false));
+ EXPECT_TRUE(ClangASTContext::RecordHasFields(empty_derived_non_empty_base_decl));
+
+ // Test that a record with no direct fields, but fields in a virtual base returns true
+ CompilerType empty_derived2 = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "EmptyDerived2",
+ clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
+ ClangASTContext::StartTagDeclarationDefinition(empty_derived2);
+ CXXBaseSpecifier *non_empty_vbase_spec =
+ m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(), lldb::eAccessPublic, true, false);
+ result = m_ast->SetBaseClassesForClassType(empty_derived2.GetOpaqueQualType(), &non_empty_vbase_spec, 1);
+ ClangASTContext::CompleteTagDeclarationDefinition(empty_derived2);
+ EXPECT_TRUE(result);
+ CXXRecordDecl *empty_derived_non_empty_vbase_cxx_decl =
+ m_ast->GetAsCXXRecordDecl(empty_derived2.GetOpaqueQualType());
+ RecordDecl *empty_derived_non_empty_vbase_decl = ClangASTContext::GetAsRecordDecl(empty_derived2);
+ EXPECT_EQ(1, ClangASTContext::GetNumBaseClasses(empty_derived_non_empty_vbase_cxx_decl, false));
+ EXPECT_TRUE(ClangASTContext::RecordHasFields(empty_derived_non_empty_vbase_decl));
+}
diff --git a/unittests/SymbolFile/CMakeLists.txt b/unittests/SymbolFile/CMakeLists.txt
new file mode 100644
index 000000000000..dcf9ebdb1161
--- /dev/null
+++ b/unittests/SymbolFile/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(PDB)
diff --git a/unittests/SymbolFile/PDB/CMakeLists.txt b/unittests/SymbolFile/PDB/CMakeLists.txt
new file mode 100644
index 000000000000..fcfb5e3062c9
--- /dev/null
+++ b/unittests/SymbolFile/PDB/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_lldb_unittest(SymbolFilePDBTests
+ SymbolFilePDBTests.cpp
+ )
+
+set(test_inputs
+ test-pdb.exe
+ test-pdb.pdb
+ test-dwarf.exe
+ test-pdb-types.exe
+ test-pdb-types.pdb)
+
+add_unittest_inputs(SymbolFilePDBTests "${test_inputs}")
diff --git a/unittests/SymbolFile/PDB/Inputs/test-dwarf.cpp b/unittests/SymbolFile/PDB/Inputs/test-dwarf.cpp
new file mode 100644
index 000000000000..f86ff3d875b4
--- /dev/null
+++ b/unittests/SymbolFile/PDB/Inputs/test-dwarf.cpp
@@ -0,0 +1,14 @@
+// Compile with "cl /c /Zi /GR- test.cpp"
+// Link with "link test.obj /debug /nodefaultlib /entry:main /out:test.exe"
+
+int __cdecl _purecall(void)
+{
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+
+ return 0;
+}
diff --git a/unittests/SymbolFile/PDB/Inputs/test-dwarf.exe b/unittests/SymbolFile/PDB/Inputs/test-dwarf.exe
new file mode 100644
index 000000000000..15e1910b4b8b
--- /dev/null
+++ b/unittests/SymbolFile/PDB/Inputs/test-dwarf.exe
Binary files differ
diff --git a/unittests/SymbolFile/PDB/Inputs/test-pdb-alt.cpp b/unittests/SymbolFile/PDB/Inputs/test-pdb-alt.cpp
new file mode 100644
index 000000000000..d36f15e53fb7
--- /dev/null
+++ b/unittests/SymbolFile/PDB/Inputs/test-pdb-alt.cpp
@@ -0,0 +1,9 @@
+// Compile with "cl /c /Zi /GR- test-pdb-alt.cpp"
+// Link with "link test-pdb.obj test-pdb-alt.obj /debug /nodefaultlib /entry:main /out:test-pdb.exe"
+
+#include "test-pdb.h"
+
+int bar(int n)
+{
+ return n-1;
+}
diff --git a/unittests/SymbolFile/PDB/Inputs/test-pdb-nested.h b/unittests/SymbolFile/PDB/Inputs/test-pdb-nested.h
new file mode 100644
index 000000000000..fc63b50d13c9
--- /dev/null
+++ b/unittests/SymbolFile/PDB/Inputs/test-pdb-nested.h
@@ -0,0 +1,9 @@
+#ifndef TEST_PDB_NESTED_H
+#define TEST_PDB_NESTED_H
+
+inline int baz(int n)
+{
+ return n+1;
+}
+
+#endif \ No newline at end of file
diff --git a/unittests/SymbolFile/PDB/Inputs/test-pdb-types.cpp b/unittests/SymbolFile/PDB/Inputs/test-pdb-types.cpp
new file mode 100644
index 000000000000..5e2fb77bc202
--- /dev/null
+++ b/unittests/SymbolFile/PDB/Inputs/test-pdb-types.cpp
@@ -0,0 +1,86 @@
+// Compile with "cl /c /Zi /GR- /EHsc test-pdb-types.cpp"
+// Link with "link test-pdb-types.obj /debug /nodefaultlib /entry:main /out:test-pdb-types.exe"
+
+using namespace std;
+
+// Sizes of builtin types
+static const int sizeof_char = sizeof(char);
+static const int sizeof_uchar = sizeof(unsigned char);
+static const int sizeof_short = sizeof(short);
+static const int sizeof_ushort = sizeof(unsigned short);
+static const int sizeof_int = sizeof(int);
+static const int sizeof_uint = sizeof(unsigned int);
+static const int sizeof_long = sizeof(long);
+static const int sizeof_ulong = sizeof(unsigned long);
+static const int sizeof_longlong = sizeof(long long);
+static const int sizeof_ulonglong = sizeof(unsigned long long);
+static const int sizeof_int64 = sizeof(__int64);
+static const int sizeof_uint64 = sizeof(unsigned __int64);
+static const int sizeof_float = sizeof(float);
+static const int sizeof_double = sizeof(double);
+static const int sizeof_bool = sizeof(bool);
+static const int sizeof_wchar = sizeof(wchar_t);
+
+enum Enum
+{
+ EValue1 = 1,
+ EValue2 = 2,
+};
+
+enum ShortEnum : short
+{
+ ESValue1 = 1,
+ ESValue2 = 2
+};
+
+namespace NS
+{
+class NSClass
+{
+ float f;
+ double d;
+};
+}
+
+class Class
+{
+public:
+ class NestedClass
+ {
+ Enum e;
+ };
+ ShortEnum se;
+};
+
+int
+test_func(int a, int b)
+{
+ return a + b;
+}
+
+typedef Class ClassTypedef;
+typedef NS::NSClass NSClassTypedef;
+int GlobalArray[10];
+
+static const int sizeof_NSClass = sizeof(NS::NSClass);
+static const int sizeof_Class = sizeof(Class);
+static const int sizeof_NestedClass = sizeof(Class::NestedClass);
+static const int sizeof_Enum = sizeof(Enum);
+static const int sizeof_ShortEnum = sizeof(ShortEnum);
+static const int sizeof_ClassTypedef = sizeof(ClassTypedef);
+static const int sizeof_NSClassTypedef = sizeof(NSClassTypedef);
+static const int sizeof_GlobalArray = sizeof(GlobalArray);
+
+int
+main(int argc, char **argv)
+{
+ ShortEnum e1;
+ Enum e2;
+ Class c1;
+ Class::NestedClass c2;
+ NS::NSClass c3;
+
+ ClassTypedef t1;
+ NSClassTypedef t2;
+ return test_func(1, 2);
+}
diff --git a/unittests/SymbolFile/PDB/Inputs/test-pdb-types.exe b/unittests/SymbolFile/PDB/Inputs/test-pdb-types.exe
new file mode 100644
index 000000000000..21a4bd2b4ef5
--- /dev/null
+++ b/unittests/SymbolFile/PDB/Inputs/test-pdb-types.exe
Binary files differ
diff --git a/unittests/SymbolFile/PDB/Inputs/test-pdb-types.pdb b/unittests/SymbolFile/PDB/Inputs/test-pdb-types.pdb
new file mode 100644
index 000000000000..acf241bcb5d6
--- /dev/null
+++ b/unittests/SymbolFile/PDB/Inputs/test-pdb-types.pdb
Binary files differ
diff --git a/unittests/SymbolFile/PDB/Inputs/test-pdb.cpp b/unittests/SymbolFile/PDB/Inputs/test-pdb.cpp
new file mode 100644
index 000000000000..c9bf057cfbfb
--- /dev/null
+++ b/unittests/SymbolFile/PDB/Inputs/test-pdb.cpp
@@ -0,0 +1,15 @@
+// Compile with "cl /c /Zi /GR- test-pdb.cpp"
+// Link with "link test-pdb.obj /debug /nodefaultlib /entry:main /out:test-pdb.exe"
+
+#include "test-pdb.h"
+
+int __cdecl _purecall(void)
+{
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ return foo(argc) + bar(argc);
+}
diff --git a/unittests/SymbolFile/PDB/Inputs/test-pdb.exe b/unittests/SymbolFile/PDB/Inputs/test-pdb.exe
new file mode 100644
index 000000000000..3a2c64504ed9
--- /dev/null
+++ b/unittests/SymbolFile/PDB/Inputs/test-pdb.exe
Binary files differ
diff --git a/unittests/SymbolFile/PDB/Inputs/test-pdb.h b/unittests/SymbolFile/PDB/Inputs/test-pdb.h
new file mode 100644
index 000000000000..273343bb03b0
--- /dev/null
+++ b/unittests/SymbolFile/PDB/Inputs/test-pdb.h
@@ -0,0 +1,13 @@
+#ifndef TEST_PDB_H
+#define TEST_PDB_H
+
+#include "test-pdb-nested.h"
+
+int bar(int n);
+
+inline int foo(int n)
+{
+ return baz(n)+1;
+}
+
+#endif \ No newline at end of file
diff --git a/unittests/SymbolFile/PDB/Inputs/test-pdb.pdb b/unittests/SymbolFile/PDB/Inputs/test-pdb.pdb
new file mode 100644
index 000000000000..f43d334d215a
--- /dev/null
+++ b/unittests/SymbolFile/PDB/Inputs/test-pdb.pdb
Binary files differ
diff --git a/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp b/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp
new file mode 100644
index 000000000000..b303ae7bac4b
--- /dev/null
+++ b/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp
@@ -0,0 +1,583 @@
+//===-- PythonDataObjectsTests.cpp ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Config/config.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/SymbolVendor.h"
+
+#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
+#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
+#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
+
+#if defined(_MSC_VER)
+#include "lldb/Host/windows/windows.h"
+#include <objbase.h>
+#endif
+
+#include <algorithm>
+
+extern const char *TestMainArgv0;
+
+using namespace lldb_private;
+
+class SymbolFilePDBTests : public testing::Test
+{
+public:
+ void
+ SetUp() override
+ {
+// Initialize and TearDown the plugin every time, so we get a brand new
+// AST every time so that modifications to the AST from each test don't
+// leak into the next test.
+#if defined(_MSC_VER)
+ ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
+#endif
+
+ HostInfo::Initialize();
+ ObjectFilePECOFF::Initialize();
+ SymbolFileDWARF::Initialize();
+ ClangASTContext::Initialize();
+ SymbolFilePDB::Initialize();
+
+ llvm::StringRef exe_folder = llvm::sys::path::parent_path(TestMainArgv0);
+ llvm::SmallString<128> inputs_folder = exe_folder;
+ llvm::sys::path::append(inputs_folder, "Inputs");
+
+ m_pdb_test_exe = inputs_folder;
+ m_dwarf_test_exe = inputs_folder;
+ m_types_test_exe = inputs_folder;
+ llvm::sys::path::append(m_pdb_test_exe, "test-pdb.exe");
+ llvm::sys::path::append(m_dwarf_test_exe, "test-dwarf.exe");
+ llvm::sys::path::append(m_types_test_exe, "test-pdb-types.exe");
+ }
+
+ void
+ TearDown() override
+ {
+ SymbolFilePDB::Terminate();
+ ClangASTContext::Initialize();
+ SymbolFileDWARF::Terminate();
+ ObjectFilePECOFF::Terminate();
+ HostInfo::Terminate();
+
+#if defined(_MSC_VER)
+ ::CoUninitialize();
+#endif
+ }
+
+protected:
+ llvm::SmallString<128> m_pdb_test_exe;
+ llvm::SmallString<128> m_dwarf_test_exe;
+ llvm::SmallString<128> m_types_test_exe;
+
+ bool
+ FileSpecMatchesAsBaseOrFull(const FileSpec &left, const FileSpec &right) const
+ {
+ // If the filenames don't match, the paths can't be equal
+ if (!left.FileEquals(right))
+ return false;
+ // If BOTH have a directory, also compare the directories.
+ if (left.GetDirectory() && right.GetDirectory())
+ return left.DirectoryEquals(right);
+
+ // If one has a directory but not the other, they match.
+ return true;
+ }
+
+ void
+ VerifyLineEntry(lldb::ModuleSP module, const SymbolContext &sc, const FileSpec &spec, LineTable &lt, uint32_t line,
+ lldb::addr_t addr)
+ {
+ LineEntry entry;
+ Address address;
+ EXPECT_TRUE(module->ResolveFileAddress(addr, address));
+
+ EXPECT_TRUE(lt.FindLineEntryByAddress(address, entry));
+ EXPECT_EQ(line, entry.line);
+ EXPECT_EQ(address, entry.range.GetBaseAddress());
+
+ EXPECT_TRUE(FileSpecMatchesAsBaseOrFull(spec, entry.file));
+ }
+
+ bool
+ ContainsCompileUnit(const SymbolContextList &sc_list, const FileSpec &spec) const
+ {
+ for (size_t i = 0; i < sc_list.GetSize(); ++i)
+ {
+ const SymbolContext &sc = sc_list[i];
+ if (FileSpecMatchesAsBaseOrFull(*sc.comp_unit, spec))
+ return true;
+ }
+ return false;
+ }
+
+ int
+ GetGlobalConstantInteger(const llvm::pdb::IPDBSession &session, llvm::StringRef var) const
+ {
+ auto global = session.getGlobalScope();
+ auto results =
+ global->findChildren(llvm::pdb::PDB_SymType::Data, var, llvm::pdb::PDB_NameSearchFlags::NS_Default);
+ uint32_t count = results->getChildCount();
+ if (count == 0)
+ return -1;
+
+ auto item = results->getChildAtIndex(0);
+ auto symbol = llvm::dyn_cast<llvm::pdb::PDBSymbolData>(item.get());
+ if (!symbol)
+ return -1;
+ llvm::pdb::Variant value = symbol->getValue();
+ switch (value.Type)
+ {
+ case llvm::pdb::PDB_VariantType::Int16:
+ return value.Value.Int16;
+ case llvm::pdb::PDB_VariantType::Int32:
+ return value.Value.Int32;
+ case llvm::pdb::PDB_VariantType::UInt16:
+ return value.Value.UInt16;
+ case llvm::pdb::PDB_VariantType::UInt32:
+ return value.Value.UInt32;
+ default:
+ return 0;
+ }
+ }
+};
+
+#if defined(HAVE_DIA_SDK)
+#define REQUIRES_DIA_SDK(TestName) TestName
+#else
+#define REQUIRES_DIA_SDK(TestName) DISABLED_##TestName
+#endif
+
+TEST_F(SymbolFilePDBTests, TestAbilitiesForDWARF)
+{
+ // Test that when we have Dwarf debug info, SymbolFileDWARF is used.
+ FileSpec fspec(m_dwarf_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ EXPECT_NE(nullptr, plugin);
+ SymbolFile *symfile = plugin->GetSymbolFile();
+ EXPECT_NE(nullptr, symfile);
+ EXPECT_EQ(symfile->GetPluginName(), SymbolFileDWARF::GetPluginNameStatic());
+
+ uint32_t expected_abilities = SymbolFile::kAllAbilities;
+ EXPECT_EQ(expected_abilities, symfile->CalculateAbilities());
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestAbilitiesForPDB))
+{
+ // Test that when we have PDB debug info, SymbolFilePDB is used.
+ FileSpec fspec(m_pdb_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ EXPECT_NE(nullptr, plugin);
+ SymbolFile *symfile = plugin->GetSymbolFile();
+ EXPECT_NE(nullptr, symfile);
+ EXPECT_EQ(symfile->GetPluginName(), SymbolFilePDB::GetPluginNameStatic());
+
+ uint32_t expected_abilities = SymbolFile::CompileUnits | SymbolFile::LineTables;
+ EXPECT_EQ(expected_abilities, symfile->CalculateAbilities());
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestResolveSymbolContextBasename))
+{
+ // Test that attempting to call ResolveSymbolContext with only a basename finds all full paths
+ // with the same basename
+ FileSpec fspec(m_pdb_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ EXPECT_NE(nullptr, plugin);
+ SymbolFile *symfile = plugin->GetSymbolFile();
+
+ FileSpec header_spec("test-pdb.cpp", false);
+ SymbolContextList sc_list;
+ uint32_t result_count = symfile->ResolveSymbolContext(header_spec, 0, false, lldb::eSymbolContextCompUnit, sc_list);
+ EXPECT_EQ(1u, result_count);
+ EXPECT_TRUE(ContainsCompileUnit(sc_list, header_spec));
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestResolveSymbolContextFullPath))
+{
+ // Test that attempting to call ResolveSymbolContext with a full path only finds the one source
+ // file that matches the full path.
+ FileSpec fspec(m_pdb_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ EXPECT_NE(nullptr, plugin);
+ SymbolFile *symfile = plugin->GetSymbolFile();
+
+ FileSpec header_spec(R"spec(D:\src\llvm\tools\lldb\unittests\SymbolFile\PDB\Inputs\test-pdb.cpp)spec", false);
+ SymbolContextList sc_list;
+ uint32_t result_count = symfile->ResolveSymbolContext(header_spec, 0, false, lldb::eSymbolContextCompUnit, sc_list);
+ EXPECT_GE(1u, result_count);
+ EXPECT_TRUE(ContainsCompileUnit(sc_list, header_spec));
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestLookupOfHeaderFileWithInlines))
+{
+ // Test that when looking up a header file via ResolveSymbolContext (i.e. a file that was not by itself
+ // compiled, but only contributes to the combined code of other source files), a SymbolContext is returned
+ // for each compiland which has line contributions from the requested header.
+ FileSpec fspec(m_pdb_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ EXPECT_NE(nullptr, plugin);
+ SymbolFile *symfile = plugin->GetSymbolFile();
+
+ FileSpec header_specs[] = {FileSpec("test-pdb.h", false), FileSpec("test-pdb-nested.h", false)};
+ FileSpec main_cpp_spec("test-pdb.cpp", false);
+ FileSpec alt_cpp_spec("test-pdb-alt.cpp", false);
+ for (const auto &hspec : header_specs)
+ {
+ SymbolContextList sc_list;
+ uint32_t result_count = symfile->ResolveSymbolContext(hspec, 0, true, lldb::eSymbolContextCompUnit, sc_list);
+ EXPECT_EQ(2u, result_count);
+ EXPECT_TRUE(ContainsCompileUnit(sc_list, main_cpp_spec));
+ EXPECT_TRUE(ContainsCompileUnit(sc_list, alt_cpp_spec));
+ }
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestLookupOfHeaderFileWithNoInlines))
+{
+ // Test that when looking up a header file via ResolveSymbolContext (i.e. a file that was not by itself
+ // compiled, but only contributes to the combined code of other source files), that if check_inlines
+ // is false, no SymbolContexts are returned.
+ FileSpec fspec(m_pdb_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ EXPECT_NE(nullptr, plugin);
+ SymbolFile *symfile = plugin->GetSymbolFile();
+
+ FileSpec header_specs[] = {FileSpec("test-pdb.h", false), FileSpec("test-pdb-nested.h", false)};
+ for (const auto &hspec : header_specs)
+ {
+ SymbolContextList sc_list;
+ uint32_t result_count = symfile->ResolveSymbolContext(hspec, 0, false, lldb::eSymbolContextCompUnit, sc_list);
+ EXPECT_EQ(0u, result_count);
+ }
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestLineTablesMatchAll))
+{
+ // Test that when calling ResolveSymbolContext with a line number of 0, all line entries from
+ // the specified files are returned.
+ FileSpec fspec(m_pdb_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ SymbolFile *symfile = plugin->GetSymbolFile();
+
+ FileSpec source_file("test-pdb.cpp", false);
+ FileSpec header1("test-pdb.h", false);
+ FileSpec header2("test-pdb-nested.h", false);
+ uint32_t cus = symfile->GetNumCompileUnits();
+ EXPECT_EQ(2u, cus);
+
+ SymbolContextList sc_list;
+ uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry;
+
+ uint32_t count = symfile->ResolveSymbolContext(source_file, 0, true, scope, sc_list);
+ EXPECT_EQ(1u, count);
+ SymbolContext sc;
+ EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc));
+
+ LineTable *lt = sc.comp_unit->GetLineTable();
+ EXPECT_NE(nullptr, lt);
+ count = lt->GetSize();
+ // We expect one extra entry for termination (per function)
+ EXPECT_EQ(16u, count);
+
+ VerifyLineEntry(module, sc, source_file, *lt, 7, 0x401040);
+ VerifyLineEntry(module, sc, source_file, *lt, 8, 0x401043);
+ VerifyLineEntry(module, sc, source_file, *lt, 9, 0x401045);
+
+ VerifyLineEntry(module, sc, source_file, *lt, 13, 0x401050);
+ VerifyLineEntry(module, sc, source_file, *lt, 14, 0x401054);
+ VerifyLineEntry(module, sc, source_file, *lt, 15, 0x401070);
+
+ VerifyLineEntry(module, sc, header1, *lt, 9, 0x401090);
+ VerifyLineEntry(module, sc, header1, *lt, 10, 0x401093);
+ VerifyLineEntry(module, sc, header1, *lt, 11, 0x4010a2);
+
+ VerifyLineEntry(module, sc, header2, *lt, 5, 0x401080);
+ VerifyLineEntry(module, sc, header2, *lt, 6, 0x401083);
+ VerifyLineEntry(module, sc, header2, *lt, 7, 0x401089);
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestLineTablesMatchSpecific))
+{
+ // Test that when calling ResolveSymbolContext with a specific line number, only line entries
+ // which match the requested line are returned.
+ FileSpec fspec(m_pdb_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ SymbolFile *symfile = plugin->GetSymbolFile();
+
+ FileSpec source_file("test-pdb.cpp", false);
+ FileSpec header1("test-pdb.h", false);
+ FileSpec header2("test-pdb-nested.h", false);
+ uint32_t cus = symfile->GetNumCompileUnits();
+ EXPECT_EQ(2u, cus);
+
+ SymbolContextList sc_list;
+ uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry;
+
+ // First test with line 7, and verify that only line 7 entries are added.
+ uint32_t count = symfile->ResolveSymbolContext(source_file, 7, true, scope, sc_list);
+ EXPECT_EQ(1u, count);
+ SymbolContext sc;
+ EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc));
+
+ LineTable *lt = sc.comp_unit->GetLineTable();
+ EXPECT_NE(nullptr, lt);
+ count = lt->GetSize();
+ // We expect one extra entry for termination
+ EXPECT_EQ(3u, count);
+
+ VerifyLineEntry(module, sc, source_file, *lt, 7, 0x401040);
+ VerifyLineEntry(module, sc, header2, *lt, 7, 0x401089);
+
+ sc_list.Clear();
+ // Then test with line 9, and verify that only line 9 entries are added.
+ count = symfile->ResolveSymbolContext(source_file, 9, true, scope, sc_list);
+ EXPECT_EQ(1u, count);
+ EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc));
+
+ lt = sc.comp_unit->GetLineTable();
+ EXPECT_NE(nullptr, lt);
+ count = lt->GetSize();
+ // We expect one extra entry for termination
+ EXPECT_EQ(3u, count);
+
+ VerifyLineEntry(module, sc, source_file, *lt, 9, 0x401045);
+ VerifyLineEntry(module, sc, header1, *lt, 9, 0x401090);
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestSimpleClassTypes))
+{
+ FileSpec fspec(m_types_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
+ const llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
+ SymbolContext sc;
+ llvm::DenseSet<SymbolFile *> searched_files;
+ TypeMap results;
+ EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString("Class"), nullptr, false, 0, searched_files, results));
+ EXPECT_EQ(1u, results.GetSize());
+ lldb::TypeSP udt_type = results.GetTypeAtIndex(0);
+ EXPECT_EQ(ConstString("Class"), udt_type->GetName());
+ CompilerType compiler_type = udt_type->GetForwardCompilerType();
+ EXPECT_TRUE(ClangASTContext::IsClassType(compiler_type.GetOpaqueQualType()));
+ EXPECT_EQ(uint64_t(GetGlobalConstantInteger(session, "sizeof_Class")), udt_type->GetByteSize());
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestNestedClassTypes))
+{
+ FileSpec fspec(m_types_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
+ const llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
+ SymbolContext sc;
+ llvm::DenseSet<SymbolFile *> searched_files;
+ TypeMap results;
+ EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString("Class::NestedClass"), nullptr, false, 0, searched_files, results));
+ EXPECT_EQ(1u, results.GetSize());
+ lldb::TypeSP udt_type = results.GetTypeAtIndex(0);
+ EXPECT_EQ(ConstString("Class::NestedClass"), udt_type->GetName());
+ CompilerType compiler_type = udt_type->GetForwardCompilerType();
+ EXPECT_TRUE(ClangASTContext::IsClassType(compiler_type.GetOpaqueQualType()));
+ EXPECT_EQ(uint64_t(GetGlobalConstantInteger(session, "sizeof_NestedClass")), udt_type->GetByteSize());
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestClassInNamespace))
+{
+ FileSpec fspec(m_types_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
+ const llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
+ SymbolContext sc;
+ llvm::DenseSet<SymbolFile *> searched_files;
+ TypeMap results;
+ EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString("NS::NSClass"), nullptr, false, 0, searched_files, results));
+ EXPECT_EQ(1u, results.GetSize());
+ lldb::TypeSP udt_type = results.GetTypeAtIndex(0);
+ EXPECT_EQ(ConstString("NS::NSClass"), udt_type->GetName());
+ CompilerType compiler_type = udt_type->GetForwardCompilerType();
+ EXPECT_TRUE(ClangASTContext::IsClassType(compiler_type.GetOpaqueQualType()));
+ EXPECT_EQ(GetGlobalConstantInteger(session, "sizeof_NSClass"), udt_type->GetByteSize());
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestEnumTypes))
+{
+ FileSpec fspec(m_types_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
+ const llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
+ SymbolContext sc;
+ llvm::DenseSet<SymbolFile *> searched_files;
+ const char *EnumsToCheck[] = {"Enum", "ShortEnum"};
+ for (auto Enum : EnumsToCheck)
+ {
+ TypeMap results;
+ EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString(Enum), nullptr, false, 0, searched_files, results));
+ EXPECT_EQ(1u, results.GetSize());
+ lldb::TypeSP enum_type = results.GetTypeAtIndex(0);
+ EXPECT_EQ(ConstString(Enum), enum_type->GetName());
+ CompilerType compiler_type = enum_type->GetFullCompilerType();
+ EXPECT_TRUE(ClangASTContext::IsEnumType(compiler_type.GetOpaqueQualType()));
+ clang::EnumDecl *enum_decl = ClangASTContext::GetAsEnumDecl(compiler_type);
+ EXPECT_NE(nullptr, enum_decl);
+ EXPECT_EQ(2, std::distance(enum_decl->enumerator_begin(), enum_decl->enumerator_end()));
+
+ std::string sizeof_var = "sizeof_";
+ sizeof_var.append(Enum);
+ EXPECT_EQ(GetGlobalConstantInteger(session, sizeof_var.c_str()), enum_type->GetByteSize());
+ }
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestArrayTypes))
+{
+ // In order to get this test working, we need to support lookup by symbol name. Because array
+ // types themselves do not have names, only the symbols have names (i.e. the name of the array).
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestFunctionTypes))
+{
+ // In order to get this test working, we need to support lookup by symbol name. Because array
+ // types themselves do not have names, only the symbols have names (i.e. the name of the array).
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestTypedefs))
+{
+ FileSpec fspec(m_types_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
+ const llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
+ SymbolContext sc;
+ llvm::DenseSet<SymbolFile *> searched_files;
+ TypeMap results;
+
+ const char *TypedefsToCheck[] = {"ClassTypedef", "NSClassTypedef"};
+ for (auto Typedef : TypedefsToCheck)
+ {
+ TypeMap results;
+ EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString(Typedef), nullptr, false, 0, searched_files, results));
+ EXPECT_EQ(1u, results.GetSize());
+ lldb::TypeSP typedef_type = results.GetTypeAtIndex(0);
+ EXPECT_EQ(ConstString(Typedef), typedef_type->GetName());
+ CompilerType compiler_type = typedef_type->GetFullCompilerType();
+ ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem());
+ EXPECT_TRUE(clang_type_system->IsTypedefType(compiler_type.GetOpaqueQualType()));
+
+ std::string sizeof_var = "sizeof_";
+ sizeof_var.append(Typedef);
+ EXPECT_EQ(GetGlobalConstantInteger(session, sizeof_var.c_str()), typedef_type->GetByteSize());
+ }
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestRegexNameMatch))
+{
+ FileSpec fspec(m_types_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
+ SymbolContext sc;
+ llvm::DenseSet<SymbolFile *> searched_files;
+ TypeMap results;
+ uint32_t num_results = symfile->FindTypes(sc, ConstString(".*"), nullptr, false, 0, searched_files, results);
+ EXPECT_GT(num_results, 1u);
+ EXPECT_EQ(num_results, results.GetSize());
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestMaxMatches))
+{
+ FileSpec fspec(m_types_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
+ SymbolContext sc;
+ llvm::DenseSet<SymbolFile *> searched_files;
+ TypeMap results;
+ uint32_t num_results = symfile->FindTypes(sc, ConstString(".*"), nullptr, false, 0, searched_files, results);
+ // Try to limit ourselves from 1 to 10 results, otherwise we could be doing this thousands of times.
+ // The idea is just to make sure that for a variety of values, the number of limited results always
+ // comes out to the number we are expecting.
+ uint32_t iterations = std::min(num_results, 10u);
+ for (uint32_t i = 1; i <= iterations; ++i)
+ {
+ uint32_t num_limited_results = symfile->FindTypes(sc, ConstString(".*"), nullptr, false, i, searched_files, results);
+ EXPECT_EQ(i, num_limited_results);
+ EXPECT_EQ(num_limited_results, results.GetSize());
+ }
+}
+
+TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestNullName))
+{
+ FileSpec fspec(m_types_test_exe.c_str(), false);
+ ArchSpec aspec("i686-pc-windows");
+ lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+ SymbolVendor *plugin = module->GetSymbolVendor();
+ SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
+ SymbolContext sc;
+ llvm::DenseSet<SymbolFile *> searched_files;
+ TypeMap results;
+ uint32_t num_results = symfile->FindTypes(sc, ConstString(), nullptr, false, 0, searched_files, results);
+ EXPECT_EQ(0u, num_results);
+ EXPECT_EQ(0u, results.GetSize());
+}
diff --git a/unittests/Utility/CMakeLists.txt b/unittests/Utility/CMakeLists.txt
index 30936acce9dc..99677a47d7cc 100644
--- a/unittests/Utility/CMakeLists.txt
+++ b/unittests/Utility/CMakeLists.txt
@@ -1,5 +1,8 @@
add_lldb_unittest(UtilityTests
+ ModuleCacheTest.cpp
StringExtractorTest.cpp
TaskPoolTest.cpp
UriParserTest.cpp
)
+
+add_unittest_inputs(UtilityTests TestModule.so)
diff --git a/unittests/Utility/Inputs/TestModule.c b/unittests/Utility/Inputs/TestModule.c
new file mode 100644
index 000000000000..12374e1f7c65
--- /dev/null
+++ b/unittests/Utility/Inputs/TestModule.c
@@ -0,0 +1,10 @@
+// Compile with $CC -nostdlib -shared TestModule.c -o TestModule.so
+// The actual contents of the test module is not important here. I am using this because it
+// produces an extremely tiny (but still perfectly valid) module.
+
+void
+boom(void)
+{
+ char *BOOM;
+ *BOOM = 47;
+}
diff --git a/unittests/Utility/Inputs/TestModule.so b/unittests/Utility/Inputs/TestModule.so
new file mode 100644
index 000000000000..9e9bf0b6e17e
--- /dev/null
+++ b/unittests/Utility/Inputs/TestModule.so
Binary files differ
diff --git a/unittests/Utility/ModuleCacheTest.cpp b/unittests/Utility/ModuleCacheTest.cpp
new file mode 100644
index 000000000000..53bfc882f232
--- /dev/null
+++ b/unittests/Utility/ModuleCacheTest.cpp
@@ -0,0 +1,179 @@
+#include "gtest/gtest.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+#include "Utility/ModuleCache.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/SymbolContext.h"
+
+extern const char *TestMainArgv0;
+
+using namespace lldb_private;
+using namespace lldb;
+
+namespace
+{
+
+class ModuleCacheTest : public testing::Test
+{
+public:
+ static void
+ SetUpTestCase();
+
+ static void
+ TearDownTestCase();
+
+protected:
+ static FileSpec s_cache_dir;
+ static llvm::SmallString<128> s_test_executable;
+
+ void
+ TryGetAndPut(const FileSpec &cache_dir, const char *hostname, bool expect_download);
+};
+}
+
+FileSpec ModuleCacheTest::s_cache_dir;
+llvm::SmallString<128> ModuleCacheTest::s_test_executable;
+
+static const char dummy_hostname[] = "dummy_hostname";
+static const char dummy_remote_dir[] = "bin";
+static const char module_name[] = "TestModule.so";
+static const char module_uuid[] = "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476";
+static const uint32_t uuid_bytes = 20;
+static const size_t module_size = 5602;
+
+static FileSpec
+GetDummyRemotePath()
+{
+ FileSpec fs("/", false, FileSpec::ePathSyntaxPosix);
+ fs.AppendPathComponent(dummy_remote_dir);
+ fs.AppendPathComponent(module_name);
+ return fs;
+}
+
+static FileSpec
+GetUuidView(FileSpec spec)
+{
+ spec.AppendPathComponent(".cache");
+ spec.AppendPathComponent(module_uuid);
+ spec.AppendPathComponent(module_name);
+ return spec;
+}
+
+static FileSpec
+GetSysrootView(FileSpec spec, const char *hostname)
+{
+ spec.AppendPathComponent(hostname);
+ spec.AppendPathComponent(dummy_remote_dir);
+ spec.AppendPathComponent(module_name);
+ return spec;
+}
+
+void
+ModuleCacheTest::SetUpTestCase()
+{
+ HostInfo::Initialize();
+ ObjectFileELF::Initialize();
+
+ FileSpec tmpdir_spec;
+ HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, s_cache_dir);
+
+ llvm::StringRef exe_folder = llvm::sys::path::parent_path(TestMainArgv0);
+ s_test_executable = exe_folder;
+ llvm::sys::path::append(s_test_executable, "Inputs", module_name);
+}
+
+void
+ModuleCacheTest::TearDownTestCase()
+{
+ ObjectFileELF::Terminate();
+ HostInfo::Terminate();
+}
+
+static void
+VerifyDiskState(const FileSpec &cache_dir, const char *hostname)
+{
+ FileSpec uuid_view = GetUuidView(cache_dir);
+ EXPECT_TRUE(uuid_view.Exists()) << "uuid_view is: " << uuid_view.GetCString();
+ EXPECT_EQ(module_size, uuid_view.GetByteSize());
+
+ FileSpec sysroot_view = GetSysrootView(cache_dir, hostname);
+ EXPECT_TRUE(sysroot_view.Exists()) << "sysroot_view is: " << sysroot_view.GetCString();
+ EXPECT_EQ(module_size, sysroot_view.GetByteSize());
+}
+
+void
+ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir, const char *hostname, bool expect_download)
+{
+ ModuleCache mc;
+ ModuleSpec module_spec;
+ module_spec.GetFileSpec() = GetDummyRemotePath();
+ module_spec.GetUUID().SetFromCString(module_uuid, uuid_bytes);
+ module_spec.SetObjectSize(module_size);
+ ModuleSP module_sp;
+ bool did_create;
+ bool download_called = false;
+
+ Error error = mc.GetAndPut(
+ cache_dir, hostname, module_spec,
+ [this, &download_called](const ModuleSpec &module_spec, const FileSpec &tmp_download_file_spec) {
+ download_called = true;
+ EXPECT_STREQ(GetDummyRemotePath().GetCString(), module_spec.GetFileSpec().GetCString());
+ std::error_code ec = llvm::sys::fs::copy_file(s_test_executable, tmp_download_file_spec.GetCString());
+ EXPECT_FALSE(ec);
+ return Error();
+ },
+ [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) { return Error("Not supported."); },
+ module_sp, &did_create);
+ EXPECT_EQ(expect_download, download_called);
+
+ EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString();
+ EXPECT_TRUE(did_create);
+ ASSERT_TRUE(bool(module_sp));
+
+ SymbolContextList sc_list;
+ EXPECT_EQ(1u, module_sp->FindFunctionSymbols(ConstString("boom"), eFunctionNameTypeFull, sc_list));
+ EXPECT_STREQ(GetDummyRemotePath().GetCString(), module_sp->GetPlatformFileSpec().GetCString());
+ EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str());
+}
+
+TEST_F(ModuleCacheTest, GetAndPut)
+{
+ FileSpec test_cache_dir = s_cache_dir;
+ test_cache_dir.AppendPathComponent("GetAndPut");
+
+ const bool expect_download = true;
+ TryGetAndPut(test_cache_dir, dummy_hostname, expect_download);
+ VerifyDiskState(test_cache_dir, dummy_hostname);
+}
+
+TEST_F(ModuleCacheTest, GetAndPutUuidExists)
+{
+ FileSpec test_cache_dir = s_cache_dir;
+ test_cache_dir.AppendPathComponent("GetAndPutUuidExists");
+
+ FileSpec uuid_view = GetUuidView(test_cache_dir);
+ std::error_code ec = llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString());
+ ASSERT_FALSE(ec);
+ ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString());
+ ASSERT_FALSE(ec);
+
+ const bool expect_download = false;
+ TryGetAndPut(test_cache_dir, dummy_hostname, expect_download);
+ VerifyDiskState(test_cache_dir, dummy_hostname);
+}
+
+TEST_F(ModuleCacheTest, GetAndPutStrangeHostname)
+{
+ FileSpec test_cache_dir = s_cache_dir;
+ test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname");
+
+ const bool expect_download = true;
+ TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download);
+ VerifyDiskState(test_cache_dir, "tab_colon_asterisk_");
+}
diff --git a/www/build.html b/www/build.html
index 787ce6220a2c..7f8a5c9817cd 100755
--- a/www/build.html
+++ b/www/build.html
@@ -55,16 +55,22 @@
<div class="postcontent">
<h2>Required Dependencies</h2>
<ul>
- <li>Visual Studio 2012 or greater</li>
- <li>Windows SDK 8.0 or higher</li>
+ <li>Visual Studio 2015 or greater</li>
+ <li>Windows SDK 8.0 or higher. In general it is best to use the latest available version.</li>
<li>
- <a href="https://www.python.org/download/releases/2.7/">Python 2.7</a>. Note that you <b>must</b>
- compile Python from source. See <a href="#WindowsPreliminaries">Preliminaries</a> for more
- information.
+ <a href="https://www.python.org/downloads/windows/">Python 3.5 or higher</a> or higher. Earlier
+ versions of Python can be made to work by compiling your own distribution from source,
+ but this workflow is unsupported and you are own your own.
</li>
<li><a href="http://martine.github.io/ninja/">Ninja build tool</a> (strongly recommended)</li>
<li><a href="http://gnuwin32.sourceforge.net/">GnuWin32</a></li>
- <li><a href="http://www.swig.org/download.html">SWIG for Windows</a></li>
+ <li><a href="http://www.swig.org/download.html">SWIG for Windows (version 3+)</a></li>
+ </ul>
+ <h2>Optional Dependencies</h2>
+ <ul>
+ <li><a href="https://github.com/Microsoft/PTVS/releases">Python Tools for Visual Studio</a>. If you
+ plan to debug test failures or even write new tests at all, PTVS is an indispensable debugging extension
+ to VS that enables full editing and debugging support for Python (including mixed native/managed debugging)</li>
</ul>
<h2 id="WindowsPreliminaries">Preliminaries</h2>
<p>
@@ -74,45 +80,13 @@
</p>
<ol>
<li><p>Install Visual Studio and the Windows SDK.</p></li>
- <li>
- <p>
- Build Python from source using the solution file supplied with the Python 2.7 source
- distribution.
- </p>
- <p>
- Because LLDB functionality is compiled into a Python extension module,
- the extension module must be compiled with the same version of Visual Studio that
- Python itself was compiled with. The binary release of Python 2.7 is compiled with
- Visual Studio 2008, so it is incompatible with linking against LLDB.
- </p>
- <p>
- Note that if you plan to do both debug and release builds of LLDB, you will need to
- compile both debug and release builds of Python. The same applies if you plan to build
- both x86 and x64 configurations of LLDB
- </p>
- </li>
- <li>
- <p>Copy &lt;python src dir&gt;\PC\pyconfig.h to &lt;python src dir&gt;\Include.</p>
- <p>
- This is necessary because pyconfig.h is a hand-maintained file which is platform specific,
- so multiple copies of this file are included with each source distribution. It appears to
- be up to the person building Python to move the correct version of pyconfig.h to the Include
- folder.
- </p>
- </li>
- <li>
- <p>
- Run lldb/scripts/install_custom_python.py so to "install" your custom build of Python to a
- canonical directory structure.
- </p>
- </li>
- <li><p>Install GnuWin32, making sure &lt;GnuWin32 install dir&gt;\bin is added to your PATH environment variable.</p></li>
- <li><p>Install SWIG for Windows, making sure &lt;SWIG install dir&gt; is added to your PATH environment variable.</p></li>
+ <li><p>Install GnuWin32, making sure <code>&lt;GnuWin32 install dir&gt;\bin</code> is added to your <code>PATH</code> environment variable.</p></li>
+ <li><p>Install SWIG for Windows, making sure <code>&lt;SWIG install dir&gt;</code> is added to your <code>PATH</code> environment variable.</p></li>
</ol>
<h2>Building LLDB</h2>
<p>
Any command prompt from which you build LLDB should have a valid Visual Studio environment setup.
- This means you should run vcvarsall.bat or open an appropriate Visual Studio Command Prompt
+ This means you should run <code>vcvarsall.bat</code> or open an appropriate Visual Studio Command Prompt
corresponding to the version you wish to use.
</p>
<p>Finally, when you are ready to build LLDB, generate CMake with the following command line:</p>
@@ -130,9 +104,8 @@
a crash, rather than having to reproduce a failure or use a crash dump.
</li>
<li>
- <b>PYTHON_HOME</b> (Required): Path the folder you specified in the --dest argument to install_custom_python.py.
- Note that install_custom_python.py will create x86 and x64 subdirectories under this folder. PYTHON_HOME should
- refer to the correct architecture-specific folder.
+ <b>PYTHON_HOME</b> (Required): Path to the folder where the Python distribution is installed. For example,
+ C:\Python35
</li>
<li>
<b>LLDB_RELOCATABLE_PYTHON</b> (Default=0): When this is 0, LLDB will bind statically to the location specified
@@ -142,7 +115,28 @@
use its default mechanism for finding the python installation at runtime (looking for installed Pythons, or using
the PYTHONHOME environment variable if it is specified).
</li>
+ <li>
+ <b>LLDB_TEST_COMPILER</b>: The test suite needs to be able to find a copy of clang.exe that it can use to compile
+ inferior programs. Note that MSVC is not supported here, it <strong>must</strong> be a path to a clang executable.
+ Note that using a release clang.exe is strongly recommended here, as it will make the test suite run much faster.
+ This can be a path to any recent clang.exe, including one you built yourself.
+ </li>
</ul>
+ Sample command line:<br/>
+ <code>cmake -G Ninja -DLLDB_TEST_DEBUG_TEST_CRASHES=1 -DPYTHON_HOME=C:\Python35 -DLLDB_TEST_COMPILER=d:\src\llvmbuild\ninja_release\bin\clang.exe ..\..\llvm</code>
+ <h2>Working with both Ninja and MSVC</h2>
+ <p>
+ Compiling with <code>ninja</code> is both faster and simpler than compiling with MSVC, but chances are you still want
+ to debug LLDB with MSVC (at least until we can debug LLDB on Windows with LLDB!). One solution to this is to run
+ <code>cmake</code> twice and generate the output into two different folders. One for compiling (the <code>ninja</code>
+ folder), and one for editing / browsing / debugging (the MSVC folder).
+ </p>
+ <p>
+ To do this, simply run <code>`cmake -G Ninja &lt;arguments&gt;`</code> from one folder, and
+ <code>`cmake -G "Visual Studio 14 2015" &lt;arguments&gt;`</code> in another folder. Then you can open the .sln file
+ in Visual Studio, set <code>lldb</code> as the startup project, and use F5 to run it. You need only edit the project
+ settings to set the executable and the working directory to point to binaries inside of the <code>ninja</code> tree.
+ </p>
</div>
</div>
<div class="post" id="BuildingLldbOnMacOSX">
diff --git a/www/status.html b/www/status.html
index ba7747f79d65..6fc71421c7c7 100755
--- a/www/status.html
+++ b/www/status.html
@@ -12,198 +12,216 @@
</div>
<div id="container">
- <div id="content">
+ <div id="content">
<!--#include virtual="sidebar.incl"-->
- <div id="middle">
- <div class="post">
- <h1 class ="postheader">Mac OS X Status</h1>
- <div class="postcontent">
+ <div id="middle">
+ <div class="post">
+ <h1 class ="postheader">Mac OS X Status</h1>
+ <div class="postcontent">
- <p>LLDB has matured a lot in the last year and can be used for
- C, C++ and Objective C development for x86_64, i386 and ARM debugging.
- The entire public API is exposed though a framework on Mac OS X which
- is used by Xcode, the lldb command line tool, and can also be used by
- Python. The entire public API is exposed through script bridging which
- allows LLDB to use an embedded Python script interpreter, as well as
- having a Python module named "lldb" which can be used from Python
- on the command line. This allows debug sessions to be scripted. It also
- allows powerful debugging actions to be created and attached to a variety
- of debugging workflows.</p>
- </div>
- <h1 class ="postheader">Linux Status</h1>
- <div class="postcontent">
- <p> LLDB is improving on Linux. While the debugserver has not been ported
- (to enable remote debugging) Linux is nearing feature completeness with Darwin
- to debug x86_64 programs, and is partially working with i386 programs.
- ARM architectures on Linux are untested.
- For more details, see the Features by OS section below.
- </div>
- <h1 class ="postheader">FreeBSD Status</h1>
- <div class="postcontent">
- <p> LLDB on FreeBSD lags behind the Linux implementation but is improving rapidly.
- For more details, see the Features by OS section below.
- </div>
- <h1 class ="postheader">Features by OS</h1>
- <div class="postcontent">
- <p> The table below shows a summary of the features that are available
- on several platforms. In addition to Linux and Mac OS X, LLDB is also
- known to work on FreeBSD. Windows and NetBSD support is under development.
- <table border="1">
- <tr>
- <th>Feature</th>
- <th>FreeBSD<br>(x86_64)</th>
- <th>Linux<br>(x86_64)</th>
- <th>Mac OS X (i386/x86_64 and ARM/Thumb)</th>
- </tr>
- <tr>
- <td>Backtracing</td>
- <td>OK</td>
- <td>OK</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>Breakpoints
- <ul>
- <li>source-line
- <li>symbolic
- <li>C++ mangled names
- <li>module scoping
- </ul>
- </td>
- <td>OK</td>
- <td>OK</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>C++11:
- <ul>
- <li>function access
- <li>template support
- <li>dynamic types
- </ul></td>
- <td>OK</td>
- <td>OK</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>Commandline lldb tool</td>
- <td>OK</td>
- <td>OK</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>Core file debugging</td>
- <td>OK (ELF)</td>
- <td>OK (ELF)</td>
- <td>OK (MachO)</td>
- </tr>
- <tr>
- <td>Debugserver (remote debugging)</td>
- <td>Not ported</td>
- <td>Not ported</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>Disassembly</td>
- <td>OK</td>
- <td>OK</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>Expression evaluation</td>
- <td>Unknown</td>
- <td>Works with some bugs</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>JIT debugging</td>
- <td>Unknown</td>
- <td>Symbolic debugging only</td>
- <td>Untested</td>
- </tr>
- <tr>
- <td>Objective-C 2.0:
- <ul>
- <li>printing properties
- <li>synthetic properties
- <li>expressions
- <li>KVO
- <li>dynamic types
- <li>dot syntax
- <li>runtime data
- <li>stepping into/over
- <li>printing the description of an object ("po")
- </ul></td>
- <td>Unknown</td>
- <td>Not applicable</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>Process control
- <ul>
- <li>attach
- <li>continue
- <li>exec, execve...
- <li>fork
- <li>launch
- <li>status
- </ul>
- </td>
- <td>Works, with some bugs</td>
- <td>OK (except exec*)</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>Public Python API</td>
- <td>OK</td>
- <td>OK</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>Registers (x86_64 and i386)
- <ul>
- <li>general purpose
- <li>floating point
- <li>exception state
- <li>SSE
- <li>AVX
- </ul>
- </td>
- <td>GP and FP OK</td>
- <td>OK (except for exception state registers)</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>Script bridging</td>
- <td>OK</td>
- <td>OK</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>Symbol reading and object file introspection</td>
- <td>OK</td>
- <td>OK</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>Thread inspection and stepping</td>
- <td>OK</td>
- <td>OK</td>
- <td>OK</td>
- </tr>
- <tr>
- <td>Watchpoints</td>
- <td>OK</td>
- <td>OK</td>
- <td>OK</td>
- </tr>
- </table>
- </div>
- <div class="postfooter"></div>
- </div>
- </div>
- </div>
+ <p>LLDB has matured a lot in the last year and can be used for
+ C, C++ and Objective C development for x86_64, i386 and ARM debugging.
+ The entire public API is exposed though a framework on Mac OS X which
+ is used by Xcode, the lldb command line tool, and can also be used by
+ Python. The entire public API is exposed through script bridging which
+ allows LLDB to use an embedded Python script interpreter, as well as
+ having a Python module named "lldb" which can be used from Python
+ on the command line. This allows debug sessions to be scripted. It also
+ allows powerful debugging actions to be created and attached to a variety
+ of debugging workflows.</p>
+ </div>
+ <h1 class ="postheader">Linux Status</h1>
+ <div class="postcontent">
+ <p> LLDB is improving on Linux. While the debugserver has not been ported
+ (to enable remote debugging) Linux is nearing feature completeness with Darwin
+ to debug x86_64 programs, and is partially working with i386 programs.
+ ARM architectures on Linux are untested.
+ For more details, see the Features by OS section below.
+ </div>
+ <h1 class ="postheader">FreeBSD Status</h1>
+ <div class="postcontent">
+ <p> LLDB on FreeBSD lags behind the Linux implementation but is improving rapidly.
+ For more details, see the Features by OS section below.
+ </div>
+ <h1 class ="postheader">Windows Status</h1>
+ <div class="postcontent">
+ <p> LLDB on Windows is still under development, but already useful for i386
+ programs (x86_64 untested) built with DWARF debug information, including postmortem
+ analysis of minidumps.
+ For more details, see the Features by OS section below.
+ </div>
+ <h1 class ="postheader">Features by OS</h1>
+ <div class="postcontent">
+ <p> The table below shows a summary of the features that are available
+ on several platforms. In addition to Linux and Mac OS X, LLDB is also
+ known to work on FreeBSD. NetBSD support is under development.
+ <table border="1">
+ <tr>
+ <th>Feature</th>
+ <th>FreeBSD<br>(x86_64)</th>
+ <th>Linux<br>(x86_64)</th>
+ <th>Mac OS X (i386/x86_64 and ARM/Thumb)</th>
+ <th>Windows (i386)</th>
+ </tr>
+ <tr>
+ <td>Backtracing</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ </tr>
+ <tr>
+ <td>Breakpoints
+ <ul>
+ <li>source-line
+ <li>symbolic
+ <li>C++ mangled names
+ <li>module scoping
+ </ul>
+ </td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ </tr>
+ <tr>
+ <td>C++11:
+ <ul>
+ <li>function access
+ <li>template support
+ <li>dynamic types
+ </ul></td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>Unknown</td>
+ </tr>
+ <tr>
+ <td>Commandline lldb tool</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ </tr>
+ <tr>
+ <td>Core file debugging</td>
+ <td>OK (ELF)</td>
+ <td>OK (ELF)</td>
+ <td>OK (MachO)</td>
+ <td>OK (Minidump)</td>
+ </tr>
+ <tr>
+ <td>Debugserver (remote debugging)</td>
+ <td>Not ported</td>
+ <td>Not ported</td>
+ <td>OK</td>
+ <td>Not ported</td>
+ </tr>
+ <tr>
+ <td>Disassembly</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ </tr>
+ <tr>
+ <td>Expression evaluation</td>
+ <td>Unknown</td>
+ <td>Works with some bugs</td>
+ <td>OK</td>
+ <td>Works with some bugs</td>
+ </tr>
+ <tr>
+ <td>JIT debugging</td>
+ <td>Unknown</td>
+ <td>Symbolic debugging only</td>
+ <td>Untested</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>Objective-C 2.0:
+ <ul>
+ <li>printing properties
+ <li>synthetic properties
+ <li>expressions
+ <li>KVO
+ <li>dynamic types
+ <li>dot syntax
+ <li>runtime data
+ <li>stepping into/over
+ <li>printing the description of an object ("po")
+ </ul></td>
+ <td>Unknown</td>
+ <td>Not applicable</td>
+ <td>OK</td>
+ <td>Not applicable</td>
+ </tr>
+ <tr>
+ <td>Process control
+ <ul>
+ <li>attach
+ <li>continue
+ <li>exec, execve...
+ <li>fork
+ <li>launch
+ <li>status
+ </ul>
+ </td>
+ <td>Works, with some bugs</td>
+ <td>OK (except exec*)</td>
+ <td>OK</td>
+ <td>OK</td>
+ </tr>
+ <tr>
+ <td>Public Python API</td>
+ <td>OK (Python 2.7)</td>
+ <td>OK (Python 2.7)</td>
+ <td>OK (Python 2.7)</td>
+ <td>OK (Python 3.5)</td>
+ </tr>
+ <tr>
+ <td>Registers (x86_64 and i386)
+ <ul>
+ <li>general purpose
+ <li>floating point
+ <li>exception state
+ <li>SSE
+ <li>AVX
+ </ul>
+ </td>
+ <td>GP and FP OK</td>
+ <td>OK (except for exception state registers)</td>
+ <td>OK</td>
+ <td>OK (except for AVX support)</td>
+ </tr>
+ <tr>
+ <td>Symbol reading and object file introspection</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK (no PDB yet)</td>
+ </tr>
+ <tr>
+ <td>Thread inspection and stepping</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ </tr>
+ <tr>
+ <td>Watchpoints</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>OK</td>
+ <td>Not ported yet</td>
+ </tr>
+ </table>
+ </div>
+ <div class="postfooter"></div>
+ </div>
+ </div>
+ </div>
</div>
</body>
</html>
diff --git a/www/test.html b/www/test.html
index b40e0ff4ddd5..60a5df51fbb9 100644
--- a/www/test.html
+++ b/www/test.html
@@ -26,14 +26,22 @@
source file and then uses LLDB to debug the resulting executable. The tests verify
both the LLDB command line interface and the scripting API.
</p>
-
+ </div>
+ <h1 class="postheader">Running tests</h1>
+ <div class="postcontent">
+ <h2>Running the full test suite</h2>
+ <p>
+ <strong>Windows Note</strong>: In the examples that follow, any invocations of <code>python</code>
+ should be replaced with <code>python_d</code>, the debug interpreter, when running the test
+ suite against a debug version of LLDB.
+ </p>
<p>
The easiest way to run the LLDB test suite is to use the <tt>check-lldb</tt> build
target. By default, the <tt>check-lldb</tt> target builds the test programs with
the same compiler that was used to build LLDB. To build the tests with a different
- compiler, you can set the <tt>LLDB_TEST_COMPILER</tt> CMake variable. It is possible to
+ compiler, you can set the <strong>LLDB_TEST_COMPILER</strong> CMake variable. It is possible to
customize the architecture of the test binaries and compiler used by appending -A
- and -C options respectively to the CMake variable <tt>LLDB_TEST_USER_ARGS</tt>. For
+ and -C options respectively to the CMake variable <strong>LLDB_TEST_USER_ARGS</strong>. For
example, to test LLDB against 32-bit binaries
built with a custom version of clang, do:
</p>
@@ -44,28 +52,27 @@
<p>Note that multiple -A and -C flags can be specified to <tt>LLDB_TEST_USER_ARGS</tt>.</p>
<p>Note that on NetBSD you must export <tt>LD_LIBRARY_PATH=$PWD/lib</tt> in your environment. This is due to lack of
the <tt>$ORIGIN</tt> linker feature.</p>
+ <h2>Running a specific test or set of tests</h2>
<p>
In addition to running all the LLDB test suites with the "check-lldb" CMake target above, it is possible to
run individual LLDB tests. For example, to run the test cases defined in TestInferiorCrashing.py, run:
</p>
<code>
<br />&gt; cd $lldb/test
- <br />&gt; python dotest.py --executable &lt;path-to-lldb&gt; -p TestInferiorCrashing.py
+ <br />&gt; python dotest.py --executable &lt;path-to-lldb&gt; -p TestInferiorCrashing.py ../packages/Python/lldbsuite/test
</code>
<p>
- In addition to running a test by name, it is also possible to specify a directory path to <tt>dotest.py</tt>
- in order to run all the tests under that directory. For example, to run all the tests under the
- 'functionalities/data-formatter' directory, run:
+ If the test is not specified by name (e.g. if you leave the <code>-p</code> argument off), LLDB will run all tests in
+ that directory:
</p>
<code>
<br />&gt; python dotest.py --executable &lt;path-to-lldb&gt; functionalities/data-formatter
</code>
<p>
- To dump additional information to <tt>stdout</tt> about how the test harness is driving LLDB, run
- <tt>dotest.py</tt> with the <tt>-t</tt> flag. Many more options that are available. To see a list of all of them, run:
+ Many more options that are available. To see a list of all of them, run:
</p>
<code>
- <br />&gt; python dotest.py -h
+ &gt; python dotest.py -h
</code>
<p>
@@ -95,7 +102,7 @@
running in parallel with a parent directory.
</p>
- <h3>Running the test-suite remotely</h3>
+ <h2>Running the test-suite remotely</h2>
<p>
Running the test-suite remotely is similar to the process of running a local test
@@ -124,6 +131,99 @@
</div>
<div class="postfooter"></div>
+ <h1 class="postheader">Debugging test failures</h1>
+ <div class="postcontent">
+ <h2>Non-Windows platforms</h2>
+ <p>
+ On non-Windows platforms, you can use the <code>-d</code> option to <code>dotest.py</code> which will cause the script to wait
+ for a while until a debugger is attached.
+ </p>
+ <h2>Windows</h2>
+ <p>
+ On Windows, it is strongly recommended to use <a href="https://github.com/Microsoft/PTVS/releases">Python Tools for Visual Studio</a>
+ for debugging test failures. It can seamlessly step between native and managed code, which is very helpful when you need to step
+ through the test itself, and then into the LLDB code that backs the operations the test is performing. A quick guide to getting
+ started with PTVS is as follows:
+ <ul>
+ <li>Install PTVS</li>
+ <li>
+ Create a Visual Studio Project for the Python code.
+ <ul>
+ <li>Go to File -> New -> Project -> Python -> From Existing Python Code.</li>
+ <li>Choose <code>llvm/tools/lldb</code> as the directory containing the Python code.</li>
+ <li>
+ When asked where to save the <code>.pyproj</code> file, choose the folder <code>llvm/tools/lldb/pyproj</code>.
+ This is a special folder that is ignored by the <code>.gitignore</code> file, since it is not checked in.
+ </li>
+ </ul>
+ </li>
+ <li>Set <code>test/dotest.py</code> as the startup file</li>
+ <li>
+ Make sure there is a Python Environment installed for your distribution. For example, if you installed Python to
+ <code>C:\Python35</code>, PTVS needs to know that this is the interpreter you want to use for running the test suite.
+ <ul>
+ <li>Go to Tools -> Options -> Python Tools -> Environment Options</li>
+ <li>Click Add Environment, and enter <code>Python 3.5 Debug</code> for the name. Fill out the values correctly.</li>
+ </ul>
+ </li>
+ <li>
+ Configure the project to use this debug interpreter.
+ <ul>
+ <li>Right click the Project node in Solution Explorer</li>
+ <li>In the <code>General</code> tab, Make sure <code>Python 3.5 Debug</code> is the selected Interpreter.</li>
+ <li>In <code>Debug/Search Paths</code>, enter the path to your <code>ninja/lib/site-packages</code> directory.</li>
+ <li>
+ In <code>Debug/Environment Variables</code>, enter<br/>
+ <code>VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\</code>
+ </li>
+ <li>
+ If you want to enabled mixed mode debugging, check <code>Enable native code debugging</code> (this slows down debugging,
+ so enable it only on an as-needed basis.)
+ </li>
+ </ul>
+ </li>
+ <li>
+ Set the command line for the test suite to run.
+ <ul>
+ <li>Right click the project in solution explorer and choose the <code>Debug</code> tab.</li>
+ <li>Enter the arguments to <code>dotest.py</code>. Note you must add <code>--no-multiprocess</code></li>
+ <li>
+ Example command options:
+ <code>
+ <br/># quiet mode
+ <br/>-q
+ <br />--arch=i686
+ <br /># Path to debug lldb.exe
+ <br />--executable D:/src/llvmbuild/ninja/bin/lldb.exe
+ <br /># Directory to store log files
+ <br />-s D:/src/llvmbuild/ninja/lldb-test-traces
+ <br />-u CXXFLAGS -u CFLAGS
+ <br /># If a test crashes, show JIT debugging dialog.
+ <br />--enable-crash-dialog
+ <br /># Path to release clang.exe
+ <br />-C d:\src\llvmbuild\ninja_release\bin\clang.exe
+ <br /># Path to the particular test you want to debug.
+ <br />-p TestPaths.py
+ <br /># Root of test tree
+ <br />D:\src\llvm\tools\lldb\packages\Python\lldbsuite\test
+ <br /># Required in order to be able to debug the test.
+ <br />--no-multiprocess
+ </code>
+ </li>
+ <li>
+ As copy-pastable command line:<br/>
+ <code>
+ -q --arch=i686 --executable D:/src/llvmbuild/ninja/bin/lldb.exe -s D:/src/llvmbuild/ninja/lldb-test-traces
+ -u CXXFLAGS -u CFLAGS --enable-crash-dialog -C d:\src\llvmbuild\ninja_release\bin\clang.exe
+ -p TestPaths.py D:\src\llvm\tools\lldb\packages\Python\lldbsuite\test --no-multiprocess
+ </code>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </p>
+ </div>
+ <div class="postfooter"></div>
</div>
</div>
</div>